From fcf848608ecc31cb85d3cd2551a2e6598e69adff Mon Sep 17 00:00:00 2001 From: Zev Eisenberg Date: Sun, 2 Feb 2020 03:35:37 -0500 Subject: [PATCH] Add Inline test failure messages (#3040) * Add Example wrapper in order to display test failures inline when running in Xcode. * Stop using Swift 5.1-only features so we can compile on Xcode 10.2. * Wrap strings in Example. * Add Changelog entry. * Wrap all examples in Example struct. * Better and more complete capturing of line numbers. * Fix broken test. * Better test traceability. * Address or disable linting warnings. * Add documentation comments. * Disable linter for a few cases. * Limit mutability and add copy-and-mutate utility functions. * Limit scope of mutability. --- CHANGELOG.md | 6 + .../Documentation/RuleDocumentation.swift | 4 +- .../Extensions/Dictionary+SwiftLint.swift | 7 +- .../SwiftLintFramework/Models/Example.swift | 58 ++ .../Models/RuleDescription.swift | 12 +- .../Models/StyleViolation.swift | 38 +- .../Reporters/CSVReporter.swift | 4 +- .../Reporters/CheckstyleReporter.swift | 2 +- .../GitHubActionsLoggingReporter.swift | 2 +- .../Reporters/JSONReporter.swift | 4 +- .../Reporters/MarkdownReporter.swift | 4 +- .../Reporters/SonarQubeReporter.swift | 2 +- .../Reporters/XcodeReporter.swift | 4 +- .../Rules/Idiomatic/BlockBasedKVORule.swift | 13 +- .../Rules/Idiomatic/ConvenienceTypeRule.swift | 30 +- .../DiscouragedObjectLiteralRule.swift | 16 +- ...scouragedOptionalBooleanRuleExamples.swift | 82 +-- ...iscouragedOptionalCollectionExamples.swift | 104 ++-- .../DuplicateImportsRuleExamples.swift | 50 +- .../Rules/Idiomatic/ExplicitACLRule.swift | 48 +- .../Idiomatic/ExplicitEnumRawValueRule.swift | 40 +- .../Rules/Idiomatic/ExplicitInitRule.swift | 38 +- .../Idiomatic/ExplicitTopLevelACLRule.swift | 28 +- .../Idiomatic/ExplicitTypeInterfaceRule.swift | 40 +- .../ExtensionAccessModifierRule.swift | 40 +- .../Rules/Idiomatic/FallthroughRule.swift | 8 +- .../Idiomatic/FatalErrorMessageRule.swift | 16 +- .../Rules/Idiomatic/ForWhereRule.swift | 44 +- .../Rules/Idiomatic/ForceCastRule.swift | 4 +- .../Rules/Idiomatic/ForceTryRule.swift | 8 +- .../Rules/Idiomatic/ForceUnwrappingRule.swift | 74 +-- .../FunctionDefaultParameterAtEndRule.swift | 28 +- .../Rules/Idiomatic/GenericTypeNameRule.swift | 54 +- .../ImplicitlyUnwrappedOptionalRule.swift | 34 +- .../Rules/Idiomatic/IsDisjointRule.swift | 12 +- .../JoinedDefaultParameterRule.swift | 29 +- .../LegacyCGGeometryFunctionsRule.swift | 124 ++--- .../LegacyConstantRuleExamples.swift | 70 +-- .../Idiomatic/LegacyConstructorRule.swift | 164 +++--- .../Rules/Idiomatic/LegacyHashingRule.swift | 28 +- .../Rules/Idiomatic/LegacyMultipleRule.swift | 32 +- .../LegacyNSGeometryFunctionsRule.swift | 122 ++--- .../Rules/Idiomatic/LegacyRandomRule.swift | 12 +- .../Rules/Idiomatic/NimbleOperatorRule.swift | 82 +-- .../NoExtensionAccessModifierRule.swift | 14 +- .../NoFallthroughOnlyRuleExamples.swift | 66 +-- .../Idiomatic/NoGroupingExtensionRule.swift | 14 +- .../Rules/Idiomatic/ObjectLiteralRule.swift | 29 +- .../PatternMatchingKeywordsRule.swift | 44 +- .../PrivateOverFilePrivateRule.swift | 38 +- .../RedundantNilCoalescingRule.swift | 12 +- .../RedundantObjcAttributeRuleExamples.swift | 167 +++--- .../RedundantOptionalInitializationRule.swift | 73 +-- .../RedundantSetAccessControlRule.swift | 32 +- .../RedundantStringEnumValueRule.swift | 32 +- .../RedundantTypeAnnotationRule.swift | 38 +- .../Idiomatic/RedundantVoidReturnRule.swift | 52 +- .../Rules/Idiomatic/StaticOperatorRule.swift | 32 +- .../Idiomatic/StrictFilePrivateRule.swift | 40 +- .../Rules/Idiomatic/SyntacticSugarRule.swift | 73 +-- .../Rules/Idiomatic/ToggleBoolRule.swift | 22 +- .../Idiomatic/TrailingSemicolonRule.swift | 22 +- .../Idiomatic/TypeNameRuleExamples.swift | 72 +-- .../Idiomatic/UnavailableFunctionRule.swift | 16 +- .../Idiomatic/UnneededBreakInSwitchRule.swift | 15 +- .../Idiomatic/UntypedErrorInCatchRule.swift | 50 +- .../Idiomatic/UnusedEnumeratedRule.swift | 26 +- .../Rules/Idiomatic/XCTFailMessageRule.swift | 16 +- .../XCTSpecificMatcherRuleExamples.swift | 144 ++--- .../Rules/Lint/AnyObjectProtocolRule.swift | 30 +- .../Rules/Lint/ArrayInitRule.swift | 46 +- .../Lint/ClassDelegateProtocolRule.swift | 22 +- .../Rules/Lint/CompilerProtocolInitRule.swift | 8 +- .../Rules/Lint/DeploymentTargetRule.swift | 38 +- ...cardedNotificationCenterObserverRule.swift | 44 +- .../Lint/DiscouragedDirectInitRule.swift | 32 +- .../Rules/Lint/DuplicateEnumCasesRule.swift | 12 +- .../Rules/Lint/DynamicInlineRule.swift | 16 +- .../Lint/EmptyXCTestMethodRuleExamples.swift | 32 +- .../Rules/Lint/ExpiringTodoRule.swift | 22 +- .../Rules/Lint/IdenticalOperandsRule.swift | 63 +-- .../Rules/Lint/InertDeferRule.swift | 20 +- .../Rules/Lint/LowerACLThanParentRule.swift | 32 +- .../Rules/Lint/MarkRule.swift | 120 +++-- .../Rules/Lint/MissingDocsRule.swift | 47 +- .../Rules/Lint/NSLocalizedStringKeyRule.swift | 8 +- .../NSLocalizedStringRequireBundleRule.swift | 28 +- .../NSObjectPreferIsEqualRuleExamples.swift | 56 +- ...ficationCenterDetachmentRuleExamples.swift | 37 +- .../Rules/Lint/OrphanedDocCommentRule.swift | 24 +- .../Rules/Lint/OverriddenSuperCallRule.swift | 104 ++-- .../Rules/Lint/OverrideInExtensionRule.swift | 34 +- .../Rules/Lint/PrivateActionRule.swift | 34 +- .../Rules/Lint/PrivateOutletRule.swift | 14 +- .../Rules/Lint/PrivateUnitTestRule.swift | 136 +++-- .../Lint/ProhibitedInterfaceBuilderRule.swift | 18 +- .../Rules/Lint/ProhibitedSuperRule.swift | 28 +- .../QuickDiscouragedCallRuleExamples.swift | 504 ++++++++++-------- ...ckDiscouragedFocusedTestRuleExamples.swift | 126 +++-- ...ckDiscouragedPendingTestRuleExamples.swift | 138 ++--- ...RawValueForCamelCasedCodableEnumRule.swift | 40 +- .../Rules/Lint/RequiredDeinitRule.swift | 34 +- .../Rules/Lint/RequiredEnumCaseRule.swift | 76 +-- .../Rules/Lint/StrongIBOutletRule.swift | 20 +- .../Rules/Lint/TodoRule.swift | 20 +- .../Lint/UnownedVariableCaptureRule.swift | 18 +- .../Rules/Lint/UnusedCaptureListRule.swift | 42 +- .../Lint/UnusedClosureParameterRule.swift | 118 ++-- .../Lint/UnusedControlFlowLabelRule.swift | 54 +- .../Rules/Lint/UnusedDeclarationRule.swift | 28 +- .../Rules/Lint/UnusedImportRule.swift | 89 ++-- .../Rules/Lint/UnusedSetterValueRule.swift | 32 +- .../Rules/Lint/ValidIBInspectableRule.swift | 32 +- .../Rules/Lint/WeakDelegateRule.swift | 29 +- .../Rules/Lint/YodaConditionRule.swift | 32 +- .../ClosureBodyLengthRuleExamples.swift | 61 ++- .../Metrics/CyclomaticComplexityRule.swift | 69 ++- .../EnumCaseAssociatedValuesLengthRule.swift | 16 +- .../Rules/Metrics/FileLengthRule.swift | 6 +- .../Metrics/FunctionParameterCountRule.swift | 38 +- .../Rules/Metrics/LargeTupleRule.swift | 56 +- .../Rules/Metrics/LineLengthRule.swift | 12 +- .../Rules/Metrics/NestingRule.swift | 44 +- .../Rules/Metrics/TypeBodyLengthRule.swift | 26 +- .../ContainsOverFilterCountRule.swift | 18 +- .../ContainsOverFilterIsEmptyRule.swift | 18 +- .../ContainsOverFirstNotNilRule.swift | 16 +- .../ContainsOverRangeNilComparisonRule.swift | 10 +- .../EmptyCollectionLiteralRule.swift | 24 +- .../Rules/Performance/EmptyCountRule.swift | 34 +- .../Rules/Performance/EmptyStringRule.swift | 8 +- .../Rules/Performance/FirstWhereRule.swift | 28 +- .../FlatMapOverMapReduceRule.swift | 6 +- .../Rules/Performance/LastWhereRule.swift | 24 +- .../Rules/Performance/ReduceBooleanRule.swift | 20 +- .../Rules/Performance/ReduceIntoRule.swift | 60 +-- .../Performance/SortedFirstLastRule.swift | 52 +- .../Rules/Style/AttributesRuleExamples.swift | 140 ++--- .../Rules/Style/ClosingBraceRule.swift | 10 +- .../ClosureEndIndentationRuleExamples.swift | 123 ++--- .../Style/ClosureParameterPositionRule.swift | 52 +- .../Rules/Style/ClosureSpacingRule.swift | 40 +- .../Rules/Style/CollectionAlignmentRule.swift | 92 ++-- .../Rules/Style/ColonRuleExamples.swift | 302 ++++++----- .../Rules/Style/CommaRule.swift | 34 +- .../ConditionalReturnsOnNewlineRule.swift | 24 +- .../Rules/Style/ControlStatementRule.swift | 116 ++-- .../Rules/Style/EmptyEnumArgumentsRule.swift | 20 +- .../Rules/Style/EmptyParametersRule.swift | 30 +- ...tyParenthesesWithTrailingClosureRule.swift | 50 +- .../Rules/Style/ExplicitSelfRule.swift | 32 +- .../Rules/Style/FileHeaderRule.swift | 26 +- .../Style/FileTypesOrderRuleExamples.swift | 22 +- .../Style/IdentifierNameRuleExamples.swift | 50 +- .../Rules/Style/ImplicitGetterRule.swift | 164 +----- .../Style/ImplicitGetterRuleExamples.swift | 183 +++++++ .../Style/ImplicitReturnRuleExamples.swift | 82 +-- .../Rules/Style/IndentationWidthRule.swift | 18 +- .../Rules/Style/LeadingWhitespaceRule.swift | 6 +- .../Rules/Style/LetVarWhitespaceRule.swift | 49 +- .../LiteralExpressionEndIdentationRule.swift | 174 +++--- .../Style/ModifierOrderRuleExamples.swift | 375 +++++++------ .../MultilineArgumentsBracketsRule.swift | 40 +- .../MultilineArgumentsRuleExamples.swift | 95 ++-- .../Style/MultilineFunctionChainsRule.swift | 52 +- .../Style/MultilineLiteralBracketsRule.swift | 44 +- .../MultilineParametersBracketsRule.swift | 48 +- .../MultilineParametersRuleExamples.swift | 500 +++++++++-------- ...tipleClosuresWithTrailingClosureRule.swift | 30 +- .../Rules/Style/NoSpaceInMethodCallRule.swift | 38 +- .../Style/NumberSeparatorRuleExamples.swift | 83 +-- .../Rules/Style/OpeningBraceRule.swift | 80 +-- .../OperatorFunctionWhitespaceRule.swift | 18 +- .../Style/OperatorUsageWhitespaceRule.swift | 98 ++-- .../Style/OptionalEnumCaseMatchingRule.swift | 58 +- .../PreferSelfTypeOverTypeOfSelfRule.swift | 46 +- .../Style/PrefixedTopLevelConstantRule.swift | 56 +- .../ProtocolPropertyAccessorsOrderRule.swift | 12 +- .../Style/RedundantDiscardableLetRule.swift | 18 +- .../Style/ReturnArrowWhitespaceRule.swift | 44 +- .../Rules/Style/ShorthandOperatorRule.swift | 36 +- .../Rules/Style/SingleTestClassRule.swift | 39 +- .../Rules/Style/SortedImportsRule.swift | 48 +- .../Rules/Style/StatementPositionRule.swift | 58 +- .../Rules/Style/SwitchCaseAlignmentRule.swift | 42 +- .../Rules/Style/SwitchCaseOnNewlineRule.swift | 72 +-- .../Rules/Style/TrailingClosureRule.swift | 26 +- .../Rules/Style/TrailingCommaRule.swift | 45 +- .../Rules/Style/TrailingNewlineRule.swift | 12 +- .../Rules/Style/TrailingWhitespaceRule.swift | 10 +- .../Style/TypeContentsOrderRuleExamples.swift | 46 +- ...ededParenthesesInClosureArgumentRule.swift | 39 +- .../Style/UnusedOptionalBindingRule.swift | 52 +- ...VerticalParameterAlignmentOnCallRule.swift | 134 +++-- ...rticalParameterAlignmentRuleExamples.swift | 99 ++-- .../VerticalWhitespaceBetweenCasesRule.swift | 51 +- .../VerticalWhitespaceClosingBracesRule.swift | 27 +- .../VerticalWhitespaceOpeningBracesRule.swift | 47 +- .../Rules/Style/VerticalWhitespaceRule.swift | 20 +- .../Rules/Style/VoidReturnRule.swift | 44 +- Source/swiftlint/Commands/RulesCommand.swift | 2 +- .../Helpers/LintOrAnalyzeCommand.swift | 5 +- SwiftLint.xcodeproj/project.pbxproj | 12 + .../AttributesRuleTests.swift | 50 +- .../CollectingRuleTests.swift | 4 +- .../ColonRuleTests.swift | 208 ++++---- .../CommandTests.swift | 74 +-- .../CompilerProtocolInitRuleTests.swift | 4 +- ...ConditionalReturnsOnNewlineRuleTests.swift | 24 +- .../ContainsOverFirstNotNilRuleTests.swift | 12 +- .../CyclomaticComplexityRuleTests.swift | 8 +- .../DeploymentTargetRuleTests.swift | 12 +- .../DisableAllTests.swift | 130 +++-- .../DiscouragedDirectInitRuleTests.swift | 12 +- .../DiscouragedObjectLiteralRuleTests.swift | 8 +- .../ExampleTests.swift | 49 ++ .../ExpiringTodoRuleTests.swift | 32 +- .../ExplicitTypeInterfaceRuleTests.swift | 100 ++-- .../FileHeaderRuleTests.swift | 64 +-- .../FileLengthRuleTests.swift | 6 +- .../FileTypesOrderRuleTests.swift | 26 +- .../FunctionBodyLengthRuleTests.swift | 27 +- .../FunctionParameterCountRuleTests.swift | 7 +- .../GenericTypeNameRuleTests.swift | 24 +- .../IdentifierNameRuleTests.swift | 16 +- ...ImplicitlyUnwrappedOptionalRuleTests.swift | 8 +- .../IndentationWidthRuleTests.swift | 6 +- .../LineLengthRuleTests.swift | 24 +- .../ModifierOrderTests.swift | 236 ++++---- .../MultilineArgumentsRuleTests.swift | 82 +-- .../NumberSeparatorRuleTests.swift | 78 +-- .../ObjectLiteralRuleTests.swift | 26 +- .../PrefixedTopLevelConstantRuleTests.swift | 10 +- .../PrivateOutletRuleTests.swift | 8 +- .../PrivateOverFilePrivateRuleTests.swift | 14 +- .../RuleDescription+Examples.swift | 10 +- .../SwiftLintFrameworkTests/TestHelpers.swift | 170 ++++-- .../TodoRuleTests.swift | 12 +- .../TrailingClosureRuleTests.swift | 8 +- .../TrailingCommaRuleTests.swift | 56 +- .../TrailingWhitespaceTests.swift | 7 +- .../TypeContentsOrderRuleTests.swift | 56 +- .../TypeNameRuleTests.swift | 22 +- .../UnusedOptionalBindingRuleTests.swift | 4 +- .../VerticalWhitespaceRuleTests.swift | 16 +- .../XCTSpecificMatcherRuleTests.swift | 60 +-- 246 files changed, 6609 insertions(+), 5684 deletions(-) create mode 100644 Source/SwiftLintFramework/Models/Example.swift create mode 100644 Source/SwiftLintFramework/Rules/Style/ImplicitGetterRuleExamples.swift create mode 100644 Tests/SwiftLintFrameworkTests/ExampleTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 548670912d..565f808ab0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,12 @@ * Add `deinitializer` type content to `type_contents_order` rule instead of grouping it with initializers. [Steven Magdy](https://github.com/StevenMagdy) +* Inline test failure messages to make development of SwiftLint easier. Test + failures in triggering and non-triggering examples will appear inline in + their respective files so you can immediately see which cases are working + and which are not. + [ZevEisenberg](https://github.com/ZevEisenberg) + [#3040](https://github.com/realm/SwiftLint/pull/3040) #### Bug Fixes diff --git a/Source/SwiftLintFramework/Documentation/RuleDocumentation.swift b/Source/SwiftLintFramework/Documentation/RuleDocumentation.swift index b10671ae28..af9f5fc8b2 100644 --- a/Source/SwiftLintFramework/Documentation/RuleDocumentation.swift +++ b/Source/SwiftLintFramework/Documentation/RuleDocumentation.swift @@ -60,10 +60,10 @@ private func detailsSummary(_ rule: Rule) -> String { """ } -private func formattedCode(_ code: String) -> String { +private func formattedCode(_ example: Example) -> String { return """ ```swift - \(code) + \(example.code) ``` """ } diff --git a/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift index 9fdcdc1c0a..3308444dfd 100644 --- a/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift @@ -1,4 +1,3 @@ -import Foundation import SourceKittenFramework /// A collection of keys and values as parsed out of SourceKit, with many conveniences for accessing SwiftLint-specific @@ -261,11 +260,13 @@ extension SourceKittenDictionary { } } -extension Dictionary where Key == String { +extension Dictionary where Key == Example { /// Returns a dictionary with SwiftLint violation markers (↓) removed from keys. /// /// - returns: A new `Dictionary`. func removingViolationMarkers() -> [Key: Value] { - return Dictionary(uniqueKeysWithValues: map { ($0.replacingOccurrences(of: "↓", with: ""), $1) }) + return Dictionary(uniqueKeysWithValues: map { key, value in + return (key.removingViolationMarkers(), value) + }) } } diff --git a/Source/SwiftLintFramework/Models/Example.swift b/Source/SwiftLintFramework/Models/Example.swift new file mode 100644 index 0000000000..d6117a135d --- /dev/null +++ b/Source/SwiftLintFramework/Models/Example.swift @@ -0,0 +1,58 @@ +/// Captures code and context information for an example of a triggering or +/// non-triggering style +public struct Example { + /// The contents of the example + public private(set) var code: String + /// The path to the file where the example was created + public private(set) var file: StaticString + /// The line in the file where the example was created + public var line: UInt +} + +public extension Example { + /// Create a new Example with the specified code, file, and line + /// - Parameters: + /// - code: The contents of the example + /// - file: The path to the file where the example is located. + /// Defaults to the file where this initializer is called. + /// - line: The line in the file where the example is located. + /// Defaults to the line where this initializer is called. + init(_ code: String, file: StaticString = #file, line: UInt = #line) { + self.code = code + self.file = file + self.line = line + } + + /// Returns the same example, but with the `code` that is passed in + /// - Parameter code: the new code to use in the modified example + func with(code: String) -> Example { + var new = self + new.code = code + return new + } + + /// Returns a copy of the Example with all instances of the "↓" character removed. + func removingViolationMarkers() -> Example { + return with(code: code.replacingOccurrences(of: "↓", with: "")) + } +} + +extension Example: Hashable { + public static func == (lhs: Example, rhs: Example) -> Bool { + // Ignoring file/line metadata because two Examples could represent + // the same idea, but captured at two different points in the code + return lhs.code == rhs.code + } + + public func hash(into hasher: inout Hasher) { + // Ignoring file/line metadata because two Examples could represent + // the same idea, but captured at two different points in the code + hasher.combine(code) + } +} + +extension Example: Comparable { + public static func < (lhs: Example, rhs: Example) -> Bool { + return lhs.code < rhs.code + } +} diff --git a/Source/SwiftLintFramework/Models/RuleDescription.swift b/Source/SwiftLintFramework/Models/RuleDescription.swift index 64615b933c..4046c04a14 100644 --- a/Source/SwiftLintFramework/Models/RuleDescription.swift +++ b/Source/SwiftLintFramework/Models/RuleDescription.swift @@ -1,5 +1,5 @@ /// A detailed description for a SwiftLint rule. Used for both documentation and testing purposes. -public struct RuleDescription: Equatable, Codable { +public struct RuleDescription: Equatable { /// The rule's unique identifier, to be used in configuration files and SwiftLint commands. /// Should be short and only comprised of lowercase latin alphabet letters and underscores formatted in snake case. public let identifier: String @@ -20,7 +20,7 @@ public struct RuleDescription: Equatable, Codable { /// /// These examples are also used for testing purposes if the rule conforms to `AutomaticTestableRule`. Tests will /// validate that the rule does not trigger any violations for these examples. - public let nonTriggeringExamples: [String] + public let nonTriggeringExamples: [Example] /// Swift source examples that do trigger one or more violations for this rule. Used for documentation purposes to /// inform users of various samples of code that are considered invalid by this rule. Should be valid Swift syntax @@ -30,7 +30,7 @@ public struct RuleDescription: Equatable, Codable { /// /// These examples are also used for testing purposes if the rule conforms to `AutomaticTestableRule`. Tests will /// validate that the rule triggers violations for these examples wherever `↓` markers are located. - public let triggeringExamples: [String] + public let triggeringExamples: [Example] /// Pairs of Swift source examples, where keys are examples that trigger violations for this rule, and the values /// are the expected value after applying corrections with the rule. @@ -39,7 +39,7 @@ public struct RuleDescription: Equatable, Codable { /// /// These examples are used for testing purposes if the rule conforms to `AutomaticTestableRule`. Tests will /// validate that the rule corrects all keys to their corresponding values. - public let corrections: [String: String] + public let corrections: [Example: Example] /// Any previous iteration of the rule's identifier that was previously shipped with SwiftLint. public let deprecatedAliases: Set @@ -73,8 +73,8 @@ public struct RuleDescription: Equatable, Codable { /// - parameter requiresFileOnDisk: Sets the description's `requiresFileOnDisk` property. public init(identifier: String, name: String, description: String, kind: RuleKind, minSwiftVersion: SwiftVersion = .three, - nonTriggeringExamples: [String] = [], triggeringExamples: [String] = [], - corrections: [String: String] = [:], + nonTriggeringExamples: [Example] = [], triggeringExamples: [Example] = [], + corrections: [Example: Example] = [:], deprecatedAliases: Set = [], requiresFileOnDisk: Bool = false) { self.identifier = identifier diff --git a/Source/SwiftLintFramework/Models/StyleViolation.swift b/Source/SwiftLintFramework/Models/StyleViolation.swift index ace172fae7..8a6eda0d49 100644 --- a/Source/SwiftLintFramework/Models/StyleViolation.swift +++ b/Source/SwiftLintFramework/Models/StyleViolation.swift @@ -1,13 +1,19 @@ /// A value describing an instance of Swift source code that is considered invalid by a SwiftLint rule. public struct StyleViolation: CustomStringConvertible, Equatable, Codable { + /// The identifier of the rule that generated this violation. + public let ruleIdentifier: String + /// The description of the rule that generated this violation. - public let ruleDescription: RuleDescription + public let ruleDescription: String + + /// The name of the rule that generated this violation. + public let ruleName: String /// The severity of this violation. - public let severity: ViolationSeverity + public private(set) var severity: ViolationSeverity /// The location of this violation. - public let location: Location + public private(set) var location: Location /// The justification for this violation. public let reason: String @@ -23,11 +29,31 @@ public struct StyleViolation: CustomStringConvertible, Equatable, Codable { /// - parameter severity: The severity of this violation. /// - parameter location: The location of this violation. /// - parameter reason: The justification for this violation. - public init(ruleDescription: RuleDescription, severity: ViolationSeverity = .warning, - location: Location, reason: String? = nil) { - self.ruleDescription = ruleDescription + public init(ruleDescription: RuleDescription, + severity: ViolationSeverity = .warning, + location: Location, + reason: String? = nil) { + self.ruleIdentifier = ruleDescription.identifier + self.ruleDescription = ruleDescription.description + self.ruleName = ruleDescription.name self.severity = severity self.location = location self.reason = reason ?? ruleDescription.description } + + /// Returns the same violation, but with the `severity` that is passed in + /// - Parameter severity: the new severity to use in the modified violation + public func with(severity: ViolationSeverity) -> StyleViolation { + var new = self + new.severity = severity + return new + } + + /// Returns the same violation, but with the `location` that is passed in + /// - Parameter location: the new location to use in the modified violation + public func with(location: Location) -> StyleViolation { + var new = self + new.location = location + return new + } } diff --git a/Source/SwiftLintFramework/Reporters/CSVReporter.swift b/Source/SwiftLintFramework/Reporters/CSVReporter.swift index 4413e6b185..65159e081a 100644 --- a/Source/SwiftLintFramework/Reporters/CSVReporter.swift +++ b/Source/SwiftLintFramework/Reporters/CSVReporter.swift @@ -34,9 +34,9 @@ public struct CSVReporter: Reporter { violation.location.line?.description ?? "", violation.location.character?.description ?? "", violation.severity.rawValue.capitalized, - violation.ruleDescription.name.escapedForCSV(), + violation.ruleName.escapedForCSV(), violation.reason.escapedForCSV(), - violation.ruleDescription.identifier + violation.ruleIdentifier ].joined(separator: ",") } } diff --git a/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift b/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift index f7fcce399a..1e82f153b2 100644 --- a/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift +++ b/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift @@ -36,7 +36,7 @@ public struct CheckstyleReporter: Reporter { let col: Int = violation.location.character ?? 0 let severity: String = violation.severity.rawValue let reason: String = violation.reason.escapedForXML() - let identifier: String = violation.ruleDescription.identifier + let identifier: String = violation.ruleIdentifier let source: String = "swiftlint.rules.\(identifier)".escapedForXML() return [ "\t\t [String: Any] { return [ "engineId": "SwiftLint", - "ruleId": violation.ruleDescription.identifier, + "ruleId": violation.ruleIdentifier, "primaryLocation": [ "message": violation.reason, "filePath": violation.location.relativeFile ?? "", diff --git a/Source/SwiftLintFramework/Reporters/XcodeReporter.swift b/Source/SwiftLintFramework/Reporters/XcodeReporter.swift index cadd5e5dfc..2c7fed1c6e 100644 --- a/Source/SwiftLintFramework/Reporters/XcodeReporter.swift +++ b/Source/SwiftLintFramework/Reporters/XcodeReporter.swift @@ -23,9 +23,9 @@ public struct XcodeReporter: Reporter { return [ "\(violation.location): ", "\(violation.severity.rawValue): ", - "\(violation.ruleDescription.name) Violation: ", + "\(violation.ruleName) Violation: ", violation.reason, - " (\(violation.ruleDescription.identifier))" + " (\(violation.ruleIdentifier))" ].joined() } } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/BlockBasedKVORule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/BlockBasedKVORule.swift index b51add91cc..adaf08c11c 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/BlockBasedKVORule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/BlockBasedKVORule.swift @@ -12,28 +12,27 @@ public struct BlockBasedKVORule: ASTRule, ConfigurationProviderRule, AutomaticTe description: "Prefer the new block based KVO API with keypaths when using Swift 3.2 or later.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" let observer = foo.observe(\\.value, options: [.new]) { (foo, change) in print(change.newValue) } - """ + """) ], triggeringExamples: [ - """ + Example(""" class Foo: NSObject { override ↓func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {} } - """ - , - """ + """), + Example(""" class Foo: NSObject { override ↓func observeValue(forKeyPath keyPath: String?, of object: Any?, change: Dictionary?, context: UnsafeMutableRawPointer?) {} } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ConvenienceTypeRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ConvenienceTypeRule.swift index b2cfc2cc82..e961e1da97 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ConvenienceTypeRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ConvenienceTypeRule.swift @@ -13,47 +13,47 @@ public struct ConvenienceTypeRule: ASTRule, OptInRule, ConfigurationProviderRule kind: .idiomatic, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - """ + Example(""" enum Math { // enum public static let pi = 3.14 } - """, - """ + """), + Example(""" // class with inheritance class MathViewController: UIViewController { public static let pi = 3.14 } - """, - """ + """), + Example(""" @objc class Math: NSObject { // class visible to Obj-C public static let pi = 3.14 } - """, - """ + """), + Example(""" struct Math { // type with non-static declarations public static let pi = 3.14 public let randomNumber = 2 } - """, - "class DummyClass {}" + """), + Example("class DummyClass {}") ], triggeringExamples: [ - """ + Example(""" ↓struct Math { public static let pi = 3.14 } - """, - """ + """), + Example(""" ↓class Math { public static let pi = 3.14 } - """, - """ + """), + Example(""" ↓struct Math { public static let pi = 3.14 @available(*, unavailable) init() {} } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedObjectLiteralRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedObjectLiteralRule.swift index 827f074f26..910517e2d9 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedObjectLiteralRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedObjectLiteralRule.swift @@ -9,16 +9,16 @@ public struct DiscouragedObjectLiteralRule: ASTRule, OptInRule, ConfigurationPro description: "Prefer initializers over object literals.", kind: .idiomatic, nonTriggeringExamples: [ - "let image = UIImage(named: aVariable)", - "let image = UIImage(named: \"interpolated \\(variable)\")", - "let color = UIColor(red: value, green: value, blue: value, alpha: 1)", - "let image = NSImage(named: aVariable)", - "let image = NSImage(named: \"interpolated \\(variable)\")", - "let color = NSColor(red: value, green: value, blue: value, alpha: 1)" + Example("let image = UIImage(named: aVariable)"), + Example("let image = UIImage(named: \"interpolated \\(variable)\")"), + Example("let color = UIColor(red: value, green: value, blue: value, alpha: 1)"), + Example("let image = NSImage(named: aVariable)"), + Example("let image = NSImage(named: \"interpolated \\(variable)\")"), + Example("let color = NSColor(red: value, green: value, blue: value, alpha: 1)") ], triggeringExamples: [ - "let image = ↓#imageLiteral(resourceName: \"image.jpg\")", - "let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)" + Example("let image = ↓#imageLiteral(resourceName: \"image.jpg\")"), + Example("let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalBooleanRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalBooleanRuleExamples.swift index dfd049b74c..b86c8a8c96 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalBooleanRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalBooleanRuleExamples.swift @@ -1,27 +1,27 @@ internal struct DiscouragedOptionalBooleanRuleExamples { static let nonTriggeringExamples = [ // Global variable - "var foo: Bool", - "var foo: [String: Bool]", - "var foo: [Bool]", - "let foo: Bool = true", - "let foo: Bool = false", - "let foo: [String: Bool] = [:]", - "let foo: [Bool] = []", + Example("var foo: Bool"), + Example("var foo: [String: Bool]"), + Example("var foo: [Bool]"), + Example("let foo: Bool = true"), + Example("let foo: Bool = false"), + Example("let foo: [String: Bool] = [:]"), + Example("let foo: [Bool] = []"), // Computed get variable - "var foo: Bool { return true }", - "let foo: Bool { return false }()", + Example("var foo: Bool { return true }"), + Example("let foo: Bool { return false }()"), // Free function return - "func foo() -> Bool {}", - "func foo() -> [String: Bool] {}", - "func foo() -> ([Bool]) -> String {}", + Example("func foo() -> Bool {}"), + Example("func foo() -> [String: Bool] {}"), + Example("func foo() -> ([Bool]) -> String {}"), // Free function parameter - "func foo(input: Bool = true) {}", - "func foo(input: [String: Bool] = [:]) {}", - "func foo(input: [Bool] = []) {}", + Example("func foo(input: Bool = true) {}"), + Example("func foo(input: [String: Bool] = [:]) {}"), + Example("func foo(input: [Bool] = []) {}"), // Method return wrapExample("class", "func foo() -> Bool {}"), @@ -52,36 +52,36 @@ internal struct DiscouragedOptionalBooleanRuleExamples { static let triggeringExamples = [ // Global variable - "var foo: ↓Bool?", - "var foo: [String: ↓Bool?]", - "var foo: [↓Bool?]", - "let foo: ↓Bool? = nil", - "let foo: [String: ↓Bool?] = [:]", - "let foo: [↓Bool?] = []", - "let foo = ↓Optional.some(false)", - "let foo = ↓Optional.some(true)", + Example("var foo: ↓Bool?"), + Example("var foo: [String: ↓Bool?]"), + Example("var foo: [↓Bool?]"), + Example("let foo: ↓Bool? = nil"), + Example("let foo: [String: ↓Bool?] = [:]"), + Example("let foo: [↓Bool?] = []"), + Example("let foo = ↓Optional.some(false)"), + Example("let foo = ↓Optional.some(true)"), // Computed Get Variable - "var foo: ↓Bool? { return nil }", - "let foo: ↓Bool? { return nil }()", + Example("var foo: ↓Bool? { return nil }"), + Example("let foo: ↓Bool? { return nil }()"), // Free function return - "func foo() -> ↓Bool? {}", - "func foo() -> [String: ↓Bool?] {}", - "func foo() -> [↓Bool?] {}", - "static func foo() -> ↓Bool? {}", - "static func foo() -> [String: ↓Bool?] {}", - "static func foo() -> [↓Bool?] {}", - "func foo() -> (↓Bool?) -> String {}", - "func foo() -> ([Int]) -> ↓Bool? {}", + Example("func foo() -> ↓Bool? {}"), + Example("func foo() -> [String: ↓Bool?] {}"), + Example("func foo() -> [↓Bool?] {}"), + Example("static func foo() -> ↓Bool? {}"), + Example("static func foo() -> [String: ↓Bool?] {}"), + Example("static func foo() -> [↓Bool?] {}"), + Example("func foo() -> (↓Bool?) -> String {}"), + Example("func foo() -> ([Int]) -> ↓Bool? {}"), // Free function parameter - "func foo(input: ↓Bool?) {}", - "func foo(input: [String: ↓Bool?]) {}", - "func foo(input: [↓Bool?]) {}", - "static func foo(input: ↓Bool?) {}", - "static func foo(input: [String: ↓Bool?]) {}", - "static func foo(input: [↓Bool?]) {}", + Example("func foo(input: ↓Bool?) {}"), + Example("func foo(input: [String: ↓Bool?]) {}"), + Example("func foo(input: [↓Bool?]) {}"), + Example("static func foo(input: ↓Bool?) {}"), + Example("static func foo(input: [String: ↓Bool?]) {}"), + Example("static func foo(input: [↓Bool?]) {}"), // Instance variable wrapExample("class", "var foo: ↓Bool?"), @@ -160,6 +160,6 @@ internal struct DiscouragedOptionalBooleanRuleExamples { // MARK: - Private -private func wrapExample(_ type: String, _ test: String) -> String { - return "\(type) Foo {\n\t\(test)\n}" +private func wrapExample(_ type: String, _ test: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example("\(type) Foo {\n\t\(test)\n}", file: file, line: line) } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift index 69ef971ab4..4a798ea359 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift @@ -1,28 +1,28 @@ internal struct DiscouragedOptionalCollectionExamples { static let nonTriggeringExamples = [ // Global variable - "var foo: [Int]", - "var foo: [String: Int]", - "var foo: Set", - "var foo: [String: [String: Int]]", - "let foo: [Int] = []", - "let foo: [String: Int] = [:]", - "let foo: Set = []", - "let foo: [String: [String: Int]] = [:]", + Example("var foo: [Int]"), + Example("var foo: [String: Int]"), + Example("var foo: Set"), + Example("var foo: [String: [String: Int]]"), + Example("let foo: [Int] = []"), + Example("let foo: [String: Int] = [:]"), + Example("let foo: Set = []"), + Example("let foo: [String: [String: Int]] = [:]"), // Computed get variable - "var foo: [Int] { return [] }", + Example("var foo: [Int] { return [] }"), // Free function return - "func foo() -> [Int] {}", - "func foo() -> [String: String] {}", - "func foo() -> Set {}", - "func foo() -> ([Int]) -> String {}", + Example("func foo() -> [Int] {}"), + Example("func foo() -> [String: String] {}"), + Example("func foo() -> Set {}"), + Example("func foo() -> ([Int]) -> String {}"), // Free function parameter - "func foo(input: [String] = []) {}", - "func foo(input: [String: String] = [:]) {}", - "func foo(input: Set = []) {}", + Example("func foo(input: [String] = []) {}"), + Example("func foo(input: [String: String] = [:]) {}"), + Example("func foo(input: Set = []) {}"), // Method return wrapExample("class", "func foo() -> [Int] {}"), @@ -56,44 +56,44 @@ internal struct DiscouragedOptionalCollectionExamples { static let triggeringExamples = [ // Global variable - "↓var foo: [Int]?", - "↓var foo: [String: Int]?", - "↓var foo: Set?", - "↓let foo: [Int]? = nil", - "↓let foo: [String: Int]? = nil", - "↓let foo: Set? = nil", + Example("↓var foo: [Int]?"), + Example("↓var foo: [String: Int]?"), + Example("↓var foo: Set?"), + Example("↓let foo: [Int]? = nil"), + Example("↓let foo: [String: Int]? = nil"), + Example("↓let foo: Set? = nil"), // Computed Get Variable - "↓var foo: [Int]? { return nil }", - "↓let foo: [Int]? { return nil }()", + Example("↓var foo: [Int]? { return nil }"), + Example("↓let foo: [Int]? { return nil }()"), // Free function return - "func ↓foo() -> [T]? {}", - "func ↓foo() -> [String: String]? {}", - "func ↓foo() -> [String: [String: String]]? {}", - "func ↓foo() -> [String: [String: String]?] {}", - "func ↓foo() -> Set? {}", - "static func ↓foo() -> [T]? {}", - "static func ↓foo() -> [String: String]? {}", - "static func ↓foo() -> [String: [String: String]]? {}", - "static func ↓foo() -> [String: [String: String]?] {}", - "static func ↓foo() -> Set? {}", - "func ↓foo() -> ([Int]?) -> String {}", - "func ↓foo() -> ([Int]) -> [String]? {}", + Example("func ↓foo() -> [T]? {}"), + Example("func ↓foo() -> [String: String]? {}"), + Example("func ↓foo() -> [String: [String: String]]? {}"), + Example("func ↓foo() -> [String: [String: String]?] {}"), + Example("func ↓foo() -> Set? {}"), + Example("static func ↓foo() -> [T]? {}"), + Example("static func ↓foo() -> [String: String]? {}"), + Example("static func ↓foo() -> [String: [String: String]]? {}"), + Example("static func ↓foo() -> [String: [String: String]?] {}"), + Example("static func ↓foo() -> Set? {}"), + Example("func ↓foo() -> ([Int]?) -> String {}"), + Example("func ↓foo() -> ([Int]) -> [String]? {}"), // Free function parameter - "func foo(↓input: [String: String]?) {}", - "func foo(↓input: [String: [String: String]]?) {}", - "func foo(↓input: [String: [String: String]?]) {}", - "func foo(↓↓input: [String: [String: String]?]?) {}", - "func foo(_ dict1: [K: V], ↓_ dict2: [K: V]?) -> [K: V]", - "func foo(dict1: [K: V], ↓dict2: [K: V]?) -> [K: V]", - "static func foo(↓input: [String: String]?) {}", - "static func foo(↓input: [String: [String: String]]?) {}", - "static func foo(↓input: [String: [String: String]?]) {}", - "static func foo(↓↓input: [String: [String: String]?]?) {}", - "static func foo(_ dict1: [K: V], ↓_ dict2: [K: V]?) -> [K: V]", - "static func foo(dict1: [K: V], ↓dict2: [K: V]?) -> [K: V]", + Example("func foo(↓input: [String: String]?) {}"), + Example("func foo(↓input: [String: [String: String]]?) {}"), + Example("func foo(↓input: [String: [String: String]?]) {}"), + Example("func foo(↓↓input: [String: [String: String]?]?) {}"), + Example("func foo(_ dict1: [K: V], ↓_ dict2: [K: V]?) -> [K: V]"), + Example("func foo(dict1: [K: V], ↓dict2: [K: V]?) -> [K: V]"), + Example("static func foo(↓input: [String: String]?) {}"), + Example("static func foo(↓input: [String: [String: String]]?) {}"), + Example("static func foo(↓input: [String: [String: String]?]) {}"), + Example("static func foo(↓↓input: [String: [String: String]?]?) {}"), + Example("static func foo(_ dict1: [K: V], ↓_ dict2: [K: V]?) -> [K: V]"), + Example("static func foo(dict1: [K: V], ↓dict2: [K: V]?) -> [K: V]"), // Instance variable wrapExample("class", "↓var foo: [Int]?"), @@ -210,6 +210,10 @@ internal struct DiscouragedOptionalCollectionExamples { // MARK: - Private -private func wrapExample(_ type: String, _ test: String) -> String { - return "\(type) Foo {\n\t\(test)\n}" +private func wrapExample(_ type: String, _ test: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" + \(type) Foo { + \(test) + } + """, file: file, line: line) } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/DuplicateImportsRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/DuplicateImportsRuleExamples.swift index 244db52fb0..3dd47b222a 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/DuplicateImportsRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/DuplicateImportsRuleExamples.swift @@ -1,25 +1,25 @@ internal struct DuplicateImportsRuleExamples { - static let nonTriggeringExamples: [String] = [ - "import A\nimport B\nimport C", - "import A.B\nimport A.C", - """ + static let nonTriggeringExamples: [Example] = [ + Example("import A\nimport B\nimport C"), + Example("import A.B\nimport A.C"), + Example(""" #if DEBUG @testable import KsApi #else import KsApi #endif - """, - "import A // module\nimport B // module" + """), + Example("import A // module\nimport B // module") ] - static let triggeringExamples: [String] = { - var list: [String] = [ - "import Foundation\nimport Dispatch\n↓import Foundation", - "import Foundation\n↓import Foundation.NSString", - "↓import Foundation.NSString\nimport Foundation", - "↓import A.B.C\nimport A.B", - "import A.B\n↓import A.B.C", - """ + static let triggeringExamples: [Example] = { + var list: [Example] = [ + Example("import Foundation\nimport Dispatch\n↓import Foundation"), + Example("import Foundation\n↓import Foundation.NSString"), + Example("↓import Foundation.NSString\nimport Foundation"), + Example("↓import A.B.C\nimport A.B"), + Example("import A.B\n↓import A.B.C"), + Example(""" import A #if DEBUG @testable import KsApi @@ -27,28 +27,28 @@ internal struct DuplicateImportsRuleExamples { import KsApi #endif ↓import A - """ + """) ] list += DuplicateImportsRule.importKinds.map { importKind in - return """ + Example(""" import A ↓import \(importKind) A.Foo - """ + """) } list += DuplicateImportsRule.importKinds.map { importKind in - return """ - import A - ↓import \(importKind) A.B.Foo - """ + Example(""" + import A + ↓import \(importKind) A.B.Foo + """) } list += DuplicateImportsRule.importKinds.map { importKind in - return """ - import A.B - ↓import \(importKind) A.B.Foo - """ + Example(""" + import A.B + ↓import \(importKind) A.B.Foo + """) } return list diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitACLRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitACLRule.swift index 741eb6466f..3089cd63fc 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitACLRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitACLRule.swift @@ -14,42 +14,42 @@ public struct ExplicitACLRule: OptInRule, ConfigurationProviderRule, AutomaticTe description: "All declarations should specify Access Control Level keywords explicitly.", kind: .idiomatic, nonTriggeringExamples: [ - "internal enum A {}\n", - "public final class B {}\n", - "private struct C {}\n", - "internal enum A {\n internal enum B {}\n}", - "internal final class Foo {}", - """ + Example("internal enum A {}\n"), + Example("public final class B {}\n"), + Example("private struct C {}\n"), + Example("internal enum A {\n internal enum B {}\n}"), + Example("internal final class Foo {}"), + Example(""" internal class Foo { private let bar = 5 } - """, - "internal func a() { let a = }\n", - "private func a() { func innerFunction() { } }", - "private enum Foo { enum Bar { } }", - "private struct C { let d = 5 }", - """ + """), + Example("internal func a() { let a = }\n"), + Example("private func a() { func innerFunction() { } }"), + Example("private enum Foo { enum Bar { } }"), + Example("private struct C { let d = 5 }"), + Example(""" internal protocol A { func b() } - """, - """ + """), + Example(""" internal protocol A { var b: Int } - """, - "internal class A { deinit {} }", - "extension A: Equatable {}", - "extension A {}" + """), + Example("internal class A { deinit {} }"), + Example("extension A: Equatable {}"), + Example("extension A {}") ], triggeringExamples: [ - "enum A {}\n", - "final class B {}\n", - "internal struct C { let d = 5 }\n", - "public struct C { let d = 5 }\n", - "func a() {}\n", - "internal let a = 0\nfunc b() {}\n" + Example("enum A {}\n"), + Example("final class B {}\n"), + Example("internal struct C { let d = 5 }\n"), + Example("public struct C { let d = 5 }\n"), + Example("func a() {}\n"), + Example("internal let a = 0\nfunc b() {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitEnumRawValueRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitEnumRawValueRule.swift index a3bedb78d3..56b6a931d5 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitEnumRawValueRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitEnumRawValueRule.swift @@ -11,64 +11,64 @@ public struct ExplicitEnumRawValueRule: ASTRule, OptInRule, ConfigurationProvide description: "Enums should be explicitly assigned their raw values.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" enum Numbers { case int(Int) case short(Int16) } - """, - """ + """), + Example(""" enum Numbers: Int { case one = 1 case two = 2 } - """, - """ + """), + Example(""" enum Numbers: Double { case one = 1.1 case two = 2.2 } - """, - """ + """), + Example(""" enum Numbers: String { case one = "one" case two = "two" } - """, - """ + """), + Example(""" protocol Algebra {} enum Numbers: Algebra { case one } - """ + """) ], triggeringExamples: [ - """ + Example(""" enum Numbers: Int { case one = 10, ↓two, three = 30 } - """, - """ + """), + Example(""" enum Numbers: NSInteger { case ↓one } - """, - """ + """), + Example(""" enum Numbers: String { case ↓one case ↓two } - """, - """ + """), + Example(""" enum Numbers: String { case ↓one, two = "two" } - """, - """ + """), + Example(""" enum Numbers: Decimal { case ↓one, ↓two } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitInitRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitInitRule.swift index 4fa8ae029a..b833ca4fee 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitInitRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitInitRule.swift @@ -13,42 +13,42 @@ public struct ExplicitInitRule: SubstitutionCorrectableASTRule, ConfigurationPro description: "Explicitly calling .init() should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - "import Foundation; class C: NSObject { override init() { super.init() }}", // super - "struct S { let n: Int }; extension S { init() { self.init(n: 1) } }", // self - "[1].flatMap(String.init)", // pass init as closure - "[String.self].map { $0.init(1) }", // initialize from a metatype value - "[String.self].map { type in type.init(1) }", // initialize from a metatype value - "Observable.zip(obs1, obs2, resultSelector: MyType.init).asMaybe()", - """ + Example("import Foundation; class C: NSObject { override init() { super.init() }}"), // super + Example("struct S { let n: Int }; extension S { init() { self.init(n: 1) } }"), // self + Example("[1].flatMap(String.init)"), // pass init as closure + Example("[String.self].map { $0.init(1) }"), // initialize from a metatype value + Example("[String.self].map { type in type.init(1) }"), // initialize from a metatype value + Example("Observable.zip(obs1, obs2, resultSelector: MyType.init).asMaybe()"), + Example(""" Observable.zip( obs1, obs2, resultSelector: MyType.init ).asMaybe() - """ + """) ], triggeringExamples: [ - "[1].flatMap{String↓.init($0)}", - "[String.self].map { Type in Type↓.init(1) }", // starting with capital assumes as type, - """ + Example("[1].flatMap{String↓.init($0)}"), + Example("[String.self].map { Type in Type↓.init(1) }"), // starting with capital assumes as type, + Example(""" func foo() -> [String] { return [1].flatMap { String↓.init($0) } } - """, - """ + """), + Example(""" Observable.zip( obs1, obs2, resultSelector: { MyType.init($0, $1) } ).asMaybe() - """ + """) ], corrections: [ - "[1].flatMap{String↓.init($0)}": "[1].flatMap{String($0)}", - "func foo() -> [String] {\n return [1].flatMap { String↓.init($0) }\n}": - "func foo() -> [String] {\n return [1].flatMap { String($0) }\n}", - "class C {\n#if true\nfunc f() {\n[1].flatMap{String.init($0)}\n}\n#endif\n}": - "class C {\n#if true\nfunc f() {\n[1].flatMap{String($0)}\n}\n#endif\n}" + Example("[1].flatMap{String↓.init($0)}"): Example("[1].flatMap{String($0)}"), + Example("func foo() -> [String] {\n return [1].flatMap { String↓.init($0) }\n}"): + Example("func foo() -> [String] {\n return [1].flatMap { String($0) }\n}"), + Example("class C {\n#if true\nfunc f() {\n[1].flatMap{String.init($0)}\n}\n#endif\n}"): + Example("class C {\n#if true\nfunc f() {\n[1].flatMap{String($0)}\n}\n#endif\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTopLevelACLRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTopLevelACLRule.swift index d1f3a4d119..136974e220 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTopLevelACLRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTopLevelACLRule.swift @@ -12,22 +12,22 @@ public struct ExplicitTopLevelACLRule: OptInRule, ConfigurationProviderRule, Aut description: "Top-level declarations should specify Access Control Level keywords explicitly.", kind: .idiomatic, nonTriggeringExamples: [ - "internal enum A {}\n", - "public final class B {}\n", - "private struct C {}\n", - "internal enum A {\n enum B {}\n}", - "internal final class Foo {}", - "internal\nclass Foo {}", - "internal func a() {}\n", - "extension A: Equatable {}", - "extension A {}" + Example("internal enum A {}\n"), + Example("public final class B {}\n"), + Example("private struct C {}\n"), + Example("internal enum A {\n enum B {}\n}"), + Example("internal final class Foo {}"), + Example("internal\nclass Foo {}"), + Example("internal func a() {}\n"), + Example("extension A: Equatable {}"), + Example("extension A {}") ], triggeringExamples: [ - "enum A {}\n", - "final class B {}\n", - "struct C {}\n", - "func a() {}\n", - "internal let a = 0\nfunc b() {}\n" + Example("enum A {}\n"), + Example("final class B {}\n"), + Example("struct C {}\n"), + Example("func a() {}\n"), + Example("internal let a = 0\nfunc b() {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTypeInterfaceRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTypeInterfaceRule.swift index 6806300cf2..0bc32acc6e 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTypeInterfaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExplicitTypeInterfaceRule.swift @@ -12,58 +12,58 @@ public struct ExplicitTypeInterfaceRule: OptInRule, ConfigurationProviderRule { description: "Properties should have a type interface", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" class Foo { var myVar: Int? = 0 } - """, - """ + """), + Example(""" class Foo { let myVar: Int? = 0 } - """, - """ + """), + Example(""" class Foo { static var myVar: Int? = 0 } - """, - """ + """), + Example(""" class Foo { class var myVar: Int? = 0 } - """ + """) ], triggeringExamples: [ - """ + Example(""" class Foo { ↓var myVar = 0 } - """, - """ + """), + Example(""" class Foo { ↓let mylet = 0 } - """, - """ + """), + Example(""" class Foo { ↓static var myStaticVar = 0 } - """, - """ + """), + Example(""" class Foo { ↓class var myClassVar = 0 } - """, - """ + """), + Example(""" class Foo { ↓let myVar = Int(0) } - """, - """ + """), + Example(""" class Foo { ↓let myVar = Set(0) } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ExtensionAccessModifierRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ExtensionAccessModifierRule.swift index 382120d733..e0b82d84c3 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ExtensionAccessModifierRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ExtensionAccessModifierRule.swift @@ -12,67 +12,67 @@ public struct ExtensionAccessModifierRule: ASTRule, ConfigurationProviderRule, O description: "Prefer to use extension access modifiers", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" extension Foo: SomeProtocol { public var bar: Int { return 1 } } - """, - """ + """), + Example(""" extension Foo { private var bar: Int { return 1 } public var baz: Int { return 1 } } - """, - """ + """), + Example(""" extension Foo { private var bar: Int { return 1 } public func baz() {} } - """, - """ + """), + Example(""" extension Foo { var bar: Int { return 1 } var baz: Int { return 1 } } - """, - """ + """), + Example(""" public extension Foo { var bar: Int { return 1 } var baz: Int { return 1 } } - """, - """ + """), + Example(""" extension Foo { private bar: Int { return 1 } private baz: Int { return 1 } } - """, - """ + """), + Example(""" extension Foo { open bar: Int { return 1 } open baz: Int { return 1 } } - """ + """) ], triggeringExamples: [ - """ + Example(""" ↓extension Foo { public var bar: Int { return 1 } public var baz: Int { return 1 } } - """, - """ + """), + Example(""" ↓extension Foo { public var bar: Int { return 1 } public func baz() {} } - """, - """ + """), + Example(""" public extension Foo { public ↓func bar() {} public ↓func baz() {} } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/FallthroughRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/FallthroughRule.swift index af4c4c4665..7af5af6ec6 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/FallthroughRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/FallthroughRule.swift @@ -11,22 +11,22 @@ public struct FallthroughRule: ConfigurationProviderRule, OptInRule, AutomaticTe description: "Fallthrough should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" switch foo { case .bar, .bar2, .bar3: something() } - """ + """) ], triggeringExamples: [ - """ + Example(""" switch foo { case .bar: ↓fallthrough case .bar2: something() } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/FatalErrorMessageRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/FatalErrorMessageRule.swift index e4ee5a0e08..32b9325864 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/FatalErrorMessageRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/FatalErrorMessageRule.swift @@ -11,28 +11,28 @@ public struct FatalErrorMessageRule: ASTRule, ConfigurationProviderRule, OptInRu description: "A fatalError call should have a message.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" func foo() { fatalError("Foo") } - """, - """ + """), + Example(""" func foo() { fatalError(x) } - """ + """) ], triggeringExamples: [ - """ + Example(""" func foo() { ↓fatalError("") } - """, - """ + """), + Example(""" func foo() { ↓fatalError() } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ForWhereRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ForWhereRule.swift index 5cc1df681d..a08ccc0f44 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ForWhereRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ForWhereRule.swift @@ -11,76 +11,76 @@ public struct ForWhereRule: ASTRule, ConfigurationProviderRule, AutomaticTestabl description: "`where` clauses are preferred over a single `if` inside a `for`.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" for user in users where user.id == 1 { } - """, + """), // if let - """ + Example(""" for user in users { if let id = user.id { } } - """, + """), // if var - """ + Example(""" for user in users { if var id = user.id { } } - """, + """), // if with else - """ + Example(""" for user in users { if user.id == 1 { } else { } } - """, + """), // if with else if - """ + Example(""" for user in users { if user.id == 1 { } else if user.id == 2 { } } - """, + """), // if is not the only expression inside for - """ + Example(""" for user in users { if user.id == 1 { } print(user) } - """, + """), // if a variable is used - """ + Example(""" for user in users { let id = user.id if id == 1 { } } - """, + """), // if something is after if - """ + Example(""" for user in users { if user.id == 1 { } return true } - """, + """), // condition with multiple clauses - """ + Example(""" for user in users { if user.id == 1 && user.age > 18 { } } - """, + """), // if case - """ + Example(""" for (index, value) in array.enumerated() { if case .valueB(_) = value { return index } } - """ + """) ], triggeringExamples: [ - """ + Example(""" for user in users { ↓if user.id == 1 { return true } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ForceCastRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ForceCastRule.swift index dea742bc47..1df4be0631 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ForceCastRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ForceCastRule.swift @@ -11,9 +11,9 @@ public struct ForceCastRule: ConfigurationProviderRule, AutomaticTestableRule { description: "Force casts should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - "NSNumber() as? Int\n" + Example("NSNumber() as? Int\n") ], - triggeringExamples: [ "NSNumber() ↓as! Int\n" ] + triggeringExamples: [ Example("NSNumber() ↓as! Int\n") ] ) public func validate(file: SwiftLintFile) -> [StyleViolation] { diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ForceTryRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ForceTryRule.swift index e8992e0e55..d6cb4ecfae 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ForceTryRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ForceTryRule.swift @@ -11,18 +11,18 @@ public struct ForceTryRule: ConfigurationProviderRule, AutomaticTestableRule { description: "Force tries should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" func a() throws {} do { try a() } catch {} - """ + """) ], triggeringExamples: [ - """ + Example(""" func a() throws {} ↓try! a() - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ForceUnwrappingRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ForceUnwrappingRule.swift index 23e6b9786f..642beeff65 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ForceUnwrappingRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ForceUnwrappingRule.swift @@ -12,46 +12,46 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule, Automat description: "Force unwrapping should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - "if let url = NSURL(string: query)", - "navigationController?.pushViewController(viewController, animated: true)", - "let s as! Test", - "try! canThrowErrors()", - "let object: Any!", - "@IBOutlet var constraints: [NSLayoutConstraint]!", - "setEditing(!editing, animated: true)", - "navigationController.setNavigationBarHidden(!navigationController." + - "navigationBarHidden, animated: true)", - "if addedToPlaylist && (!self.selectedFilters.isEmpty || " + - "self.searchBar?.text?.isEmpty == false) {}", - "print(\"\\(xVar)!\")", - "var test = (!bar)", - "var a: [Int]!", - "private var myProperty: (Void -> Void)!", - "func foo(_ options: [AnyHashable: Any]!) {", - "func foo() -> [Int]!", - "func foo() -> [AnyHashable: Any]!", - "func foo() -> [Int]! { return [] }", - "return self" + Example("if let url = NSURL(string: query)"), + Example("navigationController?.pushViewController(viewController, animated: true)"), + Example("let s as! Test"), + Example("try! canThrowErrors()"), + Example("let object: Any!"), + Example("@IBOutlet var constraints: [NSLayoutConstraint]!"), + Example("setEditing(!editing, animated: true)"), + Example("navigationController.setNavigationBarHidden(!navigationController." + + "navigationBarHidden, animated: true)"), + Example("if addedToPlaylist && (!self.selectedFilters.isEmpty || " + + "self.searchBar?.text?.isEmpty == false) {}"), + Example("print(\"\\(xVar)!\")"), + Example("var test = (!bar)"), + Example("var a: [Int]!"), + Example("private var myProperty: (Void -> Void)!"), + Example("func foo(_ options: [AnyHashable: Any]!) {"), + Example("func foo() -> [Int]!"), + Example("func foo() -> [AnyHashable: Any]!"), + Example("func foo() -> [Int]! { return [] }"), + Example("return self") ], triggeringExamples: [ - "let url = NSURL(string: query)↓!", - "navigationController↓!.pushViewController(viewController, animated: true)", - "let unwrapped = optional↓!", - "return cell↓!", - "let url = NSURL(string: \"http://www.google.com\")↓!", - "let dict = [\"Boooo\": \"👻\"]func bla() -> String { return dict[\"Boooo\"]↓! }", - "let dict = [\"Boooo\": \"👻\"]func bla() -> String { return dict[\"Boooo\"]↓!.contains(\"B\") }", - "let a = dict[\"abc\"]↓!.contains(\"B\")", - "dict[\"abc\"]↓!.bar(\"B\")", - "if dict[\"a\"]↓!!!! {", - "var foo: [Bool]! = dict[\"abc\"]↓!", - """ - context(\"abc\") { - var foo: [Bool]! = dict[\"abc\"]↓! + Example("let url = NSURL(string: query)↓!"), + Example("navigationController↓!.pushViewController(viewController, animated: true)"), + Example("let unwrapped = optional↓!"), + Example("return cell↓!"), + Example("let url = NSURL(string: \"http://www.google.com\")↓!"), + Example("let dict = [\"Boooo\": \"👻\"]func bla() -> String { return dict[\"Boooo\"]↓! }"), + Example("let dict = [\"Boooo\": \"👻\"]func bla() -> String { return dict[\"Boooo\"]↓!.contains(\"B\") }"), + Example("let a = dict[\"abc\"]↓!.contains(\"B\")"), + Example("dict[\"abc\"]↓!.bar(\"B\")"), + Example("if dict[\"a\"]↓!!!! {"), + Example("var foo: [Bool]! = dict[\"abc\"]↓!"), + Example(""" + context("abc") { + var foo: [Bool]! = dict["abc"]↓! } - """, - "open var computed: String { return foo.bar↓! }", - "return self↓!" + """), + Example("open var computed: String { return foo.bar↓! }"), + Example("return self↓!") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/FunctionDefaultParameterAtEndRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/FunctionDefaultParameterAtEndRule.swift index b9face6161..a82dd49382 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/FunctionDefaultParameterAtEndRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/FunctionDefaultParameterAtEndRule.swift @@ -11,29 +11,29 @@ public struct FunctionDefaultParameterAtEndRule: ASTRule, ConfigurationProviderR description: "Prefer to locate parameters with defaults toward the end of the parameter list.", kind: .idiomatic, nonTriggeringExamples: [ - "func foo(baz: String, bar: Int = 0) {}", - "func foo(x: String, y: Int = 0, z: CGFloat = 0) {}", - "func foo(bar: String, baz: Int = 0, z: () -> Void) {}", - "func foo(bar: String, z: () -> Void, baz: Int = 0) {}", - "func foo(bar: Int = 0) {}", - "func foo() {}", - """ + Example("func foo(baz: String, bar: Int = 0) {}"), + Example("func foo(x: String, y: Int = 0, z: CGFloat = 0) {}"), + Example("func foo(bar: String, baz: Int = 0, z: () -> Void) {}"), + Example("func foo(bar: String, z: () -> Void, baz: Int = 0) {}"), + Example("func foo(bar: Int = 0) {}"), + Example("func foo() {}"), + Example(""" class A: B { override func foo(bar: Int = 0, baz: String) {} - """, - "func foo(bar: Int = 0, completion: @escaping CompletionHandler) {}", - """ + """), + Example("func foo(bar: Int = 0, completion: @escaping CompletionHandler) {}"), + Example(""" func foo(a: Int, b: CGFloat = 0) { let block = { (error: Error?) in } } - """, - """ + """), + Example(""" func foo(a: String, b: String? = nil, c: String? = nil, d: @escaping AlertActionHandler = { _ in }) {} - """ + """) ], triggeringExamples: [ - "↓func foo(bar: Int = 0, baz: String) {}" + Example("↓func foo(bar: Int = 0, baz: String) {}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/GenericTypeNameRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/GenericTypeNameRule.swift index 7fbe7db5ff..0b86a6a5a2 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/GenericTypeNameRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/GenericTypeNameRule.swift @@ -16,36 +16,36 @@ public struct GenericTypeNameRule: ASTRule, ConfigurationProviderRule { "uppercase character and span between 1 and 20 characters in length.", kind: .idiomatic, nonTriggeringExamples: [ - "func foo() {}\n", - "func foo() -> T {}\n", - "func foo(param: U) -> T {}\n", - "func foo(param: U) -> T {}\n", - "struct Foo {}\n", - "class Foo {}\n", - "enum Foo {}\n", - "func run(_ options: NoOptions>) {}\n", - "func foo(_ options: Set) {}\n", - "func < (lhs: T?, rhs: T?) -> Bool\n", - "func configureWith(data: Either)\n", - "typealias StringDictionary = Dictionary\n", - "typealias BackwardTriple = (T3, T2, T1)\n", - "typealias DictionaryOfStrings = Dictionary\n" + Example("func foo() {}\n"), + Example("func foo() -> T {}\n"), + Example("func foo(param: U) -> T {}\n"), + Example("func foo(param: U) -> T {}\n"), + Example("struct Foo {}\n"), + Example("class Foo {}\n"), + Example("enum Foo {}\n"), + Example("func run(_ options: NoOptions>) {}\n"), + Example("func foo(_ options: Set) {}\n"), + Example("func < (lhs: T?, rhs: T?) -> Bool\n"), + Example("func configureWith(data: Either)\n"), + Example("typealias StringDictionary = Dictionary\n"), + Example("typealias BackwardTriple = (T3, T2, T1)\n"), + Example("typealias DictionaryOfStrings = Dictionary\n") ], triggeringExamples: [ - "func foo<↓T_Foo>() {}\n", - "func foo(param: U_Foo) -> T {}\n", - "func foo<↓\(String(repeating: "T", count: 21))>() {}\n", - "func foo<↓type>() {}\n", - "typealias StringDictionary<↓T_Foo> = Dictionary\n", - "typealias BackwardTriple = (T3, T2_Bar, T1)\n", - "typealias DictionaryOfStrings<↓T_Foo: Hashable> = Dictionary\n" - ] + ["class", "struct", "enum"].flatMap { type -> [String] in + Example("func foo<↓T_Foo>() {}\n"), + Example("func foo(param: U_Foo) -> T {}\n"), + Example("func foo<↓\(String(repeating: "T", count: 21))>() {}\n"), + Example("func foo<↓type>() {}\n"), + Example("typealias StringDictionary<↓T_Foo> = Dictionary\n"), + Example("typealias BackwardTriple = (T3, T2_Bar, T1)\n"), + Example("typealias DictionaryOfStrings<↓T_Foo: Hashable> = Dictionary\n") + ] + ["class", "struct", "enum"].flatMap { type -> [Example] in return [ - "\(type) Foo<↓T_Foo> {}\n", - "\(type) Foo {}\n", - "\(type) Foo<↓T_Foo, ↓U_Foo> {}\n", - "\(type) Foo<↓\(String(repeating: "T", count: 21))> {}\n", - "\(type) Foo<↓type> {}\n" + Example("\(type) Foo<↓T_Foo> {}\n"), + Example("\(type) Foo {}\n"), + Example("\(type) Foo<↓T_Foo, ↓U_Foo> {}\n"), + Example("\(type) Foo<↓\(String(repeating: "T", count: 21))> {}\n"), + Example("\(type) Foo<↓type> {}\n") ] } ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift index 546f4fbf7b..da270c73c6 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift @@ -13,25 +13,25 @@ public struct ImplicitlyUnwrappedOptionalRule: ASTRule, ConfigurationProviderRul description: "Implicitly unwrapped optionals should be avoided when possible.", kind: .idiomatic, nonTriggeringExamples: [ - "@IBOutlet private var label: UILabel!", - "@IBOutlet var label: UILabel!", - "@IBOutlet var label: [UILabel!]", - "if !boolean {}", - "let int: Int? = 42", - "let int: Int? = nil" + Example("@IBOutlet private var label: UILabel!"), + Example("@IBOutlet var label: UILabel!"), + Example("@IBOutlet var label: [UILabel!]"), + Example("if !boolean {}"), + Example("let int: Int? = 42"), + Example("let int: Int? = nil") ], triggeringExamples: [ - "let label: UILabel!", - "let IBOutlet: UILabel!", - "let labels: [UILabel!]", - "var ints: [Int!] = [42, nil, 42]", - "let label: IBOutlet!", - "let int: Int! = 42", - "let int: Int! = nil", - "var int: Int! = 42", - "let int: ImplicitlyUnwrappedOptional", - "let collection: AnyCollection", - "func foo(int: Int!) {}" + Example("let label: UILabel!"), + Example("let IBOutlet: UILabel!"), + Example("let labels: [UILabel!]"), + Example("var ints: [Int!] = [42, nil, 42]"), + Example("let label: IBOutlet!"), + Example("let int: Int! = 42"), + Example("let int: Int! = nil"), + Example("var int: Int! = 42"), + Example("let int: ImplicitlyUnwrappedOptional"), + Example("let collection: AnyCollection"), + Example("func foo(int: Int!) {}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/IsDisjointRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/IsDisjointRule.swift index ec074d8846..dc5acdd4ee 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/IsDisjointRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/IsDisjointRule.swift @@ -11,14 +11,14 @@ public struct IsDisjointRule: ConfigurationProviderRule, AutomaticTestableRule { description: "Prefer using `Set.isDisjoint(with:)` over `Set.intersection(_:).isEmpty`.", kind: .idiomatic, nonTriggeringExamples: [ - "_ = Set(syntaxKinds).isDisjoint(with: commentAndStringKindsSet)", - "let isObjc = !objcAttributes.isDisjoint(with: dictionary.enclosedSwiftAttributes)", - "_ = Set(syntaxKinds).intersection(commentAndStringKindsSet)", - "_ = !objcAttributes.intersection(dictionary.enclosedSwiftAttributes)" + Example("_ = Set(syntaxKinds).isDisjoint(with: commentAndStringKindsSet)"), + Example("let isObjc = !objcAttributes.isDisjoint(with: dictionary.enclosedSwiftAttributes)"), + Example("_ = Set(syntaxKinds).intersection(commentAndStringKindsSet)"), + Example("_ = !objcAttributes.intersection(dictionary.enclosedSwiftAttributes)") ], triggeringExamples: [ - "_ = Set(syntaxKinds).↓intersection(commentAndStringKindsSet).isEmpty", - "let isObjc = !objcAttributes.↓intersection(dictionary.enclosedSwiftAttributes).isEmpty" + Example("_ = Set(syntaxKinds).↓intersection(commentAndStringKindsSet).isEmpty"), + Example("let isObjc = !objcAttributes.↓intersection(dictionary.enclosedSwiftAttributes).isEmpty") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/JoinedDefaultParameterRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/JoinedDefaultParameterRule.swift index a5eb554f70..47dd905a47 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/JoinedDefaultParameterRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/JoinedDefaultParameterRule.swift @@ -13,29 +13,30 @@ public struct JoinedDefaultParameterRule: SubstitutionCorrectableASTRule, Config description: "Discouraged explicit usage of the default separator.", kind: .idiomatic, nonTriggeringExamples: [ - "let foo = bar.joined()", - "let foo = bar.joined(separator: \",\")", - "let foo = bar.joined(separator: toto)" + Example("let foo = bar.joined()"), + Example("let foo = bar.joined(separator: \",\")"), + Example("let foo = bar.joined(separator: toto)") ], triggeringExamples: [ - "let foo = bar.joined(↓separator: \"\")", - """ + Example("let foo = bar.joined(↓separator: \"\")"), + Example(""" let foo = bar.filter(toto) .joined(↓separator: ""), - """, - """ + """), + Example(""" func foo() -> String { return ["1", "2"].joined(↓separator: "") } - """ + """) ], corrections: [ - "let foo = bar.joined(↓separator: \"\")": "let foo = bar.joined()", - "let foo = bar.filter(toto)\n.joined(↓separator: \"\")": "let foo = bar.filter(toto)\n.joined()", - "func foo() -> String {\n return [\"1\", \"2\"].joined(↓separator: \"\")\n}": - "func foo() -> String {\n return [\"1\", \"2\"].joined()\n}", - "class C {\n#if true\nlet foo = bar.joined(↓separator: \"\")\n#endif\n}": - "class C {\n#if true\nlet foo = bar.joined()\n#endif\n}" + Example("let foo = bar.joined(↓separator: \"\")"): Example("let foo = bar.joined()"), + Example("let foo = bar.filter(toto)\n.joined(↓separator: \"\")"): + Example("let foo = bar.filter(toto)\n.joined()"), + Example("func foo() -> String {\n return [\"1\", \"2\"].joined(↓separator: \"\")\n}"): + Example("func foo() -> String {\n return [\"1\", \"2\"].joined()\n}"), + Example("class C {\n#if true\nlet foo = bar.joined(↓separator: \"\")\n#endif\n}"): + Example("class C {\n#if true\nlet foo = bar.joined()\n#endif\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyCGGeometryFunctionsRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyCGGeometryFunctionsRule.swift index 46c1fd6321..ba1f1f5125 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyCGGeometryFunctionsRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyCGGeometryFunctionsRule.swift @@ -12,73 +12,73 @@ public struct LegacyCGGeometryFunctionsRule: CorrectableRule, ConfigurationProvi description: "Struct extension properties and methods are preferred over legacy functions", kind: .idiomatic, nonTriggeringExamples: [ - "rect.width", - "rect.height", - "rect.minX", - "rect.midX", - "rect.maxX", - "rect.minY", - "rect.midY", - "rect.maxY", - "rect.isNull", - "rect.isEmpty", - "rect.isInfinite", - "rect.standardized", - "rect.integral", - "rect.insetBy(dx: 5.0, dy: -7.0)", - "rect.offsetBy(dx: 5.0, dy: -7.0)", - "rect1.union(rect2)", - "rect1.intersect(rect2)", + Example("rect.width"), + Example("rect.height"), + Example("rect.minX"), + Example("rect.midX"), + Example("rect.maxX"), + Example("rect.minY"), + Example("rect.midY"), + Example("rect.maxY"), + Example("rect.isNull"), + Example("rect.isEmpty"), + Example("rect.isInfinite"), + Example("rect.standardized"), + Example("rect.integral"), + Example("rect.insetBy(dx: 5.0, dy: -7.0)"), + Example("rect.offsetBy(dx: 5.0, dy: -7.0)"), + Example("rect1.union(rect2)"), + Example("rect1.intersect(rect2)"), // "rect.divide(atDistance: 10.2, fromEdge: edge)", No correction available for divide - "rect1.contains(rect2)", - "rect.contains(point)", - "rect1.intersects(rect2)" + Example("rect1.contains(rect2)"), + Example("rect.contains(point)"), + Example("rect1.intersects(rect2)") ], triggeringExamples: [ - "↓CGRectGetWidth(rect)", - "↓CGRectGetHeight(rect)", - "↓CGRectGetMinX(rect)", - "↓CGRectGetMidX(rect)", - "↓CGRectGetMaxX(rect)", - "↓CGRectGetMinY(rect)", - "↓CGRectGetMidY(rect)", - "↓CGRectGetMaxY(rect)", - "↓CGRectIsNull(rect)", - "↓CGRectIsEmpty(rect)", - "↓CGRectIsInfinite(rect)", - "↓CGRectStandardize(rect)", - "↓CGRectIntegral(rect)", - "↓CGRectInset(rect, 10, 5)", - "↓CGRectOffset(rect, -2, 8.3)", - "↓CGRectUnion(rect1, rect2)", - "↓CGRectIntersection(rect1, rect2)", - "↓CGRectContainsRect(rect1, rect2)", - "↓CGRectContainsPoint(rect, point)", - "↓CGRectIntersectsRect(rect1, rect2)" + Example("↓CGRectGetWidth(rect)"), + Example("↓CGRectGetHeight(rect)"), + Example("↓CGRectGetMinX(rect)"), + Example("↓CGRectGetMidX(rect)"), + Example("↓CGRectGetMaxX(rect)"), + Example("↓CGRectGetMinY(rect)"), + Example("↓CGRectGetMidY(rect)"), + Example("↓CGRectGetMaxY(rect)"), + Example("↓CGRectIsNull(rect)"), + Example("↓CGRectIsEmpty(rect)"), + Example("↓CGRectIsInfinite(rect)"), + Example("↓CGRectStandardize(rect)"), + Example("↓CGRectIntegral(rect)"), + Example("↓CGRectInset(rect, 10, 5)"), + Example("↓CGRectOffset(rect, -2, 8.3)"), + Example("↓CGRectUnion(rect1, rect2)"), + Example("↓CGRectIntersection(rect1, rect2)"), + Example("↓CGRectContainsRect(rect1, rect2)"), + Example("↓CGRectContainsPoint(rect, point)"), + Example("↓CGRectIntersectsRect(rect1, rect2)") ], corrections: [ - "↓CGRectGetWidth( rect )\n": "rect.width\n", - "↓CGRectGetHeight(rect )\n": "rect.height\n", - "↓CGRectGetMinX( rect)\n": "rect.minX\n", - "↓CGRectGetMidX( rect)\n": "rect.midX\n", - "↓CGRectGetMaxX( rect)\n": "rect.maxX\n", - "↓CGRectGetMinY(rect )\n": "rect.minY\n", - "↓CGRectGetMidY(rect )\n": "rect.midY\n", - "↓CGRectGetMaxY( rect )\n": "rect.maxY\n", - "↓CGRectIsNull( rect )\n": "rect.isNull\n", - "↓CGRectIsEmpty( rect )\n": "rect.isEmpty\n", - "↓CGRectIsInfinite( rect )\n": "rect.isInfinite\n", - "↓CGRectStandardize( rect)\n": "rect.standardized\n", - "↓CGRectIntegral(rect )\n": "rect.integral\n", - "↓CGRectInset(rect, 5.0, -7.0)\n": "rect.insetBy(dx: 5.0, dy: -7.0)\n", - "↓CGRectOffset(rect, -2, 8.3)\n": "rect.offsetBy(dx: -2, dy: 8.3)\n", - "↓CGRectUnion(rect1, rect2)\n": "rect1.union(rect2)\n", - "↓CGRectIntersection( rect1 ,rect2)\n": "rect1.intersect(rect2)\n", - "↓CGRectContainsRect( rect1,rect2 )\n": "rect1.contains(rect2)\n", - "↓CGRectContainsPoint(rect ,point)\n": "rect.contains(point)\n", - "↓CGRectIntersectsRect( rect1,rect2 )\n": "rect1.intersects(rect2)\n", - "↓CGRectIntersectsRect(rect1, rect2 )\n↓CGRectGetWidth(rect )\n": - "rect1.intersects(rect2)\nrect.width\n" + Example("↓CGRectGetWidth( rect )\n"): Example("rect.width\n"), + Example("↓CGRectGetHeight(rect )\n"): Example("rect.height\n"), + Example("↓CGRectGetMinX( rect)\n"): Example("rect.minX\n"), + Example("↓CGRectGetMidX( rect)\n"): Example("rect.midX\n"), + Example("↓CGRectGetMaxX( rect)\n"): Example("rect.maxX\n"), + Example("↓CGRectGetMinY(rect )\n"): Example("rect.minY\n"), + Example("↓CGRectGetMidY(rect )\n"): Example("rect.midY\n"), + Example("↓CGRectGetMaxY( rect )\n"): Example("rect.maxY\n"), + Example("↓CGRectIsNull( rect )\n"): Example("rect.isNull\n"), + Example("↓CGRectIsEmpty( rect )\n"): Example("rect.isEmpty\n"), + Example("↓CGRectIsInfinite( rect )\n"): Example("rect.isInfinite\n"), + Example("↓CGRectStandardize( rect)\n"): Example("rect.standardized\n"), + Example("↓CGRectIntegral(rect )\n"): Example("rect.integral\n"), + Example("↓CGRectInset(rect, 5.0, -7.0)\n"): Example("rect.insetBy(dx: 5.0, dy: -7.0)\n"), + Example("↓CGRectOffset(rect, -2, 8.3)\n"): Example("rect.offsetBy(dx: -2, dy: 8.3)\n"), + Example("↓CGRectUnion(rect1, rect2)\n"): Example("rect1.union(rect2)\n"), + Example("↓CGRectIntersection( rect1 ,rect2)\n"): Example("rect1.intersect(rect2)\n"), + Example("↓CGRectContainsRect( rect1,rect2 )\n"): Example("rect1.contains(rect2)\n"), + Example("↓CGRectContainsPoint(rect ,point)\n"): Example("rect.contains(point)\n"), + Example("↓CGRectIntersectsRect( rect1,rect2 )\n"): Example("rect1.intersects(rect2)\n"), + Example("↓CGRectIntersectsRect(rect1, rect2 )\n↓CGRectGetWidth(rect )\n"): + Example("rect1.intersects(rect2)\nrect.width\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstantRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstantRuleExamples.swift index 53d2cfaa3f..7242e6e5ae 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstantRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstantRuleExamples.swift @@ -1,43 +1,43 @@ internal struct LegacyConstantRuleExamples { - static let nonTriggeringExamples = [ - "CGRect.infinite", - "CGPoint.zero", - "CGRect.zero", - "CGSize.zero", - "NSPoint.zero", - "NSRect.zero", - "NSSize.zero", - "CGRect.null", - "CGFloat.pi", - "Float.pi" + static let nonTriggeringExamples: [Example] = [ + Example("CGRect.infinite"), + Example("CGPoint.zero"), + Example("CGRect.zero"), + Example("CGSize.zero"), + Example("NSPoint.zero"), + Example("NSRect.zero"), + Example("NSSize.zero"), + Example("CGRect.null"), + Example("CGFloat.pi"), + Example("Float.pi") ] - static let triggeringExamples = [ - "↓CGRectInfinite", - "↓CGPointZero", - "↓CGRectZero", - "↓CGSizeZero", - "↓NSZeroPoint", - "↓NSZeroRect", - "↓NSZeroSize", - "↓CGRectNull", - "↓CGFloat(M_PI)", - "↓Float(M_PI)" + static let triggeringExamples: [Example] = [ + Example("↓CGRectInfinite"), + Example("↓CGPointZero"), + Example("↓CGRectZero"), + Example("↓CGSizeZero"), + Example("↓NSZeroPoint"), + Example("↓NSZeroRect"), + Example("↓NSZeroSize"), + Example("↓CGRectNull"), + Example("↓CGFloat(M_PI)"), + Example("↓Float(M_PI)") ] - static let corrections = [ - "↓CGRectInfinite": "CGRect.infinite", - "↓CGPointZero": "CGPoint.zero", - "↓CGRectZero": "CGRect.zero", - "↓CGSizeZero": "CGSize.zero", - "↓NSZeroPoint": "NSPoint.zero", - "↓NSZeroRect": "NSRect.zero", - "↓NSZeroSize": "NSSize.zero", - "↓CGRectNull": "CGRect.null", - "↓CGRectInfinite\n↓CGRectNull\n": "CGRect.infinite\nCGRect.null\n", - "↓CGFloat(M_PI)": "CGFloat.pi", - "↓Float(M_PI)": "Float.pi", - "↓CGFloat(M_PI)\n↓Float(M_PI)\n": "CGFloat.pi\nFloat.pi\n" + static let corrections: [Example: Example] = [ + Example("↓CGRectInfinite"): Example("CGRect.infinite"), + Example("↓CGPointZero"): Example("CGPoint.zero"), + Example("↓CGRectZero"): Example("CGRect.zero"), + Example("↓CGSizeZero"): Example("CGSize.zero"), + Example("↓NSZeroPoint"): Example("NSPoint.zero"), + Example("↓NSZeroRect"): Example("NSRect.zero"), + Example("↓NSZeroSize"): Example("NSSize.zero"), + Example("↓CGRectNull"): Example("CGRect.null"), + Example("↓CGRectInfinite\n↓CGRectNull\n"): Example("CGRect.infinite\nCGRect.null\n"), + Example("↓CGFloat(M_PI)"): Example("CGFloat.pi"), + Example("↓Float(M_PI)"): Example("Float.pi"), + Example("↓CGFloat(M_PI)\n↓Float(M_PI)\n"): Example("CGFloat.pi\nFloat.pi\n") ] static let patterns = [ diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstructorRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstructorRule.swift index c62bb1fd38..cecd716478 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstructorRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyConstructorRule.swift @@ -12,92 +12,92 @@ public struct LegacyConstructorRule: ASTRule, CorrectableRule, ConfigurationProv description: "Swift constructors are preferred over legacy convenience functions.", kind: .idiomatic, nonTriggeringExamples: [ - "CGPoint(x: 10, y: 10)", - "CGPoint(x: xValue, y: yValue)", - "CGSize(width: 10, height: 10)", - "CGSize(width: aWidth, height: aHeight)", - "CGRect(x: 0, y: 0, width: 10, height: 10)", - "CGRect(x: xVal, y: yVal, width: aWidth, height: aHeight)", - "CGVector(dx: 10, dy: 10)", - "CGVector(dx: deltaX, dy: deltaY)", - "NSPoint(x: 10, y: 10)", - "NSPoint(x: xValue, y: yValue)", - "NSSize(width: 10, height: 10)", - "NSSize(width: aWidth, height: aHeight)", - "NSRect(x: 0, y: 0, width: 10, height: 10)", - "NSRect(x: xVal, y: yVal, width: aWidth, height: aHeight)", - "NSRange(location: 10, length: 1)", - "NSRange(location: loc, length: len)", - "UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)", - "UIEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)", - "NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)", - "NSEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)", - "UIOffset(horizontal: 0, vertical: 10)", - "UIOffset(horizontal: horizontal, vertical: vertical)" + Example("CGPoint(x: 10, y: 10)"), + Example("CGPoint(x: xValue, y: yValue)"), + Example("CGSize(width: 10, height: 10)"), + Example("CGSize(width: aWidth, height: aHeight)"), + Example("CGRect(x: 0, y: 0, width: 10, height: 10)"), + Example("CGRect(x: xVal, y: yVal, width: aWidth, height: aHeight)"), + Example("CGVector(dx: 10, dy: 10)"), + Example("CGVector(dx: deltaX, dy: deltaY)"), + Example("NSPoint(x: 10, y: 10)"), + Example("NSPoint(x: xValue, y: yValue)"), + Example("NSSize(width: 10, height: 10)"), + Example("NSSize(width: aWidth, height: aHeight)"), + Example("NSRect(x: 0, y: 0, width: 10, height: 10)"), + Example("NSRect(x: xVal, y: yVal, width: aWidth, height: aHeight)"), + Example("NSRange(location: 10, length: 1)"), + Example("NSRange(location: loc, length: len)"), + Example("UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)"), + Example("UIEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)"), + Example("NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)"), + Example("NSEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)"), + Example("UIOffset(horizontal: 0, vertical: 10)"), + Example("UIOffset(horizontal: horizontal, vertical: vertical)") ], triggeringExamples: [ - "↓CGPointMake(10, 10)", - "↓CGPointMake(xVal, yVal)", - "↓CGPointMake(calculateX(), 10)\n", - "↓CGSizeMake(10, 10)", - "↓CGSizeMake(aWidth, aHeight)", - "↓CGRectMake(0, 0, 10, 10)", - "↓CGRectMake(xVal, yVal, width, height)", - "↓CGVectorMake(10, 10)", - "↓CGVectorMake(deltaX, deltaY)", - "↓NSMakePoint(10, 10)", - "↓NSMakePoint(xVal, yVal)", - "↓NSMakeSize(10, 10)", - "↓NSMakeSize(aWidth, aHeight)", - "↓NSMakeRect(0, 0, 10, 10)", - "↓NSMakeRect(xVal, yVal, width, height)", - "↓NSMakeRange(10, 1)", - "↓NSMakeRange(loc, len)", - "↓UIEdgeInsetsMake(0, 0, 10, 10)", - "↓UIEdgeInsetsMake(top, left, bottom, right)", - "↓NSEdgeInsetsMake(0, 0, 10, 10)", - "↓NSEdgeInsetsMake(top, left, bottom, right)", - "↓CGVectorMake(10, 10)\n↓NSMakeRange(10, 1)", - "↓UIOffsetMake(0, 10)", - "↓UIOffsetMake(horizontal, vertical)" + Example("↓CGPointMake(10, 10)"), + Example("↓CGPointMake(xVal, yVal)"), + Example("↓CGPointMake(calculateX(), 10)\n"), + Example("↓CGSizeMake(10, 10)"), + Example("↓CGSizeMake(aWidth, aHeight)"), + Example("↓CGRectMake(0, 0, 10, 10)"), + Example("↓CGRectMake(xVal, yVal, width, height)"), + Example("↓CGVectorMake(10, 10)"), + Example("↓CGVectorMake(deltaX, deltaY)"), + Example("↓NSMakePoint(10, 10)"), + Example("↓NSMakePoint(xVal, yVal)"), + Example("↓NSMakeSize(10, 10)"), + Example("↓NSMakeSize(aWidth, aHeight)"), + Example("↓NSMakeRect(0, 0, 10, 10)"), + Example("↓NSMakeRect(xVal, yVal, width, height)"), + Example("↓NSMakeRange(10, 1)"), + Example("↓NSMakeRange(loc, len)"), + Example("↓UIEdgeInsetsMake(0, 0, 10, 10)"), + Example("↓UIEdgeInsetsMake(top, left, bottom, right)"), + Example("↓NSEdgeInsetsMake(0, 0, 10, 10)"), + Example("↓NSEdgeInsetsMake(top, left, bottom, right)"), + Example("↓CGVectorMake(10, 10)\n↓NSMakeRange(10, 1)"), + Example("↓UIOffsetMake(0, 10)"), + Example("↓UIOffsetMake(horizontal, vertical)") ], corrections: [ - "↓CGPointMake(10, 10 )\n": "CGPoint(x: 10, y: 10)\n", - "↓CGPointMake(xPos, yPos )\n": "CGPoint(x: xPos, y: yPos)\n", - "↓CGSizeMake(10, 10)\n": "CGSize(width: 10, height: 10)\n", - "↓CGSizeMake( aWidth, aHeight )\n": "CGSize(width: aWidth, height: aHeight)\n", - "↓CGRectMake(0, 0, 10, 10)\n": "CGRect(x: 0, y: 0, width: 10, height: 10)\n", - "↓CGRectMake(xPos, yPos , width, height)\n": - "CGRect(x: xPos, y: yPos, width: width, height: height)\n", - "↓CGVectorMake(10, 10)\n": "CGVector(dx: 10, dy: 10)\n", - "↓CGVectorMake(deltaX, deltaY)\n": "CGVector(dx: deltaX, dy: deltaY)\n", - "↓NSMakePoint(10, 10 )\n": "NSPoint(x: 10, y: 10)\n", - "↓NSMakePoint(xPos, yPos )\n": "NSPoint(x: xPos, y: yPos)\n", - "↓NSMakeSize(10, 10)\n": "NSSize(width: 10, height: 10)\n", - "↓NSMakeSize( aWidth, aHeight )\n": "NSSize(width: aWidth, height: aHeight)\n", - "↓NSMakeRect(0, 0, 10, 10)\n": "NSRect(x: 0, y: 0, width: 10, height: 10)\n", - "↓NSMakeRect(xPos, yPos , width, height)\n": - "NSRect(x: xPos, y: yPos, width: width, height: height)\n", - "↓NSMakeRange(10, 1)\n": "NSRange(location: 10, length: 1)\n", - "↓NSMakeRange(loc, len)\n": "NSRange(location: loc, length: len)\n", - "↓CGVectorMake(10, 10)\n↓NSMakeRange(10, 1)\n": "CGVector(dx: 10, dy: 10)\n" + - "NSRange(location: 10, length: 1)\n", - "↓CGVectorMake(dx, dy)\n↓NSMakeRange(loc, len)\n": "CGVector(dx: dx, dy: dy)\n" + - "NSRange(location: loc, length: len)\n", - "↓UIEdgeInsetsMake(0, 0, 10, 10)\n": - "UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)\n", - "↓UIEdgeInsetsMake(top, left, bottom, right)\n": - "UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)\n", - "↓NSEdgeInsetsMake(0, 0, 10, 10)\n": - "NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)\n", - "↓NSEdgeInsetsMake(top, left, bottom, right)\n": - "NSEdgeInsets(top: top, left: left, bottom: bottom, right: right)\n", - "↓NSMakeRange(0, attributedString.length)\n": - "NSRange(location: 0, length: attributedString.length)\n", - "↓CGPointMake(calculateX(), 10)\n": "CGPoint(x: calculateX(), y: 10)\n", - "↓UIOffsetMake(0, 10)\n": "UIOffset(horizontal: 0, vertical: 10)\n", - "↓UIOffsetMake(horizontal, vertical)\n": - "UIOffset(horizontal: horizontal, vertical: vertical)\n" + Example("↓CGPointMake(10, 10 )\n"): Example("CGPoint(x: 10, y: 10)\n"), + Example("↓CGPointMake(xPos, yPos )\n"): Example("CGPoint(x: xPos, y: yPos)\n"), + Example("↓CGSizeMake(10, 10)\n"): Example("CGSize(width: 10, height: 10)\n"), + Example("↓CGSizeMake( aWidth, aHeight )\n"): Example("CGSize(width: aWidth, height: aHeight)\n"), + Example("↓CGRectMake(0, 0, 10, 10)\n"): Example("CGRect(x: 0, y: 0, width: 10, height: 10)\n"), + Example("↓CGRectMake(xPos, yPos , width, height)\n"): + Example("CGRect(x: xPos, y: yPos, width: width, height: height)\n"), + Example("↓CGVectorMake(10, 10)\n"): Example("CGVector(dx: 10, dy: 10)\n"), + Example("↓CGVectorMake(deltaX, deltaY)\n"): Example("CGVector(dx: deltaX, dy: deltaY)\n"), + Example("↓NSMakePoint(10, 10 )\n"): Example("NSPoint(x: 10, y: 10)\n"), + Example("↓NSMakePoint(xPos, yPos )\n"): Example("NSPoint(x: xPos, y: yPos)\n"), + Example("↓NSMakeSize(10, 10)\n"): Example("NSSize(width: 10, height: 10)\n"), + Example("↓NSMakeSize( aWidth, aHeight )\n"): Example("NSSize(width: aWidth, height: aHeight)\n"), + Example("↓NSMakeRect(0, 0, 10, 10)\n"): Example("NSRect(x: 0, y: 0, width: 10, height: 10)\n"), + Example("↓NSMakeRect(xPos, yPos , width, height)\n"): + Example("NSRect(x: xPos, y: yPos, width: width, height: height)\n"), + Example("↓NSMakeRange(10, 1)\n"): Example("NSRange(location: 10, length: 1)\n"), + Example("↓NSMakeRange(loc, len)\n"): Example("NSRange(location: loc, length: len)\n"), + Example("↓CGVectorMake(10, 10)\n↓NSMakeRange(10, 1)\n"): + Example("CGVector(dx: 10, dy: 10)\nNSRange(location: 10, length: 1)\n"), + Example("↓CGVectorMake(dx, dy)\n↓NSMakeRange(loc, len)\n"): + Example("CGVector(dx: dx, dy: dy)\nNSRange(location: loc, length: len)\n"), + Example("↓UIEdgeInsetsMake(0, 0, 10, 10)\n"): + Example("UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)\n"), + Example("↓UIEdgeInsetsMake(top, left, bottom, right)\n"): + Example("UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)\n"), + Example("↓NSEdgeInsetsMake(0, 0, 10, 10)\n"): + Example("NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)\n"), + Example("↓NSEdgeInsetsMake(top, left, bottom, right)\n"): + Example("NSEdgeInsets(top: top, left: left, bottom: bottom, right: right)\n"), + Example("↓NSMakeRange(0, attributedString.length)\n"): + Example("NSRange(location: 0, length: attributedString.length)\n"), + Example("↓CGPointMake(calculateX(), 10)\n"): Example("CGPoint(x: calculateX(), y: 10)\n"), + Example("↓UIOffsetMake(0, 10)\n"): Example("UIOffset(horizontal: 0, vertical: 10)\n"), + Example("↓UIOffsetMake(horizontal, vertical)\n"): + Example("UIOffset(horizontal: horizontal, vertical: vertical)\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyHashingRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyHashingRule.swift index 5d4ebf27bf..b41826aff2 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyHashingRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyHashingRule.swift @@ -12,7 +12,7 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe kind: .idiomatic, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - """ + Example(""" struct Foo: Hashable { let bar: Int = 10 @@ -20,8 +20,8 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe hasher.combine(bar) } } - """, - """ + """), + Example(""" class Foo: Hashable { let bar: Int = 10 @@ -29,12 +29,12 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe hasher.combine(bar) } } - """, - """ + """), + Example(""" var hashValue: Int { return 1 } class Foo: Hashable { \n } - """, - """ + """), + Example(""" class Foo: Hashable { let bar: String = "Foo" @@ -42,8 +42,8 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe return bar } } - """, - """ + """), + Example(""" class Foo: Hashable { let bar: String = "Foo" @@ -52,10 +52,10 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe set { bar = newValue } } } - """ + """) ], triggeringExamples: [ - """ + Example(""" struct Foo: Hashable { let bar: Int = 10 @@ -63,8 +63,8 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe return bar } } - """, - """ + """), + Example(""" class Foo: Hashable { let bar: Int = 10 @@ -72,7 +72,7 @@ public struct LegacyHashingRule: ASTRule, ConfigurationProviderRule, AutomaticTe return bar } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyMultipleRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyMultipleRule.swift index 274c48dc67..368bf42869 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyMultipleRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyMultipleRule.swift @@ -12,30 +12,30 @@ public struct LegacyMultipleRule: OptInRule, ConfigurationProviderRule, Automati kind: .idiomatic, minSwiftVersion: .five, nonTriggeringExamples: [ - "cell.contentView.backgroundColor = indexPath.row.isMultiple(of: 2) ? .gray : .white", - "guard count.isMultiple(of: 2) else { throw DecodingError.dataCorrupted(...) }", - "sanityCheck(bytes > 0 && bytes.isMultiple(of: 4), \"capacity must be multiple of 4 bytes\")", - "guard let i = reversedNumbers.firstIndex(where: { $0.isMultiple(of: 2) }) else { return }", - """ + Example("cell.contentView.backgroundColor = indexPath.row.isMultiple(of: 2) ? .gray : .white"), + Example("guard count.isMultiple(of: 2) else { throw DecodingError.dataCorrupted(...) }"), + Example("sanityCheck(bytes > 0 && bytes.isMultiple(of: 4), \"capacity must be multiple of 4 bytes\")"), + Example("guard let i = reversedNumbers.firstIndex(where: { $0.isMultiple(of: 2) }) else { return }"), + Example(""" let constant = 56 let isMultiple = value.isMultiple(of: constant) - """, - """ + """), + Example(""" let constant = 56 let secret = value % constant == 5 - """, - "let secretValue = (value % 3) + 2" + """), + Example("let secretValue = (value % 3) + 2") ], triggeringExamples: [ - "cell.contentView.backgroundColor = indexPath.row ↓% 2 == 0 ? .gray : .white", - "cell.contentView.backgroundColor = indexPath.row ↓% 2 != 0 ? .gray : .white", - "guard count ↓% 2 == 0 else { throw DecodingError.dataCorrupted(...) }", - "sanityCheck(bytes > 0 && bytes ↓% 4 == 0, \"capacity must be multiple of 4 bytes\")", - "guard let i = reversedNumbers.firstIndex(where: { $0 ↓% 2 == 0 }) else { return }", - """ + Example("cell.contentView.backgroundColor = indexPath.row ↓% 2 == 0 ? .gray : .white"), + Example("cell.contentView.backgroundColor = indexPath.row ↓% 2 != 0 ? .gray : .white"), + Example("guard count ↓% 2 == 0 else { throw DecodingError.dataCorrupted(...) }"), + Example("sanityCheck(bytes > 0 && bytes ↓% 4 == 0, \"capacity must be multiple of 4 bytes\")"), + Example("guard let i = reversedNumbers.firstIndex(where: { $0 ↓% 2 == 0 }) else { return }"), + Example(""" let constant = 56 let isMultiple = value ↓% constant == 0 - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyNSGeometryFunctionsRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyNSGeometryFunctionsRule.swift index adfd80d00f..8eb84c3b3a 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyNSGeometryFunctionsRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyNSGeometryFunctionsRule.swift @@ -12,72 +12,72 @@ public struct LegacyNSGeometryFunctionsRule: CorrectableRule, ConfigurationProvi description: "Struct extension properties and methods are preferred over legacy functions", kind: .idiomatic, nonTriggeringExamples: [ - "rect.width", - "rect.height", - "rect.minX", - "rect.midX", - "rect.maxX", - "rect.minY", - "rect.midY", - "rect.maxY", - "rect.isEmpty", - "rect.integral", - "rect.insetBy(dx: 5.0, dy: -7.0)", - "rect.offsetBy(dx: 5.0, dy: -7.0)", - "rect1.union(rect2)", - "rect1.intersect(rect2)", + Example("rect.width"), + Example("rect.height"), + Example("rect.minX"), + Example("rect.midX"), + Example("rect.maxX"), + Example("rect.minY"), + Example("rect.midY"), + Example("rect.maxY"), + Example("rect.isEmpty"), + Example("rect.integral"), + Example("rect.insetBy(dx: 5.0, dy: -7.0)"), + Example("rect.offsetBy(dx: 5.0, dy: -7.0)"), + Example("rect1.union(rect2)"), + Example("rect1.intersect(rect2)"), // "rect.divide(atDistance: 10.2, fromEdge: edge)", No correction available for divide - "rect1.contains(rect2)", - "rect.contains(point)", - "rect1.intersects(rect2)" + Example("rect1.contains(rect2)"), + Example("rect.contains(point)"), + Example("rect1.intersects(rect2)") ], triggeringExamples: [ - "↓NSWidth(rect)", - "↓NSHeight(rect)", - "↓NSMinX(rect)", - "↓NSMidX(rect)", - "↓NSMaxX(rect)", - "↓NSMinY(rect)", - "↓NSMidY(rect)", - "↓NSMaxY(rect)", - "↓NSEqualRects(rect1, rect2)", - "↓NSEqualSizes(size1, size2)", - "↓NSEqualPoints(point1, point2)", - "↓NSEdgeInsetsEqual(insets2, insets2)", - "↓NSIsEmptyRect(rect)", - "↓NSIntegralRect(rect)", - "↓NSInsetRect(rect, 10, 5)", - "↓NSOffsetRect(rect, -2, 8.3)", - "↓NSUnionRect(rect1, rect2)", - "↓NSIntersectionRect(rect1, rect2)", - "↓NSContainsRect(rect1, rect2)", - "↓NSPointInRect(rect, point)", - "↓NSIntersectsRect(rect1, rect2)" + Example("↓NSWidth(rect)"), + Example("↓NSHeight(rect)"), + Example("↓NSMinX(rect)"), + Example("↓NSMidX(rect)"), + Example("↓NSMaxX(rect)"), + Example("↓NSMinY(rect)"), + Example("↓NSMidY(rect)"), + Example("↓NSMaxY(rect)"), + Example("↓NSEqualRects(rect1, rect2)"), + Example("↓NSEqualSizes(size1, size2)"), + Example("↓NSEqualPoints(point1, point2)"), + Example("↓NSEdgeInsetsEqual(insets2, insets2)"), + Example("↓NSIsEmptyRect(rect)"), + Example("↓NSIntegralRect(rect)"), + Example("↓NSInsetRect(rect, 10, 5)"), + Example("↓NSOffsetRect(rect, -2, 8.3)"), + Example("↓NSUnionRect(rect1, rect2)"), + Example("↓NSIntersectionRect(rect1, rect2)"), + Example("↓NSContainsRect(rect1, rect2)"), + Example("↓NSPointInRect(rect, point)"), + Example("↓NSIntersectsRect(rect1, rect2)") ], corrections: [ - "↓NSWidth( rect )\n": "rect.width\n", - "↓NSHeight(rect )\n": "rect.height\n", - "↓NSMinX( rect)\n": "rect.minX\n", - "↓NSMidX( rect)\n": "rect.midX\n", - "↓NSMaxX( rect)\n": "rect.maxX\n", - "↓NSMinY(rect )\n": "rect.minY\n", - "↓NSMidY(rect )\n": "rect.midY\n", - "↓NSMaxY( rect )\n": "rect.maxY\n", - "↓NSEqualPoints( point1 , point2)\n": "point1 == point2\n", - "↓NSEqualSizes(size1,size2 )\n": "size1 == size2\n", - "↓NSEqualRects( rect1, rect2)\n": "rect1 == rect2\n", - "↓NSEdgeInsetsEqual(insets1, insets2)\n": "insets1 == insets2\n", - "↓NSIsEmptyRect( rect )\n": "rect.isEmpty\n", - "↓NSIntegralRect(rect )\n": "rect.integral\n", - "↓NSInsetRect(rect, 5.0, -7.0)\n": "rect.insetBy(dx: 5.0, dy: -7.0)\n", - "↓NSOffsetRect(rect, -2, 8.3)\n": "rect.offsetBy(dx: -2, dy: 8.3)\n", - "↓NSUnionRect(rect1, rect2)\n": "rect1.union(rect2)\n", - "↓NSIntersectionRect( rect1 ,rect2)\n": "rect1.intersect(rect2)\n", - "↓NSContainsRect( rect1,rect2 )\n": "rect1.contains(rect2)\n", - "↓NSPointInRect(point ,rect)\n": "rect.contains(point)\n", // note order of arguments - "↓NSIntersectsRect( rect1,rect2 )\n": "rect1.intersects(rect2)\n", - "↓NSIntersectsRect(rect1, rect2 )\n↓NSWidth(rect )\n": - "rect1.intersects(rect2)\nrect.width\n" + Example("↓NSWidth( rect )\n"): Example("rect.width\n"), + Example("↓NSHeight(rect )\n"): Example("rect.height\n"), + Example("↓NSMinX( rect)\n"): Example("rect.minX\n"), + Example("↓NSMidX( rect)\n"): Example("rect.midX\n"), + Example("↓NSMaxX( rect)\n"): Example("rect.maxX\n"), + Example("↓NSMinY(rect )\n"): Example("rect.minY\n"), + Example("↓NSMidY(rect )\n"): Example("rect.midY\n"), + Example("↓NSMaxY( rect )\n"): Example("rect.maxY\n"), + Example("↓NSEqualPoints( point1 , point2)\n"): Example("point1 == point2\n"), + Example("↓NSEqualSizes(size1,size2 )\n"): Example("size1 == size2\n"), + Example("↓NSEqualRects( rect1, rect2)\n"): Example("rect1 == rect2\n"), + Example("↓NSEdgeInsetsEqual(insets1, insets2)\n"): Example("insets1 == insets2\n"), + Example("↓NSIsEmptyRect( rect )\n"): Example("rect.isEmpty\n"), + Example("↓NSIntegralRect(rect )\n"): Example("rect.integral\n"), + Example("↓NSInsetRect(rect, 5.0, -7.0)\n"): Example("rect.insetBy(dx: 5.0, dy: -7.0)\n"), + Example("↓NSOffsetRect(rect, -2, 8.3)\n"): Example("rect.offsetBy(dx: -2, dy: 8.3)\n"), + Example("↓NSUnionRect(rect1, rect2)\n"): Example("rect1.union(rect2)\n"), + Example("↓NSIntersectionRect( rect1 ,rect2)\n"): Example("rect1.intersect(rect2)\n"), + Example("↓NSContainsRect( rect1,rect2 )\n"): Example("rect1.contains(rect2)\n"), + Example("↓NSPointInRect(point ,rect)\n"): Example("rect.contains(point)\n"), // note order of arguments + Example("↓NSIntersectsRect( rect1,rect2 )\n"): Example("rect1.intersects(rect2)\n"), + Example("↓NSIntersectsRect(rect1, rect2 )\n↓NSWidth(rect )\n"): + Example("rect1.intersects(rect2)\nrect.width\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyRandomRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyRandomRule.swift index 205d43abbe..4e42c3626d 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyRandomRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyRandomRule.swift @@ -10,14 +10,14 @@ public struct LegacyRandomRule: ASTRule, OptInRule, ConfigurationProviderRule, A kind: .idiomatic, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - "Int.random(in: 0..<10)\n", - "Double.random(in: 8.6...111.34)\n", - "Float.random(in: 0 ..< 1)\n" + Example("Int.random(in: 0..<10)\n"), + Example("Double.random(in: 8.6...111.34)\n"), + Example("Float.random(in: 0 ..< 1)\n") ], triggeringExamples: [ - "↓arc4random(10)\n", - "↓arc4random_uniform(83)\n", - "↓drand48(52)\n" + Example("↓arc4random(10)\n"), + Example("↓arc4random_uniform(83)\n"), + Example("↓drand48(52)\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/NimbleOperatorRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/NimbleOperatorRule.swift index 73fd23d3e3..a64131a6e5 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/NimbleOperatorRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/NimbleOperatorRule.swift @@ -12,55 +12,55 @@ public struct NimbleOperatorRule: ConfigurationProviderRule, OptInRule, Correcta description: "Prefer Nimble operator overloads over free matcher functions.", kind: .idiomatic, nonTriggeringExamples: [ - "expect(seagull.squawk) != \"Hi!\"\n", - "expect(\"Hi!\") == \"Hi!\"\n", - "expect(10) > 2\n", - "expect(10) >= 10\n", - "expect(10) < 11\n", - "expect(10) <= 10\n", - "expect(x) === x", - "expect(10) == 10", - "expect(success) == true", - "expect(object.asyncFunction()).toEventually(equal(1))\n", - "expect(actual).to(haveCount(expected))\n", - """ + Example("expect(seagull.squawk) != \"Hi!\"\n"), + Example("expect(\"Hi!\") == \"Hi!\"\n"), + Example("expect(10) > 2\n"), + Example("expect(10) >= 10\n"), + Example("expect(10) < 11\n"), + Example("expect(10) <= 10\n"), + Example("expect(x) === x"), + Example("expect(10) == 10"), + Example("expect(success) == true"), + Example("expect(object.asyncFunction()).toEventually(equal(1))\n"), + Example("expect(actual).to(haveCount(expected))\n"), + Example(""" 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", - "↓expect(10).to(beLessThanOrEqualTo(10))\n", - "↓expect(x).to(beIdenticalTo(x))\n", - "↓expect(success).to(beTrue())\n", - "↓expect(success).to(beFalse())\n", - "expect(10) > 2\n ↓expect(10).to(beGreaterThan(2))\n" + Example("↓expect(seagull.squawk).toNot(equal(\"Hi\"))\n"), + Example("↓expect(12).toNot(equal(10))\n"), + Example("↓expect(10).to(equal(10))\n"), + Example("↓expect(10, line: 1).to(equal(10))\n"), + Example("↓expect(10).to(beGreaterThan(8))\n"), + Example("↓expect(10).to(beGreaterThanOrEqualTo(10))\n"), + Example("↓expect(10).to(beLessThan(11))\n"), + Example("↓expect(10).to(beLessThanOrEqualTo(10))\n"), + Example("↓expect(x).to(beIdenticalTo(x))\n"), + Example("↓expect(success).to(beTrue())\n"), + Example("↓expect(success).to(beFalse())\n"), + Example("expect(10) > 2\n ↓expect(10).to(beGreaterThan(2))\n") ], corrections: [ - "↓expect(seagull.squawk).toNot(equal(\"Hi\"))\n": "expect(seagull.squawk) != \"Hi\"\n", - "↓expect(\"Hi!\").to(equal(\"Hi!\"))\n": "expect(\"Hi!\") == \"Hi!\"\n", - "↓expect(12).toNot(equal(10))\n": "expect(12) != 10\n", - "↓expect(value1).to(equal(value2))\n": "expect(value1) == value2\n", - "↓expect( value1 ).to(equal( value2.foo))\n": "expect(value1) == value2.foo\n", - "↓expect(value1).to(equal(10))\n": "expect(value1) == 10\n", - "↓expect(10).to(beGreaterThan(8))\n": "expect(10) > 8\n", - "↓expect(10).to(beGreaterThanOrEqualTo(10))\n": "expect(10) >= 10\n", - "↓expect(10).to(beLessThan(11))\n": "expect(10) < 11\n", - "↓expect(10).to(beLessThanOrEqualTo(10))\n": "expect(10) <= 10\n", - "↓expect(x).to(beIdenticalTo(x))\n": "expect(x) === x\n", - "↓expect(success).to(beTrue())\n": "expect(success) == true\n", - "↓expect(success).to(beFalse())\n": "expect(success) == false\n", - "↓expect(success).toNot(beFalse())\n": "expect(success) != false\n", - "↓expect(success).toNot(beTrue())\n": "expect(success) != true\n", - "expect(10) > 2\n ↓expect(10).to(beGreaterThan(2))\n": "expect(10) > 2\n expect(10) > 2\n" + Example("↓expect(seagull.squawk).toNot(equal(\"Hi\"))\n"): Example("expect(seagull.squawk) != \"Hi\"\n"), + Example("↓expect(\"Hi!\").to(equal(\"Hi!\"))\n"): Example("expect(\"Hi!\") == \"Hi!\"\n"), + Example("↓expect(12).toNot(equal(10))\n"): Example("expect(12) != 10\n"), + Example("↓expect(value1).to(equal(value2))\n"): Example("expect(value1) == value2\n"), + Example("↓expect( value1 ).to(equal( value2.foo))\n"): Example("expect(value1) == value2.foo\n"), + Example("↓expect(value1).to(equal(10))\n"): Example("expect(value1) == 10\n"), + Example("↓expect(10).to(beGreaterThan(8))\n"): Example("expect(10) > 8\n"), + Example("↓expect(10).to(beGreaterThanOrEqualTo(10))\n"): Example("expect(10) >= 10\n"), + Example("↓expect(10).to(beLessThan(11))\n"): Example("expect(10) < 11\n"), + Example("↓expect(10).to(beLessThanOrEqualTo(10))\n"): Example("expect(10) <= 10\n"), + Example("↓expect(x).to(beIdenticalTo(x))\n"): Example("expect(x) === x\n"), + Example("↓expect(success).to(beTrue())\n"): Example("expect(success) == true\n"), + Example("↓expect(success).to(beFalse())\n"): Example("expect(success) == false\n"), + Example("↓expect(success).toNot(beFalse())\n"): Example("expect(success) != false\n"), + Example("↓expect(success).toNot(beTrue())\n"): Example("expect(success) != true\n"), + Example("expect(10) > 2\n ↓expect(10).to(beGreaterThan(2))\n"): Example("expect(10) > 2\n expect(10) > 2\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/NoExtensionAccessModifierRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/NoExtensionAccessModifierRule.swift index bfcbb77f28..1919dff209 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/NoExtensionAccessModifierRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/NoExtensionAccessModifierRule.swift @@ -11,15 +11,15 @@ public struct NoExtensionAccessModifierRule: ASTRule, OptInRule, ConfigurationPr description: "Prefer not to use extension access modifiers", kind: .idiomatic, nonTriggeringExamples: [ - "extension String {}", - "\n\n extension String {}" + Example("extension String {}"), + Example("\n\n extension String {}") ], triggeringExamples: [ - "↓private extension String {}", - "↓public \n extension String {}", - "↓open extension String {}", - "↓internal extension String {}", - "↓fileprivate extension String {}" + Example("↓private extension String {}"), + Example("↓public \n extension String {}"), + Example("↓open extension String {}"), + Example("↓internal extension String {}"), + Example("↓fileprivate extension String {}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/NoFallthroughOnlyRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/NoFallthroughOnlyRuleExamples.swift index af2ca2cce1..117e4d3628 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/NoFallthroughOnlyRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/NoFallthroughOnlyRuleExamples.swift @@ -1,7 +1,7 @@ internal struct NoFallthroughOnlyRuleExamples { - static let nonTriggeringExamples: [String] = { + static let nonTriggeringExamples: [Example] = { let commonExamples = [ - """ + Example(""" switch myvar { case 1: var a = 1 @@ -9,8 +9,8 @@ internal struct NoFallthroughOnlyRuleExamples { case 2: var a = 2 } - """, - """ + """), + Example(""" switch myvar { case "a": var one = 1 @@ -19,8 +19,8 @@ internal struct NoFallthroughOnlyRuleExamples { case "b": /* comment */ var three = 3 } - """, - """ + """), + Example(""" switch myvar { case 1: let one = 1 @@ -28,8 +28,8 @@ internal struct NoFallthroughOnlyRuleExamples { // comment var two = 2 } - """, - """ + """), + Example(""" switch myvar { case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2): var three = 3 @@ -37,8 +37,8 @@ internal struct NoFallthroughOnlyRuleExamples { default: var three = 4 } - """, - """ + """), + Example(""" switch myvar { case .alpha: var one = 1 @@ -48,8 +48,8 @@ internal struct NoFallthroughOnlyRuleExamples { default: var four = 4 } - """, - """ + """), + Example(""" let aPoint = (1, -1) switch aPoint { case let (x, y) where x == y: @@ -60,8 +60,8 @@ internal struct NoFallthroughOnlyRuleExamples { default: let C = "C" } - """, - """ + """), + Example(""" switch myvar { case MyFun(with: { $1 }): let one = 1 @@ -69,7 +69,7 @@ internal struct NoFallthroughOnlyRuleExamples { case "abc": let two = 2 } - """ + """) ] guard SwiftVersion.current >= .five else { @@ -77,7 +77,7 @@ internal struct NoFallthroughOnlyRuleExamples { } return commonExamples + [ - """ + Example(""" switch enumInstance { case .caseA: print("it's a") @@ -86,20 +86,20 @@ internal struct NoFallthroughOnlyRuleExamples { @unknown default: print("it's not a") } - """ + """) ] }() static let triggeringExamples = [ - """ + Example(""" switch myvar { case 1: ↓fallthrough case 2: var a = 1 } - """, - """ + """), + Example(""" switch myvar { case 1: var a = 2 @@ -108,14 +108,14 @@ internal struct NoFallthroughOnlyRuleExamples { case 3: var a = 3 } - """, - """ + """), + Example(""" switch myvar { case 1: // comment ↓fallthrough } - """, - """ + """), + Example(""" switch myvar { case 1: /* multi line @@ -124,16 +124,16 @@ internal struct NoFallthroughOnlyRuleExamples { case 2: var a = 2 } - """, - """ + """), + Example(""" switch myvar { case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2): ↓fallthrough default: var three = 4 } - """, - """ + """), + Example(""" switch myvar { case .alpha: var one = 1 @@ -144,8 +144,8 @@ internal struct NoFallthroughOnlyRuleExamples { default: var four = 4 } - """, - """ + """), + Example(""" let aPoint = (1, -1) switch aPoint { case let (x, y) where x == y: @@ -155,14 +155,14 @@ internal struct NoFallthroughOnlyRuleExamples { default: let B = "B" } - """, - """ + """), + Example(""" switch myvar { case MyFun(with: { $1 }): ↓fallthrough case "abc": let two = 2 } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/NoGroupingExtensionRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/NoGroupingExtensionRule.swift index 123542689a..3e4a3b03f3 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/NoGroupingExtensionRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/NoGroupingExtensionRule.swift @@ -11,15 +11,15 @@ public struct NoGroupingExtensionRule: OptInRule, ConfigurationProviderRule, Aut description: "Extensions shouldn't be used to group code within the same source file.", kind: .idiomatic, nonTriggeringExamples: [ - "protocol Food {}\nextension Food {}\n", - "class Apples {}\nextension Oranges {}\n", - "class Box {}\nextension Box where T: Vegetable {}\n" + Example("protocol Food {}\nextension Food {}\n"), + Example("class Apples {}\nextension Oranges {}\n"), + Example("class Box {}\nextension Box where T: Vegetable {}\n") ], triggeringExamples: [ - "enum Fruit {}\n↓extension Fruit {}\n", - "↓extension Tea: Error {}\nstruct Tea {}\n", - "class Ham { class Spam {}}\n↓extension Ham.Spam {}\n", - "extension External { struct Gotcha {}}\n↓extension External.Gotcha {}\n" + Example("enum Fruit {}\n↓extension Fruit {}\n"), + Example("↓extension Tea: Error {}\nstruct Tea {}\n"), + Example("class Ham { class Spam {}}\n↓extension Ham.Spam {}\n"), + Example("extension External { struct Gotcha {}}\n↓extension External.Gotcha {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ObjectLiteralRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ObjectLiteralRule.swift index 8680e3ce91..88f4264dd6 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ObjectLiteralRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ObjectLiteralRule.swift @@ -11,22 +11,23 @@ public struct ObjectLiteralRule: ASTRule, ConfigurationProviderRule, OptInRule { description: "Prefer object literals over image and color inits.", kind: .idiomatic, nonTriggeringExamples: [ - "let image = #imageLiteral(resourceName: \"image.jpg\")", - "let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", - "let image = UIImage(named: aVariable)", - "let image = UIImage(named: \"interpolated \\(variable)\")", - "let color = UIColor(red: value, green: value, blue: value, alpha: 1)", - "let image = NSImage(named: aVariable)", - "let image = NSImage(named: \"interpolated \\(variable)\")", - "let color = NSColor(red: value, green: value, blue: value, alpha: 1)" + Example("let image = #imageLiteral(resourceName: \"image.jpg\")"), + Example("let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)"), + Example("let image = UIImage(named: aVariable)"), + Example("let image = UIImage(named: \"interpolated \\(variable)\")"), + Example("let color = UIColor(red: value, green: value, blue: value, alpha: 1)"), + Example("let image = NSImage(named: aVariable)"), + Example("let image = NSImage(named: \"interpolated \\(variable)\")"), + Example("let color = NSColor(red: value, green: value, blue: value, alpha: 1)") ], - triggeringExamples: ["", ".init"].flatMap { (method: String) -> [String] in - ["UI", "NS"].flatMap { (prefix: String) -> [String] in + triggeringExamples: ["", ".init"].flatMap { (method: String) -> [Example] in + ["UI", "NS"].flatMap { (prefix: String) -> [Example] in [ - "let image = ↓\(prefix)Image\(method)(named: \"foo\")", - "let color = ↓\(prefix)Color\(method)(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)", - "let color = ↓\(prefix)Color\(method)(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)", - "let color = ↓\(prefix)Color\(method)(white: 0.5, alpha: 1)" + Example("let image = ↓\(prefix)Image\(method)(named: \"foo\")"), + Example("let color = ↓\(prefix)Color\(method)(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)"), + // swiftlint:disable:next line_length + Example("let color = ↓\(prefix)Color\(method)(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)"), + Example("let color = ↓\(prefix)Color\(method)(white: 0.5, alpha: 1)") ] } } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/PatternMatchingKeywordsRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/PatternMatchingKeywordsRule.swift index d2d016815e..da25faf729 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/PatternMatchingKeywordsRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/PatternMatchingKeywordsRule.swift @@ -12,25 +12,25 @@ public struct PatternMatchingKeywordsRule: ASTRule, ConfigurationProviderRule, O description: "Combine multiple pattern matching bindings by moving keywords out of tuples.", kind: .idiomatic, nonTriggeringExamples: [ - "default", - "case 1", - "case bar", - "case let (x, y)", - "case .foo(let x)", - "case let .foo(x, y)", - "case .foo(let x), .bar(let x)", - "case .foo(let x, var y)", - "case var (x, y)", - "case .foo(var x)", - "case var .foo(x, y)" + Example("default"), + Example("case 1"), + Example("case bar"), + Example("case let (x, y)"), + Example("case .foo(let x)"), + Example("case let .foo(x, y)"), + Example("case .foo(let x), .bar(let x)"), + Example("case .foo(let x, var y)"), + Example("case var (x, y)"), + Example("case .foo(var x)"), + Example("case var .foo(x, y)") ].map(wrapInSwitch), triggeringExamples: [ - "case (↓let x, ↓let y)", - "case .foo(↓let x, ↓let y)", - "case (.yamlParsing(↓let x), .yamlParsing(↓let y))", - "case (↓var x, ↓var y)", - "case .foo(↓var x, ↓var y)", - "case (.yamlParsing(↓var x), .yamlParsing(↓var y))" + Example("case (↓let x, ↓let y)"), + Example("case .foo(↓let x, ↓let y)"), + Example("case (.yamlParsing(↓let x), .yamlParsing(↓let y))"), + Example("case (↓var x, ↓var y)"), + Example("case .foo(↓var x, ↓var y)"), + Example("case (.yamlParsing(↓var x), .yamlParsing(↓var y))") ].map(wrapInSwitch) ) @@ -69,8 +69,10 @@ public struct PatternMatchingKeywordsRule: ASTRule, ConfigurationProviderRule, O } } -private func wrapInSwitch(_ str: String) -> String { - return "switch foo {\n" + - " \(str): break\n" + - "}" +private func wrapInSwitch(_ example: Example) -> Example { + return example.with(code: """ + switch foo { + \(example.code): break + } + """) } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/PrivateOverFilePrivateRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/PrivateOverFilePrivateRule.swift index 04b7d45cff..db6169c863 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/PrivateOverFilePrivateRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/PrivateOverFilePrivateRule.swift @@ -12,46 +12,46 @@ public struct PrivateOverFilePrivateRule: ConfigurationProviderRule, Substitutio description: "Prefer `private` over `fileprivate` declarations.", kind: .idiomatic, nonTriggeringExamples: [ - "extension String {}", - "private extension String {}", - "public \n enum MyEnum {}", - "open extension \n String {}", - "internal extension String {}", - """ + Example("extension String {}"), + Example("private extension String {}"), + Example("public \n enum MyEnum {}"), + Example("open extension \n String {}"), + Example("internal extension String {}"), + Example(""" extension String { fileprivate func Something(){} } - """, - """ + """), + Example(""" class MyClass { fileprivate let myInt = 4 } - """, - """ + """), + Example(""" class MyClass { fileprivate(set) var myInt = 4 } - """, - """ + """), + Example(""" struct Outter { struct Inter { fileprivate struct Inner {} } } - """ + """) ], triggeringExamples: [ - "↓fileprivate enum MyEnum {}", - """ + Example("↓fileprivate enum MyEnum {}"), + Example(""" ↓fileprivate class MyClass { fileprivate(set) var myInt = 4 } - """ + """) ], corrections: [ - "↓fileprivate enum MyEnum {}": "private enum MyEnum {}", - "↓fileprivate class MyClass {\nfileprivate(set) var myInt = 4\n}": - "private class MyClass {\nfileprivate(set) var myInt = 4\n}" + Example("↓fileprivate enum MyEnum {}"): Example("private enum MyEnum {}"), + Example("↓fileprivate class MyClass {\nfileprivate(set) var myInt = 4\n}"): + Example("private class MyClass {\nfileprivate(set) var myInt = 4\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantNilCoalescingRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantNilCoalescingRule.swift index 22e8585a21..71b4fd35c2 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantNilCoalescingRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantNilCoalescingRule.swift @@ -14,15 +14,17 @@ public struct RedundantNilCoalescingRule: OptInRule, SubstitutionCorrectableRule ", coalescing operator with nil as rhs is redundant", kind: .idiomatic, nonTriggeringExamples: [ - "var myVar: Int?; myVar ?? 0\n" + Example("var myVar: Int?; myVar ?? 0\n") ], triggeringExamples: [ - "var myVar: Int? = nil; myVar↓ ?? nil\n", - "var myVar: Int? = nil; myVar↓??nil\n" + Example("var myVar: Int? = nil; myVar↓ ?? nil\n"), + Example("var myVar: Int? = nil; myVar↓??nil\n") ], corrections: [ - "var myVar: Int? = nil; let foo = myVar↓ ?? nil\n": "var myVar: Int? = nil; let foo = myVar\n", - "var myVar: Int? = nil; let foo = myVar↓??nil\n": "var myVar: Int? = nil; let foo = myVar\n" + Example("var myVar: Int? = nil; let foo = myVar↓ ?? nil\n"): + Example("var myVar: Int? = nil; let foo = myVar\n"), + Example("var myVar: Int? = nil; let foo = myVar↓??nil\n"): + Example("var myVar: Int? = nil; let foo = myVar\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantObjcAttributeRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantObjcAttributeRuleExamples.swift index f12f4d2680..db4a9d69d0 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantObjcAttributeRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantObjcAttributeRuleExamples.swift @@ -1,15 +1,15 @@ // swiftlint:disable:next type_body_length struct RedundantObjcAttributeRuleExamples { static let nonTriggeringExamples = [ - "@objc private var foo: String? {}", - "@IBInspectable private var foo: String? {}", - "@objc private func foo(_ sender: Any) {}", - "@IBAction private func foo(_ sender: Any) {}", - "@GKInspectable private var foo: String! {}", - "private @GKInspectable var foo: String! {}", - "@NSManaged var foo: String!", - "@objc @NSCopying var foo: String!", - """ + Example("@objc private var foo: String? {}"), + Example("@IBInspectable private var foo: String? {}"), + Example("@objc private func foo(_ sender: Any) {}"), + Example("@IBAction private func foo(_ sender: Any) {}"), + Example("@GKInspectable private var foo: String! {}"), + Example("private @GKInspectable var foo: String! {}"), + Example("@NSManaged var foo: String!"), + Example("@objc @NSCopying var foo: String!"), + Example(""" @objcMembers class Foo { var bar: Any? @@ -19,36 +19,36 @@ struct RedundantObjcAttributeRuleExamples { var foo: Any? } } - """, - """ + """), + Example(""" @objc extension Foo { var bar: Int { return 0 } } - """, - """ + """), + Example(""" extension Foo { @objc var bar: Int { return 0 } } - """, - """ + """), + Example(""" @objc @IBDesignable extension Foo { var bar: Int { return 0 } } - """, - """ + """), + Example(""" @IBDesignable extension Foo { @objc var bar: Int { return 0 } var fooBar: Int { return 1 } } - """, - """ + """), + Example(""" @objcMembers class Foo: NSObject { @objc @@ -56,40 +56,40 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """, - """ + """), + Example(""" @objcMembers class Foo { class Bar: NSObject { @objc var foo: Any } } - """, - """ + """), + Example(""" @objcMembers class Foo { @objc class Bar {} } - """ + """) ] static let triggeringExamples = [ - "↓@objc @IBInspectable private var foo: String? {}", - "@IBInspectable ↓@objc private var foo: String? {}", - "↓@objc @IBAction private func foo(_ sender: Any) {}", - "@IBAction ↓@objc private func foo(_ sender: Any) {}", - "↓@objc @GKInspectable private var foo: String! {}", - "@GKInspectable ↓@objc private var foo: String! {}", - "↓@objc @NSManaged private var foo: String!", - "@NSManaged ↓@objc private var foo: String!", - "↓@objc @IBDesignable class Foo {}", - """ + Example("↓@objc @IBInspectable private var foo: String? {}"), + Example("@IBInspectable ↓@objc private var foo: String? {}"), + Example("↓@objc @IBAction private func foo(_ sender: Any) {}"), + Example("@IBAction ↓@objc private func foo(_ sender: Any) {}"), + Example("↓@objc @GKInspectable private var foo: String! {}"), + Example("@GKInspectable ↓@objc private var foo: String! {}"), + Example("↓@objc @NSManaged private var foo: String!"), + Example("@NSManaged ↓@objc private var foo: String!"), + Example("↓@objc @IBDesignable class Foo {}"), + Example(""" @objcMembers class Foo { ↓@objc var bar: Any? } - """, - """ + """), + Example(""" @objcMembers class Foo { ↓@objc var bar: Any? @@ -100,8 +100,8 @@ struct RedundantObjcAttributeRuleExamples { var foo: Any? } } - """, - """ + """), + Example(""" @objc extension Foo { ↓@objc @@ -109,8 +109,8 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """, - """ + """), + Example(""" @objc @IBDesignable extension Foo { ↓@objc @@ -118,8 +118,8 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """, - """ + """), + Example(""" @objcMembers class Foo { @objcMembers @@ -127,8 +127,8 @@ struct RedundantObjcAttributeRuleExamples { ↓@objc var foo: Any } } - """, - """ + """), + Example(""" @objc extension Foo { ↓@objc @@ -136,31 +136,36 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """ + """) ] static let corrections = [ - "↓@objc @IBInspectable private var foo: String? {}": "@IBInspectable private var foo: String? {}", - "@IBInspectable ↓@objc private var foo: String? {}": "@IBInspectable private var foo: String? {}", - "@IBAction ↓@objc private func foo(_ sender: Any) {}": "@IBAction private func foo(_ sender: Any) {}", - "↓@objc @GKInspectable private var foo: String! {}": "@GKInspectable private var foo: String! {}", - "@GKInspectable ↓@objc private var foo: String! {}": "@GKInspectable private var foo: String! {}", - "↓@objc @NSManaged private var foo: String!": "@NSManaged private var foo: String!", - "@NSManaged ↓@objc private var foo: String!": "@NSManaged private var foo: String!", - "↓@objc @IBDesignable class Foo {}": "@IBDesignable class Foo {}", - """ + Example("↓@objc @IBInspectable private var foo: String? {}"): + Example("@IBInspectable private var foo: String? {}"), + Example("@IBInspectable ↓@objc private var foo: String? {}"): + Example("@IBInspectable private var foo: String? {}"), + Example("@IBAction ↓@objc private func foo(_ sender: Any) {}"): + Example("@IBAction private func foo(_ sender: Any) {}"), + Example("↓@objc @GKInspectable private var foo: String! {}"): + Example("@GKInspectable private var foo: String! {}"), + Example("@GKInspectable ↓@objc private var foo: String! {}"): + Example("@GKInspectable private var foo: String! {}"), + Example("↓@objc @NSManaged private var foo: String!"): Example("@NSManaged private var foo: String!"), + Example("@NSManaged ↓@objc private var foo: String!"): Example("@NSManaged private var foo: String!"), + Example("↓@objc @IBDesignable class Foo {}"): Example("@IBDesignable class Foo {}"), + Example(""" @objcMembers class Foo { ↓@objc var bar: Any? } - """: - """ + """): + Example(""" @objcMembers class Foo { var bar: Any? } - """, - """ + """), + Example(""" @objcMembers class Foo { ↓@objc var bar: Any? @@ -171,8 +176,8 @@ struct RedundantObjcAttributeRuleExamples { var foo2: Any? } } - """: - """ + """): + Example(""" @objcMembers class Foo { var bar: Any? @@ -183,8 +188,8 @@ struct RedundantObjcAttributeRuleExamples { var foo2: Any? } } - """, - """ + """), + Example(""" @objc extension Foo { ↓@objc @@ -192,16 +197,16 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """: - """ + """): + Example(""" @objc extension Foo { var bar: Int { return 0 } } - """, - """ + """), + Example(""" @objc @IBDesignable extension Foo { ↓@objc @@ -209,16 +214,16 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """: - """ + """): + Example(""" @objc @IBDesignable extension Foo { var bar: Int { return 0 } } - """, - """ + """), + Example(""" @objcMembers class Foo { @objcMembers @@ -226,8 +231,8 @@ struct RedundantObjcAttributeRuleExamples { ↓@objc var foo: Any } } - """: - """ + """): + Example(""" @objcMembers class Foo { @objcMembers @@ -235,8 +240,8 @@ struct RedundantObjcAttributeRuleExamples { var foo: Any } } - """, - """ + """), + Example(""" @objc extension Foo { ↓@objc @@ -244,16 +249,16 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """: - """ + """): + Example(""" @objc extension Foo { private var bar: Int { return 0 } } - """, - """ + """), + Example(""" @objc extension Foo { ↓@objc @@ -263,14 +268,14 @@ struct RedundantObjcAttributeRuleExamples { return 0 } } - """: - """ + """): + Example(""" @objc extension Foo { private var bar: Int { return 0 } } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantOptionalInitializationRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantOptionalInitializationRule.swift index a2cc6f0c70..de563e1391 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantOptionalInitializationRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantOptionalInitializationRule.swift @@ -13,52 +13,51 @@ public struct RedundantOptionalInitializationRule: SubstitutionCorrectableASTRul description: "Initializing an optional variable with nil is redundant.", kind: .idiomatic, nonTriggeringExamples: [ - "var myVar: Int?\n", - "let myVar: Int? = nil\n", - "var myVar: Int? = 0\n", - "func foo(bar: Int? = 0) { }\n", - "var myVar: Optional\n", - "let myVar: Optional = nil\n", - "var myVar: Optional = 0\n", + Example("var myVar: Int?\n"), + Example("let myVar: Int? = nil\n"), + Example("var myVar: Int? = 0\n"), + Example("func foo(bar: Int? = 0) { }\n"), + Example("var myVar: Optional\n"), + Example("let myVar: Optional = nil\n"), + Example("var myVar: Optional = 0\n"), // properties with body should be ignored - """ + Example(""" var foo: Int? { if bar != nil { } return 0 } - """ - , + """), // properties with a closure call - """ + Example(""" var foo: Int? = { if bar != nil { } return 0 }() - """, + """), // lazy variables need to be initialized - "lazy var test: Int? = nil", + Example("lazy var test: Int? = nil"), // local variables - """ + Example(""" func funcName() { var myVar: String? } - """, - """ + """), + Example(""" func funcName() { let myVar: String? = nil } - """ + """) ], triggeringExamples: triggeringExamples, corrections: corrections ) - private static let triggeringExamples: [String] = { + private static let triggeringExamples: [Example] = { let commonExamples = [ - "var myVar: Int?↓ = nil\n", - "var myVar: Optional↓ = nil\n", - "var myVar: Int?↓=nil\n", - "var myVar: Optional↓=nil\n" + Example("var myVar: Int?↓ = nil\n"), + Example("var myVar: Optional↓ = nil\n"), + Example("var myVar: Int?↓=nil\n"), + Example("var myVar: Optional↓=nil\n)") ] guard SwiftVersion.current >= .fourDotOne else { @@ -66,25 +65,37 @@ public struct RedundantOptionalInitializationRule: SubstitutionCorrectableASTRul } return commonExamples + [ - "func funcName() {\n var myVar: String?↓ = nil\n}" + Example(""" + func funcName() { + var myVar: String?↓ = nil + } + """) ] }() - private static let corrections: [String: String] = { + private static let corrections: [Example: Example] = { var corrections = [ - "var myVar: Int?↓ = nil\n": "var myVar: Int?\n", - "var myVar: Optional↓ = nil\n": "var myVar: Optional\n", - "var myVar: Int?↓=nil\n": "var myVar: Int?\n", - "var myVar: Optional↓=nil\n": "var myVar: Optional\n", - "class C {\n#if true\nvar myVar: Int?↓ = nil\n#endif\n}": - "class C {\n#if true\nvar myVar: Int?\n#endif\n}" + Example("var myVar: Int?↓ = nil\n"): Example("var myVar: Int?\n"), + Example("var myVar: Optional↓ = nil\n"): Example("var myVar: Optional\n"), + Example("var myVar: Int?↓=nil\n"): Example("var myVar: Int?\n"), + Example("var myVar: Optional↓=nil\n"): Example("var myVar: Optional\n"), + Example("class C {\n#if true\nvar myVar: Int?↓ = nil\n#endif\n}"): + Example("class C {\n#if true\nvar myVar: Int?\n#endif\n}") ] guard SwiftVersion.current >= .fourDotOne else { return corrections } - corrections["func foo() {\n var myVar: String?↓ = nil\n}"] = "func foo() {\n var myVar: String?\n}" + corrections[Example(""" + func foo() { + var myVar: String?↓ = nil + } + """)] = Example(""" + func foo() { + var myVar: String? + } + """) return corrections }() diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantSetAccessControlRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantSetAccessControlRule.swift index 8ea2937a6a..d39fc1ac26 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantSetAccessControlRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantSetAccessControlRule.swift @@ -13,36 +13,36 @@ public struct RedundantSetAccessControlRule: ConfigurationProviderRule, Automati kind: .idiomatic, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "private(set) public var foo: Int", - "public let foo: Int", - "public var foo: Int", - "var foo: Int", - """ + Example("private(set) public var foo: Int"), + Example("public let foo: Int"), + Example("public var foo: Int"), + Example("var foo: Int"), + Example(""" private final class A { private(set) var value: Int } - """ + """) ], triggeringExamples: [ - "↓private(set) private var foo: Int", - "↓fileprivate(set) fileprivate var foo: Int", - "↓internal(set) internal var foo: Int", - "↓public(set) public var foo: Int", - """ + Example("↓private(set) private var foo: Int"), + Example("↓fileprivate(set) fileprivate var foo: Int"), + Example("↓internal(set) internal var foo: Int"), + Example("↓public(set) public var foo: Int"), + Example(""" open class Foo { ↓open(set) open var bar: Int } - """, - """ + """), + Example(""" class A { ↓internal(set) var value: Int } - """, - """ + """), + Example(""" fileprivate class A { ↓fileprivate(set) var value: Int } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantStringEnumValueRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantStringEnumValueRule.swift index b66836e470..23a60b92ec 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantStringEnumValueRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantStringEnumValueRule.swift @@ -21,53 +21,53 @@ public struct RedundantStringEnumValueRule: ASTRule, ConfigurationProviderRule, description: "String enum values can be omitted when they are equal to the enumcase name.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" enum Numbers: String { case one case two } - """, - """ + """), + Example(""" enum Numbers: Int { case one = 1 case two = 2 } - """, - """ + """), + Example(""" enum Numbers: String { case one = "ONE" case two = "TWO" } - """, - """ + """), + Example(""" enum Numbers: String { case one = "ONE" case two = "two" } - """, - """ + """), + Example(""" enum Numbers: String { case one, two } - """ + """) ], triggeringExamples: [ - """ + Example(""" enum Numbers: String { case one = ↓"one" case two = ↓"two" } - """, - """ + """), + Example(""" enum Numbers: String { case one = ↓"one", two = ↓"two" } - """, - """ + """), + Example(""" enum Numbers: String { case one, two = ↓"two" } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantTypeAnnotationRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantTypeAnnotationRule.swift index d5d7f965ac..c7c626319d 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantTypeAnnotationRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantTypeAnnotationRule.swift @@ -13,44 +13,44 @@ public struct RedundantTypeAnnotationRule: OptInRule, SubstitutionCorrectableRul description: "Variables should not have redundant type annotation", kind: .idiomatic, nonTriggeringExamples: [ - "var url = URL()", - "var url: CustomStringConvertible = URL()", - "@IBInspectable var color: UIColor = UIColor.white" + Example("var url = URL()"), + Example("var url: CustomStringConvertible = URL()"), + Example("@IBInspectable var color: UIColor = UIColor.white") ], triggeringExamples: [ - "var url↓:URL=URL()", - "var url↓:URL = URL(string: \"\")", - "var url↓: URL = URL()", - "let url↓: URL = URL()", - "lazy var url↓: URL = URL()", - "let alphanumerics↓: CharacterSet = CharacterSet.alphanumerics", - """ + Example("var url↓:URL=URL()"), + Example("var url↓:URL = URL(string: \"\")"), + Example("var url↓: URL = URL()"), + Example("let url↓: URL = URL()"), + Example("lazy var url↓: URL = URL()"), + Example("let alphanumerics↓: CharacterSet = CharacterSet.alphanumerics"), + Example(""" class ViewController: UIViewController { func someMethod() { let myVar↓: Int = Int(5) } } - """ + """) ], corrections: [ - "var url↓: URL = URL()": "var url = URL()", - "let url↓: URL = URL()": "let url = URL()", - "let alphanumerics↓: CharacterSet = CharacterSet.alphanumerics": - "let alphanumerics = CharacterSet.alphanumerics", - """ + Example("var url↓: URL = URL()"): Example("var url = URL()"), + Example("let url↓: URL = URL()"): Example("let url = URL()"), + Example("let alphanumerics↓: CharacterSet = CharacterSet.alphanumerics"): + Example("let alphanumerics = CharacterSet.alphanumerics"), + Example(""" class ViewController: UIViewController { func someMethod() { let myVar↓: Int = Int(5) } } - """: - """ + """): + Example(""" class ViewController: UIViewController { func someMethod() { let myVar = Int(5) } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantVoidReturnRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantVoidReturnRule.swift index 417e2050bc..d157e3d03a 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/RedundantVoidReturnRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/RedundantVoidReturnRule.swift @@ -13,47 +13,47 @@ public struct RedundantVoidReturnRule: ConfigurationProviderRule, SubstitutionCo description: "Returning Void in a function declaration is redundant.", kind: .idiomatic, nonTriggeringExamples: [ - "func foo() {}\n", - "func foo() -> Int {}\n", - "func foo() -> (Int) -> Void {}\n", - "func foo() -> VoidResponse\n", - "let foo: Int -> Void\n", - "func foo() -> (Int) -> () {}\n", - "let foo: Int -> ()\n", - "func foo() -> ()?\n", - "func foo() -> ()!\n", - "func foo() -> Void?\n", - "func foo() -> Void!\n", - """ + Example("func foo() {}\n"), + Example("func foo() -> Int {}\n"), + Example("func foo() -> Int -> Void {}\n"), + Example("func foo() -> VoidResponse\n"), + Example("let foo: (Int) -> Void\n"), + Example("func foo() -> Int -> () {}\n"), + Example("let foo: (Int) -> ()\n"), + Example("func foo() -> ()?\n"), + Example("func foo() -> ()!\n"), + Example("func foo() -> Void?\n"), + Example("func foo() -> Void!\n"), + Example(""" struct A { subscript(key: String) { print(key) } } - """ + """) ], triggeringExamples: [ - "func foo()↓ -> Void {}\n", - """ + Example("func foo()↓ -> Void {}\n"), + Example(""" protocol Foo { func foo()↓ -> Void } - """, - "func foo()↓ -> () {}\n", - "func foo()↓ -> ( ) {}", - """ + """), + Example("func foo()↓ -> () {}\n"), + Example("func foo()↓ -> ( ) {}"), + Example(""" protocol Foo { func foo()↓ -> () } - """ + """) ], corrections: [ - "func foo()↓ -> Void {}\n": "func foo() {}\n", - "protocol Foo {\n func foo()↓ -> Void\n}\n": "protocol Foo {\n func foo()\n}\n", - "func foo()↓ -> () {}\n": "func foo() {}\n", - "protocol Foo {\n func foo()↓ -> ()\n}\n": "protocol Foo {\n func foo()\n}\n", - "protocol Foo {\n #if true\n func foo()↓ -> Void\n #endif\n}\n": - "protocol Foo {\n #if true\n func foo()\n #endif\n}\n" + Example("func foo()↓ -> Void {}\n"): Example("func foo() {}\n"), + Example("protocol Foo {\n func foo()↓ -> Void\n}\n"): Example("protocol Foo {\n func foo()\n}\n"), + Example("func foo()↓ -> () {}\n"): Example("func foo() {}\n"), + Example("protocol Foo {\n func foo()↓ -> ()\n}\n"): Example("protocol Foo {\n func foo()\n}\n"), + Example("protocol Foo {\n #if true\n func foo()↓ -> Void\n #endif\n}\n"): + Example("protocol Foo {\n #if true\n func foo()\n #endif\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/StaticOperatorRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/StaticOperatorRule.swift index 3b15a7efa5..cb312ecd36 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/StaticOperatorRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/StaticOperatorRule.swift @@ -12,27 +12,27 @@ public struct StaticOperatorRule: ASTRule, ConfigurationProviderRule, OptInRule, description: "Operators should be declared as static functions, not free functions.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" class A: Equatable { static func == (lhs: A, rhs: A) -> Bool { return false } - """, - """ + """), + Example(""" class A: Equatable { static func == (lhs: A, rhs: A) -> Bool { return false } - """, - """ + """), + Example(""" public extension Array where Element == Rule { static func == (lhs: Array, rhs: Array) -> Bool { if lhs.count != rhs.count { return false } return !zip(lhs, rhs).contains { !$0.0.isEqualTo($0.1) } } } - """, - """ + """), + Example(""" private extension Optional where Wrapped: Comparable { static func < (lhs: Optional, rhs: Optional) -> Bool { switch (lhs, rhs) { @@ -45,26 +45,26 @@ public struct StaticOperatorRule: ASTRule, ConfigurationProviderRule, OptInRule, } } } - """ + """) ], triggeringExamples: [ - """ + Example(""" ↓func == (lhs: A, rhs: A) -> Bool { return false } - """, - """ + """), + Example(""" ↓func == (lhs: A, rhs: A) -> Bool { return false } - """, - """ + """), + Example(""" ↓func == (lhs: [Rule], rhs: [Rule]) -> Bool { if lhs.count != rhs.count { return false } return !zip(lhs, rhs).contains { !$0.0.isEqualTo($0.1) } } - """, - """ + """), + Example(""" private ↓func < (lhs: T?, rhs: T?) -> Bool { switch (lhs, rhs) { case let (lhs?, rhs?): @@ -75,7 +75,7 @@ public struct StaticOperatorRule: ASTRule, ConfigurationProviderRule, OptInRule, return false } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/StrictFilePrivateRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/StrictFilePrivateRule.swift index 57f0c6aabf..9b1e9d149c 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/StrictFilePrivateRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/StrictFilePrivateRule.swift @@ -12,50 +12,50 @@ public struct StrictFilePrivateRule: OptInRule, ConfigurationProviderRule, Autom description: "`fileprivate` should be avoided.", kind: .idiomatic, nonTriggeringExamples: [ - "extension String {}", - "private extension String {}", - """ + Example("extension String {}"), + Example("private extension String {}"), + Example(""" public extension String {} - """, - """ + """), + Example(""" open extension String {} - """, - "internal extension String {}" + """), + Example("internal extension String {}") ], triggeringExamples: [ - "↓fileprivate extension String {}", - """ + Example("↓fileprivate extension String {}"), + Example(""" ↓fileprivate extension String {} - """, - """ + """), + Example(""" ↓fileprivate extension String {} - """, - """ + """), + Example(""" extension String { ↓fileprivate func Something(){} } - """, - """ + """), + Example(""" class MyClass { ↓fileprivate let myInt = 4 } - """, - """ + """), + Example(""" class MyClass { ↓fileprivate(set) var myInt = 4 } - """, - """ + """), + Example(""" struct Outter { struct Inter { ↓fileprivate struct Inner {} } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/SyntacticSugarRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/SyntacticSugarRule.swift index 59b8ca3112..e663a6df01 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/SyntacticSugarRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/SyntacticSugarRule.swift @@ -18,52 +18,53 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv description: "Shorthand syntactic sugar should be used, i.e. [Int] instead of Array.", kind: .idiomatic, nonTriggeringExamples: [ - "let x: [Int]", - "let x: [Int: String]", - "let x: Int?", - "func x(a: [Int], b: Int) -> [Int: Any]", - "let x: Int!", - """ + Example("let x: [Int]"), + Example("let x: [Int: String]"), + Example("let x: Int?"), + Example("func x(a: [Int], b: Int) -> [Int: Any]"), + Example("let x: Int!"), + Example(""" extension Array { func x() { } } - """, - """ + """), + Example(""" extension Dictionary { func x() { } } - """, - "let x: CustomArray", - "var currentIndex: Array.Index?", - "func x(a: [Int], b: Int) -> Array.Index", - "unsafeBitCast(nonOptionalT, to: Optional.self)", - "type is Optional.Type", - "let x: Foo.Optional" + """), + Example("let x: CustomArray"), + Example("var currentIndex: Array.Index?"), + Example("func x(a: [Int], b: Int) -> Array.Index"), + Example("unsafeBitCast(nonOptionalT, to: Optional.self)"), + Example("type is Optional.Type"), + Example("let x: Foo.Optional") ], triggeringExamples: [ - "let x: ↓Array", - "let x: ↓Dictionary", - "let x: ↓Optional", - "let x: ↓ImplicitlyUnwrappedOptional", - "func x(a: ↓Array, b: Int) -> [Int: Any]", - "func x(a: [Int], b: Int) -> ↓Dictionary", - "func x(a: ↓Array, b: Int) -> ↓Dictionary", - "let x = ↓Array.array(of: object)", - "let x: ↓Swift.Optional" + Example("let x: ↓Array"), + Example("let x: ↓Dictionary"), + Example("let x: ↓Optional"), + Example("let x: ↓ImplicitlyUnwrappedOptional"), + Example("func x(a: ↓Array, b: Int) -> [Int: Any]"), + Example("func x(a: [Int], b: Int) -> ↓Dictionary"), + Example("func x(a: ↓Array, b: Int) -> ↓Dictionary"), + Example("let x = ↓Array.array(of: object)"), + Example("let x: ↓Swift.Optional") ], corrections: [ - "let x: Array": "let x: [String]", - "let x: Array< String >": "let x: [ String ]", - "let x: Dictionary": "let x: [Int: String]", - "let x: Dictionary": "let x: [Int : String]", - "let x: Optional": "let x: Int?", - "let x: Optional< Int >": "let x: Int?", - "let x: ImplicitlyUnwrappedOptional": "let x: Int!", - "let x: ImplicitlyUnwrappedOptional< Int >": "let x: Int!", - "func x(a: Array, b: Int) -> [Int: Any]": "func x(a: [Int], b: Int) -> [Int: Any]", - "func x(a: [Int], b: Int) -> Dictionary": "func x(a: [Int], b: Int) -> [Int: String]", - "let x = Array.array(of: object)": "let x = [String].array(of: object)", - "let x: Swift.Optional": "let x: String?" + Example("let x: Array"): Example("let x: [String]"), + Example("let x: Array< String >"): Example("let x: [ String ]"), + Example("let x: Dictionary"): Example("let x: [Int: String]"), + Example("let x: Dictionary"): Example("let x: [Int : String]"), + Example("let x: Optional"): Example("let x: Int?"), + Example("let x: Optional< Int >"): Example("let x: Int?"), + Example("let x: ImplicitlyUnwrappedOptional"): Example("let x: Int!"), + Example("let x: ImplicitlyUnwrappedOptional< Int >"): Example("let x: Int!"), + Example("func x(a: Array, b: Int) -> [Int: Any]"): Example("func x(a: [Int], b: Int) -> [Int: Any]"), + Example("func x(a: [Int], b: Int) -> Dictionary"): + Example("func x(a: [Int], b: Int) -> [Int: String]"), + Example("let x = Array.array(of: object)"): Example("let x = [String].array(of: object)"), + Example("let x: Swift.Optional"): Example("let x: String?") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/ToggleBoolRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/ToggleBoolRule.swift index e7cb748b4d..5928bc87d7 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/ToggleBoolRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/ToggleBoolRule.swift @@ -13,21 +13,21 @@ public struct ToggleBoolRule: SubstitutionCorrectableRule, ConfigurationProvider kind: .idiomatic, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - "isHidden.toggle()\n", - "view.clipsToBounds.toggle()\n", - "func foo() { abc.toggle() }", - "view.clipsToBounds = !clipsToBounds\n", - "disconnected = !connected\n" + Example("isHidden.toggle()\n"), + Example("view.clipsToBounds.toggle()\n"), + Example("func foo() { abc.toggle() }"), + Example("view.clipsToBounds = !clipsToBounds\n"), + Example("disconnected = !connected\n") ], triggeringExamples: [ - "↓isHidden = !isHidden\n", - "↓view.clipsToBounds = !view.clipsToBounds\n", - "func foo() { ↓abc = !abc }" + Example("↓isHidden = !isHidden\n"), + Example("↓view.clipsToBounds = !view.clipsToBounds\n"), + Example("func foo() { ↓abc = !abc }") ], corrections: [ - "↓isHidden = !isHidden\n": "isHidden.toggle()\n", - "↓view.clipsToBounds = !view.clipsToBounds\n": "view.clipsToBounds.toggle()\n", - "func foo() { ↓abc = !abc }": "func foo() { abc.toggle() }" + Example("↓isHidden = !isHidden\n"): Example("isHidden.toggle()\n"), + Example("↓view.clipsToBounds = !view.clipsToBounds\n"): Example("view.clipsToBounds.toggle()\n"), + Example("func foo() { ↓abc = !abc }"): Example("func foo() { abc.toggle() }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/TrailingSemicolonRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/TrailingSemicolonRule.swift index 09ba7e33da..696c954193 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/TrailingSemicolonRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/TrailingSemicolonRule.swift @@ -11,20 +11,20 @@ public struct TrailingSemicolonRule: SubstitutionCorrectableRule, ConfigurationP name: "Trailing Semicolon", description: "Lines should not have trailing semicolons.", kind: .idiomatic, - nonTriggeringExamples: [ "let a = 0\n" ], + nonTriggeringExamples: [ Example("let a = 0\n") ], triggeringExamples: [ - "let a = 0↓;\n", - "let a = 0↓;\nlet b = 1\n", - "let a = 0↓;;\n", - "let a = 0↓; ;;\n", - "let a = 0↓; ; ;\n" + Example("let a = 0↓;\n"), + Example("let a = 0↓;\nlet b = 1\n"), + Example("let a = 0↓;;\n"), + Example("let a = 0↓; ;;\n"), + Example("let a = 0↓; ; ;\n") ], corrections: [ - "let a = 0↓;\n": "let a = 0\n", - "let a = 0↓;\nlet b = 1\n": "let a = 0\nlet b = 1\n", - "let a = 0↓;;\n": "let a = 0\n", - "let a = 0↓; ;;\n": "let a = 0\n", - "let a = 0↓; ; ;\n": "let a = 0\n" + Example("let a = 0↓;\n"): Example("let a = 0\n"), + Example("let a = 0↓;\nlet b = 1\n"): Example("let a = 0\nlet b = 1\n"), + Example("let a = 0↓;;\n"): Example("let a = 0\n"), + Example("let a = 0↓; ;;\n"): Example("let a = 0\n"), + Example("let a = 0↓; ; ;\n"): Example("let a = 0\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/TypeNameRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/TypeNameRuleExamples.swift index 7c22090510..0f8a536cef 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/TypeNameRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/TypeNameRuleExamples.swift @@ -1,69 +1,69 @@ internal struct TypeNameRuleExamples { private static let types = ["class", "struct", "enum"] - static let nonTriggeringExamples: [String] = { - let typeExamples: [String] = types.flatMap { type -> [String] in + static let nonTriggeringExamples: [Example] = { + let typeExamples: [Example] = types.flatMap { type -> [Example] in [ - "\(type) MyType {}", - "private \(type) _MyType {}", - "\(type) \(repeatElement("A", count: 40).joined()) {}", - "\(type) MyView_Previews: PreviewProvider", - "private \(type) _MyView_Previews: PreviewProvider" + Example("\(type) MyType {}"), + Example("private \(type) _MyType {}"), + Example("\(type) \(repeatElement("A", count: 40).joined()) {}"), + Example("\(type) MyView_Previews: PreviewProvider"), + Example("private \(type) _MyView_Previews: PreviewProvider") ] } - let typeAliasAndAssociatedTypeExamples = [ - "typealias Foo = Void", - "private typealias Foo = Void", - """ + let typeAliasAndAssociatedTypeExamples: [Example] = [ + Example("typealias Foo = Void"), + Example("private typealias Foo = Void"), + Example(""" protocol Foo { associatedtype Bar } - """, - """ + """), + Example(""" protocol Foo { associatedtype Bar: Equatable } - """ + """) ] - return typeExamples + typeAliasAndAssociatedTypeExamples + ["enum MyType {\ncase value\n}"] + return typeExamples + typeAliasAndAssociatedTypeExamples + [Example("enum MyType {\ncase value\n}")] }() - static let triggeringExamples: [String] = { - let typeExamples: [String] = types.flatMap { type in + static let triggeringExamples: [Example] = { + let typeExamples: [Example] = types.flatMap { type in [ - "\(type) ↓myType {}", - "\(type) ↓_MyType {}", - "private \(type) ↓MyType_ {}", - "\(type) ↓My {}", - "\(type) ↓\(repeatElement("A", count: 41).joined()) {}", - "\(type) ↓MyView_Previews", - "private \(type) ↓_MyView_Previews", - "\(type) ↓MyView_Previews_Previews: PreviewProvider" + Example("\(type) ↓myType {}"), + Example("\(type) ↓_MyType {}"), + Example("private \(type) ↓MyType_ {}"), + Example("\(type) ↓My {}"), + Example("\(type) ↓\(repeatElement("A", count: 41).joined()) {}"), + Example("\(type) ↓MyView_Previews"), + Example("private \(type) ↓_MyView_Previews"), + Example("\(type) ↓MyView_Previews_Previews: PreviewProvider") ] } - let typeAliasAndAssociatedTypeExamples: [String] = [ - "typealias ↓X = Void", - "private typealias ↓Foo_Bar = Void", - "private typealias ↓foo = Void", - "typealias ↓\(repeatElement("A", count: 41).joined()) = Void", - """ + let typeAliasAndAssociatedTypeExamples: [Example] = [ + Example("typealias ↓X = Void"), + Example("private typealias ↓Foo_Bar = Void"), + Example("private typealias ↓foo = Void"), + Example("typealias ↓\(repeatElement("A", count: 41).joined()) = Void"), + Example(""" protocol Foo { associatedtype ↓X } - """, - """ + """), + Example(""" protocol Foo { associatedtype ↓Foo_Bar: Equatable } - """, - """ + """), + Example(""" protocol Foo { associatedtype ↓\(repeatElement("A", count: 41).joined()) } - """ + """) ] return typeExamples + typeAliasAndAssociatedTypeExamples diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/UnavailableFunctionRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/UnavailableFunctionRule.swift index 4c2234949a..929b35bf1b 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/UnavailableFunctionRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/UnavailableFunctionRule.swift @@ -13,15 +13,15 @@ public struct UnavailableFunctionRule: ASTRule, ConfigurationProviderRule, OptIn kind: .idiomatic, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - """ + Example(""" class ViewController: UIViewController { @available(*, unavailable) public required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } - """, - """ + """), + Example(""" func jsonValue(_ jsonString: String) -> NSObject { let data = jsonString.data(using: .utf8)! let result = try! JSONSerialization.jsonObject(with: data, options: []) @@ -32,24 +32,24 @@ public struct UnavailableFunctionRule: ASTRule, ConfigurationProviderRule, OptIn } fatalError() } - """ + """) ], triggeringExamples: [ - """ + Example(""" class ViewController: UIViewController { public required ↓init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } - """, - """ + """), + Example(""" class ViewController: UIViewController { public required ↓init?(coder aDecoder: NSCoder) { let reason = "init(coder:) has not been implemented" fatalError(reason) } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/UnneededBreakInSwitchRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/UnneededBreakInSwitchRule.swift index 7304c33185..cd4702a130 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/UnneededBreakInSwitchRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/UnneededBreakInSwitchRule.swift @@ -1,11 +1,16 @@ import Foundation import SourceKittenFramework -private func embedInSwitch(_ text: String, case: String = "case .bar") -> String { - return "switch foo {\n" + - "\(`case`):\n" + - " \(text)\n" + - "}" +private func embedInSwitch( + _ text: String, + case: String = "case .bar", + file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" + switch foo { + \(`case`): + \(text) + } + """, file: file, line: line) } public struct UnneededBreakInSwitchRule: ConfigurationProviderRule, AutomaticTestableRule { public var configuration = SeverityConfiguration(.warning) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/UntypedErrorInCatchRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/UntypedErrorInCatchRule.swift index cabf802634..c7600d1e04 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/UntypedErrorInCatchRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/UntypedErrorInCatchRule.swift @@ -35,71 +35,71 @@ public struct UntypedErrorInCatchRule: OptInRule, ConfigurationProviderRule, Aut description: "Catch statements should not declare error variables without type casting.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" do { try foo() } catch {} - """, - """ + """), + Example(""" do { try foo() } catch Error.invalidOperation { } catch {} - """, - """ + """), + Example(""" do { try foo() } catch let error as MyError { } catch {} - """, - """ + """), + Example(""" do { try foo() } catch var error as MyError { } catch {} - """ + """) ], triggeringExamples: [ - """ + Example(""" do { try foo() } ↓catch var error {} - """, - """ + """), + Example(""" do { try foo() } ↓catch let error {} - """, - """ + """), + Example(""" do { try foo() } ↓catch let someError {} - """, - """ + """), + Example(""" do { try foo() } ↓catch var someError {} - """, - """ + """), + Example(""" do { try foo() } ↓catch let e {} - """, - """ + """), + Example(""" do { try foo() } ↓catch(let error) {} - """, - """ + """), + Example(""" do { try foo() } ↓catch (let error) {} - """ + """) ], corrections: [ - "do {\n try foo() \n} ↓catch let error {}": "do {\n try foo() \n} catch {}", - "do {\n try foo() \n} ↓catch(let error) {}": "do {\n try foo() \n} catch {}", - "do {\n try foo() \n} ↓catch (let error) {}": "do {\n try foo() \n} catch {}" + Example("do {\n try foo() \n} ↓catch let error {}"): Example("do {\n try foo() \n} catch {}"), + Example("do {\n try foo() \n} ↓catch(let error) {}"): Example("do {\n try foo() \n} catch {}"), + Example("do {\n try foo() \n} ↓catch (let error) {}"): Example("do {\n try foo() \n} catch {}") ]) public func validate(file: SwiftLintFile) -> [StyleViolation] { diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/UnusedEnumeratedRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/UnusedEnumeratedRule.swift index 0889add700..8da8a2bcb6 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/UnusedEnumeratedRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/UnusedEnumeratedRule.swift @@ -11,21 +11,21 @@ public struct UnusedEnumeratedRule: ASTRule, ConfigurationProviderRule, Automati description: "When the index or the item is not used, `.enumerated()` can be removed.", kind: .idiomatic, nonTriggeringExamples: [ - "for (idx, foo) in bar.enumerated() { }\n", - "for (_, foo) in bar.enumerated().something() { }\n", - "for (_, foo) in bar.something() { }\n", - "for foo in bar.enumerated() { }\n", - "for foo in bar { }\n", - "for (idx, _) in bar.enumerated().something() { }\n", - "for (idx, _) in bar.something() { }\n", - "for idx in bar.indices { }\n", - "for (section, (event, _)) in data.enumerated() {}\n" + Example("for (idx, foo) in bar.enumerated() { }\n"), + Example("for (_, foo) in bar.enumerated().something() { }\n"), + Example("for (_, foo) in bar.something() { }\n"), + Example("for foo in bar.enumerated() { }\n"), + Example("for foo in bar { }\n"), + Example("for (idx, _) in bar.enumerated().something() { }\n"), + Example("for (idx, _) in bar.something() { }\n"), + Example("for idx in bar.indices { }\n"), + Example("for (section, (event, _)) in data.enumerated() {}\n") ], triggeringExamples: [ - "for (↓_, foo) in bar.enumerated() { }\n", - "for (↓_, foo) in abc.bar.enumerated() { }\n", - "for (↓_, foo) in abc.something().enumerated() { }\n", - "for (idx, ↓_) in bar.enumerated() { }\n" + Example("for (↓_, foo) in bar.enumerated() { }\n"), + Example("for (↓_, foo) in abc.bar.enumerated() { }\n"), + Example("for (↓_, foo) in abc.something().enumerated() { }\n"), + Example("for (idx, ↓_) in bar.enumerated() { }\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/XCTFailMessageRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/XCTFailMessageRule.swift index 55c5f73c0b..5ab39e50b1 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/XCTFailMessageRule.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/XCTFailMessageRule.swift @@ -11,28 +11,28 @@ public struct XCTFailMessageRule: ASTRule, ConfigurationProviderRule, AutomaticT description: "An XCTFail call should include a description of the assertion.", kind: .idiomatic, nonTriggeringExamples: [ - """ + Example(""" func testFoo() { XCTFail("bar") } - """, - """ + """), + Example(""" func testFoo() { XCTFail(bar) } - """ + """) ], triggeringExamples: [ - """ + Example(""" func testFoo() { ↓XCTFail() } - """, - """ + """), + Example(""" func testFoo() { ↓XCTFail("") } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/XCTSpecificMatcherRuleExamples.swift b/Source/SwiftLintFramework/Rules/Idiomatic/XCTSpecificMatcherRuleExamples.swift index dca7d5bd60..6fba7c8fd2 100644 --- a/Source/SwiftLintFramework/Rules/Idiomatic/XCTSpecificMatcherRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Idiomatic/XCTSpecificMatcherRuleExamples.swift @@ -1,107 +1,107 @@ internal struct XCTSpecificMatcherRuleExamples { static let nonTriggeringExamples = [ // True/False - "XCTAssertFalse(foo)", - "XCTAssertTrue(foo)", + Example("XCTAssertFalse(foo)"), + Example("XCTAssertTrue(foo)"), // Nil/Not nil - "XCTAssertNil(foo)", - "XCTAssertNotNil(foo)", + Example("XCTAssertNil(foo)"), + Example("XCTAssertNotNil(foo)"), // Equal/Not equal - "XCTAssertEqual(foo, 2)", - "XCTAssertNotEqual(foo, \"false\")", + Example("XCTAssertEqual(foo, 2)"), + Example("XCTAssertNotEqual(foo, \"false\")"), // Arrays with key words - "XCTAssertEqual(foo, [1, 2, 3, true])", - "XCTAssertEqual(foo, [1, 2, 3, false])", - "XCTAssertEqual(foo, [1, 2, 3, nil])", - "XCTAssertEqual(foo, [true, nil, true, nil])", - "XCTAssertEqual([1, 2, 3, true], foo)", - "XCTAssertEqual([1, 2, 3, false], foo)", - "XCTAssertEqual([1, 2, 3, nil], foo)", - "XCTAssertEqual([true, nil, true, nil], foo)", + Example("XCTAssertEqual(foo, [1, 2, 3, true])"), + Example("XCTAssertEqual(foo, [1, 2, 3, false])"), + Example("XCTAssertEqual(foo, [1, 2, 3, nil])"), + Example("XCTAssertEqual(foo, [true, nil, true, nil])"), + Example("XCTAssertEqual([1, 2, 3, true], foo)"), + Example("XCTAssertEqual([1, 2, 3, false], foo)"), + Example("XCTAssertEqual([1, 2, 3, nil], foo)"), + Example("XCTAssertEqual([true, nil, true, nil], foo)"), // Inverted logic - "XCTAssertEqual(2, foo)", - "XCTAssertNotEqual(\"false\", foo)", - "XCTAssertEqual(false, foo?.bar)", - "XCTAssertEqual(true, foo?.bar)", + Example("XCTAssertEqual(2, foo)"), + Example("XCTAssertNotEqual(\"false\"), foo)"), + Example("XCTAssertEqual(false, foo?.bar)"), + Example("XCTAssertEqual(true, foo?.bar)"), // Blank spaces - "XCTAssertFalse( foo )", - "XCTAssertTrue( foo )", - "XCTAssertNil( foo )", - "XCTAssertNotNil( foo )", - "XCTAssertEqual( foo , 2 )", - "XCTAssertNotEqual( foo, \"false\")", + Example("XCTAssertFalse( foo )"), + Example("XCTAssertTrue( foo )"), + Example("XCTAssertNil( foo )"), + Example("XCTAssertNotNil( foo )"), + Example("XCTAssertEqual( foo , 2 )"), + Example("XCTAssertNotEqual( foo, \"false\")"), // Optionals - "XCTAssertEqual(foo?.bar, false)", - "XCTAssertEqual(foo?.bar, true)", - "XCTAssertNil(foo?.bar)", - "XCTAssertNotNil(foo?.bar)", - "XCTAssertEqual(foo?.bar, 2)", - "XCTAssertNotEqual(foo?.bar, \"false\")", + Example("XCTAssertEqual(foo?.bar, false)"), + Example("XCTAssertEqual(foo?.bar, true)"), + Example("XCTAssertNil(foo?.bar)"), + Example("XCTAssertNotNil(foo?.bar)"), + Example("XCTAssertEqual(foo?.bar, 2)"), + Example("XCTAssertNotEqual(foo?.bar, \"false\")"), // Function calls and enums - "XCTAssertEqual(foo?.bar, toto())", - "XCTAssertEqual(foo?.bar, .toto(.zoo))", - "XCTAssertEqual(toto(), foo?.bar)", - "XCTAssertEqual(.toto(.zoo), foo?.bar)" + Example("XCTAssertEqual(foo?.bar, toto())"), + Example("XCTAssertEqual(foo?.bar, .toto(.zoo))"), + Example("XCTAssertEqual(toto(), foo?.bar)"), + Example("XCTAssertEqual(.toto(.zoo), foo?.bar)") ] static let triggeringExamples = [ // Without message - "↓XCTAssertEqual(foo, true)", - "↓XCTAssertEqual(foo, false)", - "↓XCTAssertEqual(foo, nil)", - "↓XCTAssertNotEqual(foo, true)", - "↓XCTAssertNotEqual(foo, false)", - "↓XCTAssertNotEqual(foo, nil)", + Example("↓XCTAssertEqual(foo, true)"), + Example("↓XCTAssertEqual(foo, false)"), + Example("↓XCTAssertEqual(foo, nil)"), + Example("↓XCTAssertNotEqual(foo, true)"), + Example("↓XCTAssertNotEqual(foo, false)"), + Example("↓XCTAssertNotEqual(foo, nil)"), // Inverted logic (just in case...) - "↓XCTAssertEqual(true, foo)", - "↓XCTAssertEqual(false, foo)", - "↓XCTAssertEqual(nil, foo)", - "↓XCTAssertNotEqual(true, foo)", - "↓XCTAssertNotEqual(false, foo)", - "↓XCTAssertNotEqual(nil, foo)", + Example("↓XCTAssertEqual(true, foo)"), + Example("↓XCTAssertEqual(false, foo)"), + Example("↓XCTAssertEqual(nil, foo)"), + Example("↓XCTAssertNotEqual(true, foo)"), + Example("↓XCTAssertNotEqual(false, foo)"), + Example("↓XCTAssertNotEqual(nil, foo)"), // With message - "↓XCTAssertEqual(foo, true, \"toto\")", - "↓XCTAssertEqual(foo, false, \"toto\")", - "↓XCTAssertEqual(foo, nil, \"toto\")", - "↓XCTAssertNotEqual(foo, true, \"toto\")", - "↓XCTAssertNotEqual(foo, false, \"toto\")", - "↓XCTAssertNotEqual(foo, nil, \"toto\")", - "↓XCTAssertEqual(true, foo, \"toto\")", - "↓XCTAssertEqual(false, foo, \"toto\")", - "↓XCTAssertEqual(nil, foo, \"toto\")", - "↓XCTAssertNotEqual(true, foo, \"toto\")", - "↓XCTAssertNotEqual(false, foo, \"toto\")", - "↓XCTAssertNotEqual(nil, foo, \"toto\")", + Example("↓XCTAssertEqual(foo, true, \"toto\")"), + Example("↓XCTAssertEqual(foo, false, \"toto\")"), + Example("↓XCTAssertEqual(foo, nil, \"toto\")"), + Example("↓XCTAssertNotEqual(foo, true, \"toto\")"), + Example("↓XCTAssertNotEqual(foo, false, \"toto\")"), + Example("↓XCTAssertNotEqual(foo, nil, \"toto\")"), + Example("↓XCTAssertEqual(true, foo, \"toto\")"), + Example("↓XCTAssertEqual(false, foo, \"toto\")"), + Example("↓XCTAssertEqual(nil, foo, \"toto\")"), + Example("↓XCTAssertNotEqual(true, foo, \"toto\")"), + Example("↓XCTAssertNotEqual(false, foo, \"toto\")"), + Example("↓XCTAssertNotEqual(nil, foo, \"toto\")"), // Blank spaces - "↓XCTAssertEqual(foo,true)", - "↓XCTAssertEqual( foo , false )", - "↓XCTAssertEqual( foo , nil )", + Example("↓XCTAssertEqual(foo,true)"), + Example("↓XCTAssertEqual( foo , false )"), + Example("↓XCTAssertEqual( foo , nil )"), // Arrays - "↓XCTAssertEqual(true, [1, 2, 3, true].hasNumbers())", - "↓XCTAssertEqual([1, 2, 3, true].hasNumbers(), true)", + Example("↓XCTAssertEqual(true, [1, 2, 3, true].hasNumbers())"), + Example("↓XCTAssertEqual([1, 2, 3, true].hasNumbers(), true)"), // Optionals - "↓XCTAssertEqual(foo?.bar, nil)", - "↓XCTAssertNotEqual(foo?.bar, nil)", + Example("↓XCTAssertEqual(foo?.bar, nil)"), + Example("↓XCTAssertNotEqual(foo?.bar, nil)"), // Weird cases - "↓XCTAssertEqual(nil, true)", - "↓XCTAssertEqual(nil, false)", - "↓XCTAssertEqual(true, nil)", - "↓XCTAssertEqual(false, nil)", - "↓XCTAssertEqual(nil, nil)", - "↓XCTAssertEqual(true, true)", - "↓XCTAssertEqual(false, false)" + Example("↓XCTAssertEqual(nil, true)"), + Example("↓XCTAssertEqual(nil, false)"), + Example("↓XCTAssertEqual(true, nil)"), + Example("↓XCTAssertEqual(false, nil)"), + Example("↓XCTAssertEqual(nil, nil)"), + Example("↓XCTAssertEqual(true, true)"), + Example("↓XCTAssertEqual(false, false)") ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/AnyObjectProtocolRule.swift b/Source/SwiftLintFramework/Rules/Lint/AnyObjectProtocolRule.swift index 842423a2c5..f98bfd8a3a 100644 --- a/Source/SwiftLintFramework/Rules/Lint/AnyObjectProtocolRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/AnyObjectProtocolRule.swift @@ -14,25 +14,25 @@ public struct AnyObjectProtocolRule: SubstitutionCorrectableASTRule, OptInRule, kind: .lint, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "protocol SomeProtocol {}\n", - "protocol SomeClassOnlyProtocol: AnyObject {}\n", - "protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n", - "@objc protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n" + Example("protocol SomeProtocol {}\n"), + Example("protocol SomeClassOnlyProtocol: AnyObject {}\n"), + Example("protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n"), + Example("@objc protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n") ], triggeringExamples: [ - "protocol SomeClassOnlyProtocol: ↓class {}\n", - "protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n", - "@objc protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n" + Example("protocol SomeClassOnlyProtocol: ↓class {}\n"), + Example("protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n"), + Example("@objc protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n") ], corrections: [ - "protocol SomeClassOnlyProtocol: ↓class {}\n": - "protocol SomeClassOnlyProtocol: AnyObject {}\n", - "protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n": - "protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n", - "protocol SomeClassOnlyProtocol: SomeInheritedProtocol, ↓class {}\n": - "protocol SomeClassOnlyProtocol: SomeInheritedProtocol, AnyObject {}\n", - "@objc protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n": - "@objc protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n" + Example("protocol SomeClassOnlyProtocol: ↓class {}\n"): + Example("protocol SomeClassOnlyProtocol: AnyObject {}\n"), + Example("protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n"): + Example("protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n"), + Example("protocol SomeClassOnlyProtocol: SomeInheritedProtocol, ↓class {}\n"): + Example("protocol SomeClassOnlyProtocol: SomeInheritedProtocol, AnyObject {}\n"), + Example("@objc protocol SomeClassOnlyProtocol: ↓class, SomeInheritedProtocol {}\n"): + Example("@objc protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/ArrayInitRule.swift b/Source/SwiftLintFramework/Rules/Lint/ArrayInitRule.swift index a560de0572..eaa498bbe5 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ArrayInitRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ArrayInitRule.swift @@ -12,35 +12,35 @@ public struct ArrayInitRule: ASTRule, ConfigurationProviderRule, OptInRule, Auto description: "Prefer using `Array(seq)` over `seq.map { $0 }` to convert a sequence into an Array.", kind: .lint, nonTriggeringExamples: [ - "Array(foo)\n", - "foo.map { $0.0 }\n", - "foo.map { $1 }\n", - "foo.map { $0() }\n", - "foo.map { ((), $0) }\n", - "foo.map { $0! }\n", - "foo.map { $0! /* force unwrap */ }\n", - "foo.something { RouteMapper.map($0) }\n", - "foo.map { !$0 }\n", - "foo.map { /* a comment */ !$0 }\n" + Example("Array(foo)\n"), + Example("foo.map { $0.0 }\n"), + Example("foo.map { $1 }\n"), + Example("foo.map { $0() }\n"), + Example("foo.map { ((), $0) }\n"), + Example("foo.map { $0! }\n"), + Example("foo.map { $0! /* force unwrap */ }\n"), + Example("foo.something { RouteMapper.map($0) }\n"), + Example("foo.map { !$0 }\n"), + Example("foo.map { /* a comment */ !$0 }\n") ], triggeringExamples: [ - "↓foo.map({ $0 })\n", - "↓foo.map { $0 }\n", - "↓foo.map { return $0 }\n", - "↓foo.map { elem in\n" + + Example("↓foo.map({ $0 })\n"), + Example("↓foo.map { $0 }\n"), + Example("↓foo.map { return $0 }\n"), + Example("↓foo.map { elem in\n" + " elem\n" + - "}\n", - "↓foo.map { elem in\n" + + "}\n"), + Example("↓foo.map { elem in\n" + " return elem\n" + - "}\n", - "↓foo.map { (elem: String) in\n" + + "}\n"), + Example("↓foo.map { (elem: String) in\n" + " elem\n" + - "}\n", - "↓foo.map { elem -> String in\n" + + "}\n"), + Example("↓foo.map { elem -> String in\n" + " elem\n" + - "}\n", - "↓foo.map { $0 /* a comment */ }\n", - "↓foo.map { /* a comment */ $0 }\n" + "}\n"), + Example("↓foo.map { $0 /* a comment */ }\n"), + Example("↓foo.map { /* a comment */ $0 }\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/ClassDelegateProtocolRule.swift b/Source/SwiftLintFramework/Rules/Lint/ClassDelegateProtocolRule.swift index b5d63749db..a853eb5360 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ClassDelegateProtocolRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ClassDelegateProtocolRule.swift @@ -12,19 +12,19 @@ public struct ClassDelegateProtocolRule: ASTRule, ConfigurationProviderRule, Aut description: "Delegate protocols should be class-only so they can be weakly referenced.", kind: .lint, nonTriggeringExamples: [ - "protocol FooDelegate: class {}\n", - "protocol FooDelegate: class, BarDelegate {}\n", - "protocol Foo {}\n", - "class FooDelegate {}\n", - "@objc protocol FooDelegate {}\n", - "@objc(MyFooDelegate)\n protocol FooDelegate {}\n", - "protocol FooDelegate: BarDelegate {}\n", - "protocol FooDelegate: AnyObject {}\n", - "protocol FooDelegate: NSObjectProtocol {}\n" + Example("protocol FooDelegate: class {}\n"), + Example("protocol FooDelegate: class, BarDelegate {}\n"), + Example("protocol Foo {}\n"), + Example("class FooDelegate {}\n"), + Example("@objc protocol FooDelegate {}\n"), + Example("@objc(MyFooDelegate)\n protocol FooDelegate {}\n"), + Example("protocol FooDelegate: BarDelegate {}\n"), + Example("protocol FooDelegate: AnyObject {}\n"), + Example("protocol FooDelegate: NSObjectProtocol {}\n") ], triggeringExamples: [ - "↓protocol FooDelegate {}\n", - "↓protocol FooDelegate: Bar {}\n" + Example("↓protocol FooDelegate {}\n"), + Example("↓protocol FooDelegate: Bar {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/CompilerProtocolInitRule.swift b/Source/SwiftLintFramework/Rules/Lint/CompilerProtocolInitRule.swift index d60fb95988..b5edb0f53e 100644 --- a/Source/SwiftLintFramework/Rules/Lint/CompilerProtocolInitRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/CompilerProtocolInitRule.swift @@ -15,12 +15,12 @@ public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule { ), kind: .lint, nonTriggeringExamples: [ - "let set: Set = [1, 2]\n", - "let set = Set(array)\n" + Example("let set: Set = [1, 2]\n"), + Example("let set = Set(array)\n") ], triggeringExamples: [ - "let set = ↓Set(arrayLiteral: 1, 2)\n", - "let set = ↓Set.init(arrayLiteral: 1, 2)\n" + Example("let set = ↓Set(arrayLiteral: 1, 2)\n"), + Example("let set = ↓Set.init(arrayLiteral: 1, 2)\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/DeploymentTargetRule.swift b/Source/SwiftLintFramework/Rules/Lint/DeploymentTargetRule.swift index 8a1388bd74..370b73e57c 100644 --- a/Source/SwiftLintFramework/Rules/Lint/DeploymentTargetRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/DeploymentTargetRule.swift @@ -15,27 +15,27 @@ public struct DeploymentTargetRule: ConfigurationProviderRule { kind: .lint, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "@available(iOS 12.0, *)\nclass A {}", - "@available(watchOS 4.0, *)\nclass A {}", - "@available(swift 3.0.2)\nclass A {}", - "class A {}", - "if #available(iOS 10.0, *) {}", - "if #available(iOS 10, *) {}", - "guard #available(iOS 12.0, *) else { return }" + Example("@available(iOS 12.0, *)\nclass A {}"), + Example("@available(watchOS 4.0, *)\nclass A {}"), + Example("@available(swift 3.0.2)\nclass A {}"), + Example("class A {}"), + Example("if #available(iOS 10.0, *) {}"), + Example("if #available(iOS 10, *) {}"), + Example("guard #available(iOS 12.0, *) else { return }") ], triggeringExamples: [ - "↓@available(iOS 6.0, *)\nclass A {}", - "↓@available(iOS 7.0, *)\nclass A {}", - "↓@available(iOS 6, *)\nclass A {}", - "↓@available(iOS 6.0, macOS 10.12, *)\n class A {}", - "↓@available(macOS 10.12, iOS 6.0, *)\n class A {}", - "↓@available(macOS 10.7, *)\nclass A {}", - "↓@available(OSX 10.7, *)\nclass A {}", - "↓@available(watchOS 0.9, *)\nclass A {}", - "↓@available(tvOS 8, *)\nclass A {}", - "if ↓#available(iOS 6.0, *) {}", - "if ↓#available(iOS 6, *) {}", - "guard ↓#available(iOS 6.0, *) else { return }" + Example("↓@available(iOS 6.0, *)\nclass A {}"), + Example("↓@available(iOS 7.0, *)\nclass A {}"), + Example("↓@available(iOS 6, *)\nclass A {}"), + Example("↓@available(iOS 6.0, macOS 10.12, *)\n class A {}"), + Example("↓@available(macOS 10.12, iOS 6.0, *)\n class A {}"), + Example("↓@available(macOS 10.7, *)\nclass A {}"), + Example("↓@available(OSX 10.7, *)\nclass A {}"), + Example("↓@available(watchOS 0.9, *)\nclass A {}"), + Example("↓@available(tvOS 8, *)\nclass A {}"), + Example("if ↓#available(iOS 6.0, *) {}"), + Example("if ↓#available(iOS 6, *) {}"), + Example("guard ↓#available(iOS 6.0, *) else { return }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/DiscardedNotificationCenterObserverRule.swift b/Source/SwiftLintFramework/Rules/Lint/DiscardedNotificationCenterObserverRule.swift index 27a6958e7e..d03f1d5bad 100644 --- a/Source/SwiftLintFramework/Rules/Lint/DiscardedNotificationCenterObserverRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/DiscardedNotificationCenterObserverRule.swift @@ -13,34 +13,40 @@ public struct DiscardedNotificationCenterObserverRule: ASTRule, ConfigurationPro "returned should be stored so it can be removed later.", kind: .lint, nonTriggeringExamples: [ - "let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }\n", - "let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n", - "func foo() -> Any {\n" + + Example("let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }\n"), + Example(""" + let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }) + """), + Example("func foo() -> Any {\n" + " return nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n" + - "}\n", - "var obs: [Any?] = []\n" + - "obs.append(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n", - "var obs: [String: Any?] = []\n" + - "obs[\"foo\"] = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n", - "var obs: [Any?] = []\n" + - "obs.append(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n", - "func foo(_ notif: Any) {\n" + + "}\n"), + Example("var obs: [Any?] = []\n" + + "obs.append(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n"), + Example(""" + var obs: [String: Any?] = [] + obs["foo"] = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }) + """), + Example("var obs: [Any?] = []\n" + + "obs.append(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n"), + Example("func foo(_ notif: Any) {\n" + " obs.append(notif)\n" + "}\n" + - "foo(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n", - """ + "foo(nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }))\n"), + Example(""" var obs: [NSObjectProtocol] = [ nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }), nc.addObserver(forName: .CKAccountChanged, object: nil, queue: nil, using: { }) ] - """ + """) ], triggeringExamples: [ - "↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }\n", - "↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n", - "@discardableResult func foo() -> Any {\n" + - " return ↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n" + - "}\n" + Example("↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }\n"), + Example("↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { })\n"), + Example(""" + @discardableResult func foo() -> Any { + return ↓nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: { }) + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/DiscouragedDirectInitRule.swift b/Source/SwiftLintFramework/Rules/Lint/DiscouragedDirectInitRule.swift index cfbf43c52b..18a7d29ef9 100644 --- a/Source/SwiftLintFramework/Rules/Lint/DiscouragedDirectInitRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/DiscouragedDirectInitRule.swift @@ -9,24 +9,24 @@ public struct DiscouragedDirectInitRule: ASTRule, ConfigurationProviderRule { description: "Discouraged direct initialization of types that can be harmful.", kind: .lint, nonTriggeringExamples: [ - "let foo = UIDevice.current", - "let foo = Bundle.main", - "let foo = Bundle(path: \"bar\")", - "let foo = Bundle(identifier: \"bar\")", - "let foo = Bundle.init(path: \"bar\")", - "let foo = Bundle.init(identifier: \"bar\")" + Example("let foo = UIDevice.current"), + Example("let foo = Bundle.main"), + Example("let foo = Bundle(path: \"bar\")"), + Example("let foo = Bundle(identifier: \"bar\")"), + Example("let foo = Bundle.init(path: \"bar\")"), + Example("let foo = Bundle.init(identifier: \"bar\")") ], triggeringExamples: [ - "↓UIDevice()", - "↓Bundle()", - "let foo = ↓UIDevice()", - "let foo = ↓Bundle()", - "let foo = bar(bundle: ↓Bundle(), device: ↓UIDevice())", - "↓UIDevice.init()", - "↓Bundle.init()", - "let foo = ↓UIDevice.init()", - "let foo = ↓Bundle.init()", - "let foo = bar(bundle: ↓Bundle.init(), device: ↓UIDevice.init())" + Example("↓UIDevice()"), + Example("↓Bundle()"), + Example("let foo = ↓UIDevice()"), + Example("let foo = ↓Bundle()"), + Example("let foo = bar(bundle: ↓Bundle(), device: ↓UIDevice())"), + Example("↓UIDevice.init()"), + Example("↓Bundle.init()"), + Example("let foo = ↓UIDevice.init()"), + Example("let foo = ↓Bundle.init()"), + Example("let foo = bar(bundle: ↓Bundle.init(), device: ↓UIDevice.init())") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/DuplicateEnumCasesRule.swift b/Source/SwiftLintFramework/Rules/Lint/DuplicateEnumCasesRule.swift index f28f9b2172..79840494ff 100644 --- a/Source/SwiftLintFramework/Rules/Lint/DuplicateEnumCasesRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/DuplicateEnumCasesRule.swift @@ -11,29 +11,29 @@ public struct DuplicateEnumCasesRule: ConfigurationProviderRule, ASTRule, Automa description: "Enum can't contain multiple cases with the same name.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" enum PictureImport { case addImage(image: UIImage) case addData(data: Data) } - """, - """ + """), + Example(""" enum A { case add(image: UIImage) } enum B { case add(image: UIImage) } - """ + """) ], triggeringExamples: [ - """ + Example(""" enum PictureImport { case ↓add(image: UIImage) case addURL(url: URL) case ↓add(data: Data) } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/DynamicInlineRule.swift b/Source/SwiftLintFramework/Rules/Lint/DynamicInlineRule.swift index 9b049c0b87..5580638312 100644 --- a/Source/SwiftLintFramework/Rules/Lint/DynamicInlineRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/DynamicInlineRule.swift @@ -12,16 +12,16 @@ public struct DynamicInlineRule: ASTRule, ConfigurationProviderRule, AutomaticTe description: "Avoid using 'dynamic' and '@inline(__always)' together.", kind: .lint, nonTriggeringExamples: [ - "class C {\ndynamic func f() {}}", - "class C {\n@inline(__always) func f() {}}", - "class C {\n@inline(never) dynamic func f() {}}" + Example("class C {\ndynamic func f() {}}"), + Example("class C {\n@inline(__always) func f() {}}"), + Example("class C {\n@inline(never) dynamic func f() {}}") ], triggeringExamples: [ - "class C {\n@inline(__always) dynamic ↓func f() {}\n}", - "class C {\n@inline(__always) public dynamic ↓func f() {}\n}", - "class C {\n@inline(__always) dynamic internal ↓func f() {}\n}", - "class C {\n@inline(__always)\ndynamic ↓func f() {}\n}", - "class C {\n@inline(__always)\ndynamic\n↓func f() {}\n}" + Example("class C {\n@inline(__always) dynamic ↓func f() {}\n}"), + Example("class C {\n@inline(__always) public dynamic ↓func f() {}\n}"), + Example("class C {\n@inline(__always) dynamic internal ↓func f() {}\n}"), + Example("class C {\n@inline(__always)\ndynamic ↓func f() {}\n}"), + Example("class C {\n@inline(__always)\ndynamic\n↓func f() {}\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/EmptyXCTestMethodRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/EmptyXCTestMethodRuleExamples.swift index 789599019e..e796a0365e 100644 --- a/Source/SwiftLintFramework/Rules/Lint/EmptyXCTestMethodRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/EmptyXCTestMethodRuleExamples.swift @@ -2,7 +2,7 @@ internal struct EmptyXCTestMethodRuleExamples { static let nonTriggeringExamples = [ // Valid XCTestCase class - """ + Example(""" class TotoTests: XCTestCase { var foobar: Foobar? @@ -28,11 +28,11 @@ internal struct EmptyXCTestMethodRuleExamples { // comment... } } - """, + """), // Not an XCTestCase class - """ + Example(""" class Foobar { func setUp() {} @@ -40,11 +40,11 @@ internal struct EmptyXCTestMethodRuleExamples { func testFoo() {} } - """, + """), // Methods with parameters - """ + Example(""" class TotoTests: XCTestCase { func setUp(with object: Foobar) {} @@ -54,23 +54,23 @@ internal struct EmptyXCTestMethodRuleExamples { func testBar(bar: (String) -> Int) {} } - """, + """), // Asserts in one line - """ + Example(""" class TotoTests: XCTestCase { func testFoo() { XCTAssertTrue(foobar?.foo) } func testBar() { XCTAssertFalse(foobar?.bar) } } - """ + """) ] static let triggeringExamples = [ // XCTestCase class with empty methods - """ + Example(""" class TotoTests: XCTestCase { override ↓func setUp() { } @@ -93,9 +93,9 @@ internal struct EmptyXCTestMethodRuleExamples { func helperFunction() { } } - """, + """), - """ + Example(""" class TotoTests: XCTestCase { override ↓func setUp() {} @@ -105,11 +105,11 @@ internal struct EmptyXCTestMethodRuleExamples { func helperFunction() {} } - """, + """), // XCTestCase class with comments (and blank lines) - """ + Example(""" class TotoTests: XCTestCase { override ↓func setUp() { // comment... @@ -141,11 +141,11 @@ internal struct EmptyXCTestMethodRuleExamples { func helperFunction() { } } - """, + """), // Two XCTestCase classes on the same file - """ + Example(""" class FooTests: XCTestCase { override ↓func setUp() {} } @@ -153,6 +153,6 @@ internal struct EmptyXCTestMethodRuleExamples { class BarTests: XCTestCase { ↓func testFoo() {} } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/ExpiringTodoRule.swift b/Source/SwiftLintFramework/Rules/Lint/ExpiringTodoRule.swift index 84017dfccc..8fc0153516 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ExpiringTodoRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ExpiringTodoRule.swift @@ -22,19 +22,19 @@ public struct ExpiringTodoRule: ConfigurationProviderRule, OptInRule { description: "TODOs and FIXMEs should be resolved prior to their expiry date.", kind: .lint, nonTriggeringExamples: [ - "// notaTODO:\n", - "// notaFIXME:\n", - "// TODO: [12/31/9999]\n", - "// TODO(note)\n", - "// FIXME(note)\n", - "/* FIXME: */\n", - "/* TODO: */\n", - "/** FIXME: */\n", - "/** TODO: */\n" + Example("// notaTODO:\n"), + Example("// notaFIXME:\n"), + Example("// TODO: [12/31/9999]\n"), + Example("// TODO(note)\n"), + Example("// FIXME(note)\n"), + Example("/* FIXME: */\n"), + Example("/* TODO: */\n"), + Example("/** FIXME: */\n"), + Example("/** TODO: */\n") ], triggeringExamples: [ - "// TODO: [10/14/2019]\n", - "// FIXME: [10/14/2019]\n" + Example("// TODO: [10/14/2019]\n"), + Example("// FIXME: [10/14/2019]\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/IdenticalOperandsRule.swift b/Source/SwiftLintFramework/Rules/Lint/IdenticalOperandsRule.swift index b3fe01e63f..1b0f4e45c4 100644 --- a/Source/SwiftLintFramework/Rules/Lint/IdenticalOperandsRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/IdenticalOperandsRule.swift @@ -15,44 +15,45 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom kind: .lint, nonTriggeringExamples: operators.flatMap { operation in [ - "1 \(operation) 2", - "foo \(operation) bar", - "prefixedFoo \(operation) foo", - "foo.aProperty \(operation) foo.anotherProperty", - "self.aProperty \(operation) self.anotherProperty", - "\"1 \(operation) 1\"", - "self.aProperty \(operation) aProperty", - "lhs.aProperty \(operation) rhs.aProperty", - "lhs.identifier \(operation) rhs.identifier", - "i \(operation) index", - "$0 \(operation) 0", - "keyValues?.count ?? 0 \(operation) 0", - "string \(operation) string.lowercased()", - """ + Example("1 \(operation) 2"), + Example("foo \(operation) bar"), + Example("prefixedFoo \(operation) foo"), + Example("foo.aProperty \(operation) foo.anotherProperty"), + Example("self.aProperty \(operation) self.anotherProperty"), + Example("\"1 \(operation) 1\""), + Example("self.aProperty \(operation) aProperty"), + Example("lhs.aProperty \(operation) rhs.aProperty"), + Example("lhs.identifier \(operation) rhs.identifier"), + Example("i \(operation) index"), + Example("$0 \(operation) 0"), + Example("keyValues?.count ?? 0 \(operation) 0"), + Example("string \(operation) string.lowercased()"), + Example(""" let num: Int? = 0 _ = num != nil && num \(operation) num?.byteSwapped - """, - "num \(operation) num!.byteSwapped" + """), + Example("num \(operation) num!.byteSwapped") ] } + [ - "func evaluate(_ mode: CommandMode) -> Result>>", - "let array = Array>()", - "guard Set(identifiers).count != identifiers.count else { return }", - #"expect("foo") == "foo""#, - "type(of: model).cachePrefix == cachePrefix", - "histogram[156].0 == 0x003B8D96 && histogram[156].1 == 1" + // swiftlint:disable:next line_length + Example("func evaluate(_ mode: CommandMode) -> Result>>"), + Example("let array = Array>()"), + Example("guard Set(identifiers).count != identifiers.count else { return }"), + Example(#"expect("foo") == "foo""#), + Example("type(of: model).cachePrefix == cachePrefix"), + Example("histogram[156].0 == 0x003B8D96 && histogram[156].1 == 1") ], triggeringExamples: operators.flatMap { operation in [ - "↓1 \(operation) 1", - "↓foo \(operation) foo", - "↓foo.aProperty \(operation) foo.aProperty", - "↓self.aProperty \(operation) self.aProperty", - "↓$0 \(operation) $0", - "↓a?.b \(operation) a?.b", - "if (↓elem \(operation) elem) {}", - "XCTAssertTrue(↓s3 \(operation) s3)", - "if let tab = tabManager.selectedTab, ↓tab.webView \(operation) tab.webView" + Example("↓1 \(operation) 1"), + Example("↓foo \(operation) foo"), + Example("↓foo.aProperty \(operation) foo.aProperty"), + Example("↓self.aProperty \(operation) self.aProperty"), + Example("↓$0 \(operation) $0"), + Example("↓a?.b \(operation) a?.b"), + Example("if (↓elem \(operation) elem) {}"), + Example("XCTAssertTrue(↓s3 \(operation) s3)"), + Example("if let tab = tabManager.selectedTab, ↓tab.webView \(operation) tab.webView") ] } ) diff --git a/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift b/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift index 2be5615fdd..c520f582f5 100644 --- a/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift @@ -12,42 +12,42 @@ public struct InertDeferRule: ConfigurationProviderRule, AutomaticTestableRule { description: "If defer is at the end of its parent scope, it will be executed right where it is anyway.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" func example3() { defer { /* deferred code */ } print("other code") } - """, - """ + """), + Example(""" func example4() { if condition { defer { /* deferred code */ } print("other code") } } - """ + """) ], triggeringExamples: [ - """ + Example(""" func example0() { ↓defer { /* deferred code */ } } - """, - """ + """), + Example(""" func example1() { ↓defer { /* deferred code */ } // comment } - """, - """ + """), + Example(""" func example2() { if condition { ↓defer { /* deferred code */ } // comment } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/LowerACLThanParentRule.swift b/Source/SwiftLintFramework/Rules/Lint/LowerACLThanParentRule.swift index b5ad9c4609..fd32e98a99 100644 --- a/Source/SwiftLintFramework/Rules/Lint/LowerACLThanParentRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/LowerACLThanParentRule.swift @@ -11,24 +11,24 @@ public struct LowerACLThanParentRule: OptInRule, ConfigurationProviderRule, Auto description: "Ensure definitions have a lower access control level than their enclosing parent", kind: .lint, nonTriggeringExamples: [ - "public struct Foo { public func bar() {} }", - "internal struct Foo { func bar() {} }", - "struct Foo { func bar() {} }", - "open class Foo { public func bar() {} }", - "open class Foo { open func bar() {} }", - "fileprivate struct Foo { private func bar() {} }", - "private struct Foo { private func bar(id: String) }", - "extension Foo { public func bar() {} }", - "private struct Foo { fileprivate func bar() {} }", - "private func foo(id: String) {}", - "private class Foo { func bar() {} }" + Example("public struct Foo { public func bar() {} }"), + Example("internal struct Foo { func bar() {} }"), + Example("struct Foo { func bar() {} }"), + Example("open class Foo { public func bar() {} }"), + Example("open class Foo { open func bar() {} }"), + Example("fileprivate struct Foo { private func bar() {} }"), + Example("private struct Foo { private func bar(id: String) }"), + Example("extension Foo { public func bar() {} }"), + Example("private struct Foo { fileprivate func bar() {} }"), + Example("private func foo(id: String) {}"), + Example("private class Foo { func bar() {} }") ], triggeringExamples: [ - "struct Foo { public ↓func bar() {} }", - "enum Foo { public ↓func bar() {} }", - "public class Foo { open ↓func bar() }", - "class Foo { public private(set) ↓var bar: String? }", - "private class Foo { internal ↓func bar() {} }" + Example("struct Foo { public ↓func bar() {} }"), + Example("enum Foo { public ↓func bar() {} }"), + Example("public class Foo { open ↓func bar() }"), + Example("class Foo { public private(set) ↓var bar: String? }"), + Example("private class Foo { internal ↓func bar() {} }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/MarkRule.swift b/Source/SwiftLintFramework/Rules/Lint/MarkRule.swift index 58c86f764d..4dd16ef743 100644 --- a/Source/SwiftLintFramework/Rules/Lint/MarkRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/MarkRule.swift @@ -12,58 +12,58 @@ public struct MarkRule: CorrectableRule, ConfigurationProviderRule { description: "MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'", kind: .lint, nonTriggeringExamples: [ - "// MARK: good\n", - "// MARK: - good\n", - "// MARK: -\n", - "// BOOKMARK", - "//BOOKMARK", - "// BOOKMARKS" + Example("// MARK: good\n"), + Example("// MARK: - good\n"), + Example("// MARK: -\n"), + Example("// BOOKMARK"), + Example("//BOOKMARK"), + Example("// BOOKMARKS") ], triggeringExamples: [ - "↓//MARK: bad", - "↓// MARK:bad", - "↓//MARK:bad", - "↓// MARK: bad", - "↓// MARK: bad", - "↓// MARK: -bad", - "↓// MARK:- bad", - "↓// MARK:-bad", - "↓//MARK: - bad", - "↓//MARK:- bad", - "↓//MARK: -bad", - "↓//MARK:-bad", - "↓//Mark: bad", - "↓// Mark: bad", - "↓// MARK bad", - "↓//MARK bad", - "↓// MARK - bad", - "↓//MARK : bad", - "↓// MARKL:", - "↓// MARKR ", - "↓// MARKK -", - "↓/// MARK:", - "↓/// MARK bad", + Example("↓//MARK: bad"), + Example("↓// MARK:bad"), + Example("↓//MARK:bad"), + Example("↓// MARK: bad"), + Example("↓// MARK: bad"), + Example("↓// MARK: -bad"), + Example("↓// MARK:- bad"), + Example("↓// MARK:-bad"), + Example("↓//MARK: - bad"), + Example("↓//MARK:- bad"), + Example("↓//MARK: -bad"), + Example("↓//MARK:-bad"), + Example("↓//Mark: bad"), + Example("↓// Mark: bad"), + Example("↓// MARK bad"), + Example("↓//MARK bad"), + Example("↓// MARK - bad"), + Example("↓//MARK : bad"), + Example("↓// MARKL:"), + Example("↓// MARKR "), + Example("↓// MARKK -"), + Example("↓/// MARK:"), + Example("↓/// MARK bad"), issue1029Example ], corrections: [ - "↓//MARK: comment": "// MARK: comment", - "↓// MARK: comment": "// MARK: comment", - "↓// MARK:comment": "// MARK: comment", - "↓// MARK: comment": "// MARK: comment", - "↓//MARK: - comment": "// MARK: - comment", - "↓// MARK:- comment": "// MARK: - comment", - "↓// MARK: -comment": "// MARK: - comment", - "↓// MARK: - comment": "// MARK: - comment", - "↓// Mark: comment": "// MARK: comment", - "↓// Mark: - comment": "// MARK: - comment", - "↓// MARK - comment": "// MARK: - comment", - "↓// MARK : comment": "// MARK: comment", - "↓// MARKL:": "// MARK:", - "↓// MARKL: -": "// MARK: -", - "↓// MARKK ": "// MARK: ", - "↓// MARKK -": "// MARK: -", - "↓/// MARK:": "// MARK:", - "↓/// MARK comment": "// MARK: comment", + Example("↓//MARK: comment"): Example("// MARK: comment"), + Example("↓// MARK: comment"): Example("// MARK: comment"), + Example("↓// MARK:comment"): Example("// MARK: comment"), + Example("↓// MARK: comment"): Example("// MARK: comment"), + Example("↓//MARK: - comment"): Example("// MARK: - comment"), + Example("↓// MARK:- comment"): Example("// MARK: - comment"), + Example("↓// MARK: -comment"): Example("// MARK: - comment"), + Example("↓// MARK: - comment"): Example("// MARK: - comment"), + Example("↓// Mark: comment"): Example("// MARK: comment"), + Example("↓// Mark: - comment"): Example("// MARK: - comment"), + Example("↓// MARK - comment"): Example("// MARK: - comment"), + Example("↓// MARK : comment"): Example("// MARK: comment"), + Example("↓// MARKL:"): Example("// MARK:"), + Example("↓// MARKL: -"): Example("// MARK: -"), + Example("↓// MARKK "): Example("// MARK: "), + Example("↓// MARKK -"): Example("// MARK: -"), + Example("↓/// MARK:"): Example("// MARK:"), + Example("↓/// MARK comment"): Example("// MARK: comment"), issue1029Example: issue1029Correction ] ) @@ -196,17 +196,21 @@ public struct MarkRule: CorrectableRule, ConfigurationProviderRule { } } -private let issue1029Example = "↓//MARK:- Top-Level bad mark\n" + - "↓//MARK:- Another bad mark\n" + - "struct MarkTest {}\n" + - "↓// MARK:- Bad mark\n" + - "extension MarkTest {}\n" - -private let issue1029Correction = "// MARK: - Top-Level bad mark\n" + - "// MARK: - Another bad mark\n" + - "struct MarkTest {}\n" + - "// MARK: - Bad mark\n" + - "extension MarkTest {}\n" +private let issue1029Example = Example(""" + ↓//MARK:- Top-Level bad mark + ↓//MARK:- Another bad mark + struct MarkTest {} + ↓// MARK:- Bad mark + extension MarkTest {} + """) + +private let issue1029Correction = Example(""" + // MARK: - Top-Level bad mark + // MARK: - Another bad mark + struct MarkTest {} + // MARK: - Bad mark + extension MarkTest {} + """) // These need to be at the bottom of the file to work around https://bugs.swift.org/browse/SR-10486 diff --git a/Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift b/Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift index 9127768593..75c8037eae 100644 --- a/Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift @@ -46,31 +46,52 @@ public struct MissingDocsRule: OptInRule, ConfigurationProviderRule, AutomaticTe minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ // locally-defined superclass member is documented, but subclass member is not - "/// docs\npublic class A {\n/// docs\npublic func b() {}\n}\n" + - "/// docs\npublic class B: A { override public func b() {} }\n", + Example(""" + /// docs + public class A { + /// docs + public func b() {} + } + /// docs + public class B: A { override public func b() {} } + """), // externally-defined superclass member is documented, but subclass member is not - "import Foundation\n/// docs\npublic class B: NSObject {\n" + - "// no docs\noverride public var description: String { fatalError() } }\n", - """ + Example(""" + import Foundation + /// docs + public class B: NSObject { + // no docs + override public var description: String { fatalError() } } + """), + Example(""" /// docs public class A { deinit {} } - """, - """ + """), + Example(""" public extension A {} - """ + """) ], triggeringExamples: [ // public, undocumented - "public func a() {}\n", + Example("public func a() {}\n"), // public, undocumented - "// regular comment\npublic func a() {}\n", + Example("// regular comment\npublic func a() {}\n"), // public, undocumented - "/* regular comment */\npublic func a() {}\n", + Example("/* regular comment */\npublic func a() {}\n"), // protocol member and inherited member are both undocumented - "/// docs\npublic protocol A {\n// no docs\nvar b: Int { get } }\n" + - "/// docs\npublic struct C: A {\n\npublic let b: Int\n}" + Example(""" + /// docs + public protocol A { + // no docs + var b: Int { get } } + /// docs + public struct C: A { + + public let b: Int + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringKeyRule.swift b/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringKeyRule.swift index 90a4b14233..3515dee3cc 100644 --- a/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringKeyRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringKeyRule.swift @@ -11,12 +11,12 @@ public struct NSLocalizedStringKeyRule: ASTRule, OptInRule, ConfigurationProvide description: "Static strings should be used as key in NSLocalizedString in order to genstrings work.", kind: .lint, nonTriggeringExamples: [ - "NSLocalizedString(\"key\", comment: nil)", - "NSLocalizedString(\"key\" + \"2\", comment: nil)" + Example("NSLocalizedString(\"key\", comment: nil)"), + Example("NSLocalizedString(\"key\" + \"2\", comment: nil)") ], triggeringExamples: [ - "NSLocalizedString(↓method(), comment: nil)", - "NSLocalizedString(↓\"key_\\(param)\", comment: nil)" + Example("NSLocalizedString(↓method(), comment: nil)"), + Example("NSLocalizedString(↓\"key_\\(param)\", comment: nil)") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringRequireBundleRule.swift b/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringRequireBundleRule.swift index 042df5b642..e54a082a67 100644 --- a/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringRequireBundleRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/NSLocalizedStringRequireBundleRule.swift @@ -9,34 +9,34 @@ public struct NSLocalizedStringRequireBundleRule: ASTRule, OptInRule, Configurat description: "Calls to NSLocalizedString should specify the bundle which contains the strings file.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" NSLocalizedString("someKey", bundle: .main, comment: "test") - """, - """ + """), + Example(""" NSLocalizedString("someKey", tableName: "a", bundle: Bundle(for: A.self), comment: "test") - """, - """ + """), + Example(""" NSLocalizedString("someKey", tableName: "xyz", bundle: someBundle, value: "test" comment: "test") - """, - """ + """), + Example(""" arbitraryFunctionCall("something") - """ + """) ], triggeringExamples: [ - """ + Example(""" ↓NSLocalizedString("someKey", comment: "test") - """, - """ + """), + Example(""" ↓NSLocalizedString("someKey", tableName: "a", comment: "test") - """, - """ + """), + Example(""" ↓NSLocalizedString("someKey", tableName: "xyz", value: "test", comment: "test") - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/NSObjectPreferIsEqualRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/NSObjectPreferIsEqualRuleExamples.swift index 331a1ce0cd..e04adec8e6 100644 --- a/Source/SwiftLintFramework/Rules/Lint/NSObjectPreferIsEqualRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/NSObjectPreferIsEqualRuleExamples.swift @@ -1,99 +1,99 @@ internal struct NSObjectPreferIsEqualRuleExamples { - static let nonTriggeringExamples: [String] = [ + static let nonTriggeringExamples: [Example] = [ // NSObject subclass without == - """ + Example(""" class AClass: NSObject { } - """, + """), // @objc class without == - """ + Example(""" @objc class AClass: SomeNSObjectSubclass { } - """, + """), // Class with == which does not subclass NSObject - """ + Example(""" class AClass: Equatable { static func ==(lhs: AClass, rhs: AClass) -> Bool { return true } - """, + """), // NSObject subclass implementing isEqual - """ + Example(""" class AClass: NSObject { override func isEqual(_ object: Any?) -> Bool { return true } } - """, + """), // @objc class implementing isEqual - """ + Example(""" @objc class AClass: SomeNSObjectSubclass { override func isEqual(_ object: Any?) -> Bool { return false } } - """, + """), // NSObject subclass with non-static == - """ + Example(""" class AClass: NSObject { func ==(lhs: AClass, rhs: AClass) -> Bool { return true } } - """, + """), // NSObject subclass implementing == with different signature - """ + Example(""" class AClass: NSObject { static func ==(lhs: AClass, rhs: BClass) -> Bool { return true } } - """, + """), // Equatable struct - """ + Example(""" struct AStruct: Equatable { static func ==(lhs: AStruct, rhs: AStruct) -> Bool { return false } } - """, + """), // Equatable enum - """ + Example(""" enum AnEnum: Equatable { static func ==(lhs: AnEnum, rhs: AnEnum) -> Bool { return true } } - """ + """) ] - static let triggeringExamples: [String] = [ + static let triggeringExamples: [Example] = [ // NSObject subclass implementing == - """ + Example(""" class AClass: NSObject { ↓static func ==(lhs: AClass, rhs: AClass) -> Bool { return false } } - """, + """), // @objc class implementing == - """ + Example(""" @objc class AClass: SomeOtherNSObjectSubclass { ↓static func ==(lhs: AClass, rhs: AClass) -> Bool { return true } } - """, + """), // Equatable NSObject subclass implementing == - """ + Example(""" class AClass: NSObject, Equatable { ↓static func ==(lhs: AClass, rhs: AClass) -> Bool { return false } } - """, + """), // NSObject subclass overriding isEqual and implementing == - """ + Example(""" class AClass: NSObject { override func isEqual(_ object: Any?) -> Bool { guard let other = object as? AClass else { @@ -106,6 +106,6 @@ internal struct NSObjectPreferIsEqualRuleExamples { return false } } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/NotificationCenterDetachmentRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/NotificationCenterDetachmentRuleExamples.swift index b040009ddd..bd1b60ab0e 100644 --- a/Source/SwiftLintFramework/Rules/Lint/NotificationCenterDetachmentRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/NotificationCenterDetachmentRuleExamples.swift @@ -1,23 +1,28 @@ internal struct NotificationCenterDetachmentRuleExamples { static let nonTriggeringExamples = [ - "class Foo { \n" + - " deinit {\n" + - " NotificationCenter.default.removeObserver(self)\n" + - " }\n" + - "}\n", - - "class Foo { \n" + - " func bar() {\n" + - " NotificationCenter.default.removeObserver(otherObject)\n" + - " }\n" + - "}\n" + Example(""" + class Foo { + deinit { + NotificationCenter.default.removeObserver(self) + } + } + """), + Example(""" + class Foo { + func bar() { + NotificationCenter.default.removeObserver(otherObject) + } + } + """) ] static let triggeringExamples = [ - "class Foo { \n" + - " func bar() {\n" + - " ↓NotificationCenter.default.removeObserver(self)\n" + - " }\n" + - "}\n" + Example(""" + class Foo { + func bar() { + ↓NotificationCenter.default.removeObserver(self) + } + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/OrphanedDocCommentRule.swift b/Source/SwiftLintFramework/Rules/Lint/OrphanedDocCommentRule.swift index a80b99fa44..769ee44c7e 100644 --- a/Source/SwiftLintFramework/Rules/Lint/OrphanedDocCommentRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/OrphanedDocCommentRule.swift @@ -13,38 +13,38 @@ public struct OrphanedDocCommentRule: ConfigurationProviderRule { kind: .lint, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - """ + Example(""" /// My great property var myGreatProperty: String! - """, - """ + """), + Example(""" ////////////////////////////////////// // // Copyright header. // ////////////////////////////////////// - """, - """ + """), + Example(""" /// Look here for more info: https://github.com. var myGreatProperty: String! - """, - """ + """), + Example(""" /// Look here for more info: /// https://github.com. var myGreatProperty: String! - """ + """) ], triggeringExamples: [ - """ + Example(""" ↓/// My great property // Not a doc string var myGreatProperty: String! - """, - """ + """), + Example(""" ↓/// Look here for more info: https://github.com. // Not a doc string var myGreatProperty: String! - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/OverriddenSuperCallRule.swift b/Source/SwiftLintFramework/Rules/Lint/OverriddenSuperCallRule.swift index 9375061229..573a3b48a8 100644 --- a/Source/SwiftLintFramework/Rules/Lint/OverriddenSuperCallRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/OverriddenSuperCallRule.swift @@ -11,52 +11,68 @@ public struct OverriddenSuperCallRule: ConfigurationProviderRule, ASTRule, OptIn description: "Some overridden methods should always call super", kind: .lint, nonTriggeringExamples: [ - "class VC: UIViewController {\n" + - "\toverride func viewWillAppear(_ animated: Bool) {\n" + - "\t\tsuper.viewWillAppear(animated)\n" + - "\t}\n" + - "}\n", - "class VC: UIViewController {\n" + - "\toverride func viewWillAppear(_ animated: Bool) {\n" + - "\t\tself.method1()\n" + - "\t\tsuper.viewWillAppear(animated)\n" + - "\t\tself.method2()\n" + - "\t}\n" + - "}\n", - "class VC: UIViewController {\n" + - "\toverride func loadView() {\n" + - "\t}\n" + - "}\n", - "class Some {\n" + - "\tfunc viewWillAppear(_ animated: Bool) {\n" + - "\t}\n" + - "}\n", - "class VC: UIViewController {\n" + - "\toverride func viewDidLoad() {\n" + - "\t\tdefer {\n" + - "\t\t\tsuper.viewDidLoad()\n" + - "\t\t}\n" + - "\t}\n" + - "}\n" + Example(""" + class VC: UIViewController { + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + } + """), + Example(""" + class VC: UIViewController { + override func viewWillAppear(_ animated: Bool) { + self.method1() + super.viewWillAppear(animated) + self.method2() + } + } + """), + Example(""" + class VC: UIViewController { + override func loadView() { + } + } + """), + Example(""" + class Some { + func viewWillAppear(_ animated: Bool) { + } + } + """), + Example(""" + class VC: UIViewController { + override func viewDidLoad() { + defer { + super.viewDidLoad() + } + } + } + """) ], triggeringExamples: [ - "class VC: UIViewController {\n" + - "\toverride func viewWillAppear(_ animated: Bool) {↓\n" + - "\t\t//Not calling to super\n" + - "\t\tself.method()\n" + - "\t}\n" + - "}\n", - "class VC: UIViewController {\n" + - "\toverride func viewWillAppear(_ animated: Bool) {↓\n" + - "\t\tsuper.viewWillAppear(animated)\n" + - "\t\t//Other code\n" + - "\t\tsuper.viewWillAppear(animated)\n" + - "\t}\n" + - "}\n", - "class VC: UIViewController {\n" + - "\toverride func didReceiveMemoryWarning() {↓\n" + - "\t}\n" + - "}\n" + Example(""" + class VC: UIViewController { + override func viewWillAppear(_ animated: Bool) {↓ + //Not calling to super + self.method() + } + } + """), + Example(""" + class VC: UIViewController { + override func viewWillAppear(_ animated: Bool) {↓ + super.viewWillAppear(animated) + //Other code + super.viewWillAppear(animated) + } + } + """), + Example(""" + class VC: UIViewController { + override func didReceiveMemoryWarning() {↓ + } + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/OverrideInExtensionRule.swift b/Source/SwiftLintFramework/Rules/Lint/OverrideInExtensionRule.swift index ce7068f900..c2d3abfc59 100644 --- a/Source/SwiftLintFramework/Rules/Lint/OverrideInExtensionRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/OverrideInExtensionRule.swift @@ -11,23 +11,27 @@ public struct OverrideInExtensionRule: ConfigurationProviderRule, OptInRule, Aut description: "Extensions shouldn't override declarations.", kind: .lint, nonTriggeringExamples: [ - "extension Person {\n var age: Int { return 42 }\n}\n", - "extension Person {\n func celebrateBirthday() {}\n}\n", - "class Employee: Person {\n override func celebrateBirthday() {}\n}\n", - "class Foo: NSObject {}\n" + - "extension Foo {\n" + - " override var description: String { return \"\" }\n" + - "}\n", - "struct Foo {\n" + - " class Bar: NSObject {}\n" + - "}\n" + - "extension Foo.Bar {\n" + - " override var description: String { return \"\" }\n" + - "}\n" + Example("extension Person {\n var age: Int { return 42 }\n}\n"), + Example("extension Person {\n func celebrateBirthday() {}\n}\n"), + Example("class Employee: Person {\n override func celebrateBirthday() {}\n}\n"), + Example(""" + class Foo: NSObject {} + extension Foo { + override var description: String { return "" } + } + """), + Example(""" + struct Foo { + class Bar: NSObject {} + } + extension Foo.Bar { + override var description: String { return "" } + } + """) ], triggeringExamples: [ - "extension Person {\n override ↓var age: Int { return 42 }\n}\n", - "extension Person {\n override ↓func celebrateBirthday() {}\n}\n" + Example("extension Person {\n override ↓var age: Int { return 42 }\n}\n"), + Example("extension Person {\n override ↓func celebrateBirthday() {}\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/PrivateActionRule.swift b/Source/SwiftLintFramework/Rules/Lint/PrivateActionRule.swift index ce7911ce2f..832ab3294a 100644 --- a/Source/SwiftLintFramework/Rules/Lint/PrivateActionRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/PrivateActionRule.swift @@ -11,25 +11,25 @@ public struct PrivateActionRule: ASTRule, OptInRule, ConfigurationProviderRule, description: "IBActions should be private.", kind: .lint, nonTriggeringExamples: [ - "class Foo {\n\t@IBAction private func barButtonTapped(_ sender: UIButton) {}\n}\n", - "struct Foo {\n\t@IBAction private func barButtonTapped(_ sender: UIButton) {}\n}\n", - "class Foo {\n\t@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}\n}\n", - "struct Foo {\n\t@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}\n}\n", - "private extension Foo {\n\t@IBAction func barButtonTapped(_ sender: UIButton) {}\n}\n", - "fileprivate extension Foo {\n\t@IBAction func barButtonTapped(_ sender: UIButton) {}\n}\n" + Example("class Foo {\n\t@IBAction private func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("struct Foo {\n\t@IBAction private func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("class Foo {\n\t@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("struct Foo {\n\t@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("private extension Foo {\n\t@IBAction func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("fileprivate extension Foo {\n\t@IBAction func barButtonTapped(_ sender: UIButton) {}\n}\n") ], triggeringExamples: [ - "class Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "struct Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "class Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "struct Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "class Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "struct Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "extension Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "extension Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "public extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n", - "internal extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n" + Example("class Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("struct Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("class Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("struct Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("class Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("struct Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("extension Foo {\n\t@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("extension Foo {\n\t@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("public extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n"), + Example("internal extension Foo {\n\t@IBAction ↓func barButtonTapped(_ sender: UIButton) {}\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/PrivateOutletRule.swift b/Source/SwiftLintFramework/Rules/Lint/PrivateOutletRule.swift index eca923c0e1..1d03418369 100644 --- a/Source/SwiftLintFramework/Rules/Lint/PrivateOutletRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/PrivateOutletRule.swift @@ -11,15 +11,15 @@ public struct PrivateOutletRule: ASTRule, OptInRule, ConfigurationProviderRule { description: "IBOutlets should be private to avoid leaking UIKit to higher layers.", kind: .lint, nonTriggeringExamples: [ - "class Foo {\n @IBOutlet private var label: UILabel?\n}\n", - "class Foo {\n @IBOutlet private var label: UILabel!\n}\n", - "class Foo {\n var notAnOutlet: UILabel\n}\n", - "class Foo {\n @IBOutlet weak private var label: UILabel?\n}\n", - "class Foo {\n @IBOutlet private weak var label: UILabel?\n}\n" + Example("class Foo {\n @IBOutlet private var label: UILabel?\n}\n"), + Example("class Foo {\n @IBOutlet private var label: UILabel!\n}\n"), + Example("class Foo {\n var notAnOutlet: UILabel\n}\n"), + Example("class Foo {\n @IBOutlet weak private var label: UILabel?\n}\n"), + Example("class Foo {\n @IBOutlet private weak var label: UILabel?\n}\n") ], triggeringExamples: [ - "class Foo {\n @IBOutlet ↓var label: UILabel?\n}\n", - "class Foo {\n @IBOutlet ↓var label: UILabel!\n}\n" + Example("class Foo {\n @IBOutlet ↓var label: UILabel?\n}\n"), + Example("class Foo {\n @IBOutlet ↓var label: UILabel!\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/PrivateUnitTestRule.swift b/Source/SwiftLintFramework/Rules/Lint/PrivateUnitTestRule.swift index 5993862c03..c8f5007be6 100644 --- a/Source/SwiftLintFramework/Rules/Lint/PrivateUnitTestRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/PrivateUnitTestRule.swift @@ -39,67 +39,89 @@ public struct PrivateUnitTestRule: ASTRule, ConfigurationProviderRule, CacheDesc description: "Unit tests marked private are silently skipped.", kind: .lint, nonTriggeringExamples: [ - "class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", - "internal class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", - "public class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", - "@objc private class FooTest: XCTestCase { " + - "@objc private func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", + Example(""" + "class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + } + """), + Example(""" + internal class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + } + """), + Example(""" + public class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + } + """), + Example(""" + @objc private class FooTest: XCTestCase { + @objc private func test1() {} + internal func test2() {} + public func test3() {} + } + """), // Non-test classes - "private class Foo: NSObject { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", - "private class Foo { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "}", + Example(""" + private class Foo: NSObject { + func test1() {} + internal func test2() {} + public func test3() {} + } + """), + Example(""" + private class Foo { + func test1() {} + internal func test2() {} + public func test3() {} + } + """), // Methods with params - "public class FooTest: XCTestCase { " + - "func test1(param: Int) {}\n " + - "}" + Example(""" + public class FooTest: XCTestCase { + func test1(param: Int) {} + } + """) ], triggeringExamples: [ - "private ↓class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "private func test4() {}\n " + - "}", - "class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "private ↓func test4() {}\n " + - "}", - "internal class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "private ↓func test4() {}\n " + - "}", - "public class FooTest: XCTestCase { " + - "func test1() {}\n " + - "internal func test2() {}\n " + - "public func test3() {}\n " + - "private ↓func test4() {}\n " + - "}" + Example(""" + private ↓class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + private func test4() {} + } + """), + Example(""" + class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + private ↓func test4() {} + } + """), + Example(""" + internal class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + private ↓func test4() {} + } + """), + Example(""" + public class FooTest: XCTestCase { + func test1() {} + internal func test2() {} + public func test3() {} + private ↓func test4() {} + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/ProhibitedInterfaceBuilderRule.swift b/Source/SwiftLintFramework/Rules/Lint/ProhibitedInterfaceBuilderRule.swift index 03541cd8aa..dae73da824 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ProhibitedInterfaceBuilderRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ProhibitedInterfaceBuilderRule.swift @@ -11,13 +11,13 @@ public struct ProhibitedInterfaceBuilderRule: ConfigurationProviderRule, ASTRule description: "Creating views using Interface Builder should be avoided.", kind: .lint, nonTriggeringExamples: [ - "var label: UILabel!", - "@objc func buttonTapped(_ sender: UIButton) {}" - ].map(wrapExample), + wrapExample("var label: UILabel!"), + wrapExample("@objc func buttonTapped(_ sender: UIButton) {}") + ], triggeringExamples: [ - "@IBOutlet ↓var label: UILabel!", - "@IBAction ↓func buttonTapped(_ sender: UIButton) {}" - ].map(wrapExample) + wrapExample("@IBOutlet ↓var label: UILabel!"), + wrapExample("@IBAction ↓func buttonTapped(_ sender: UIButton) {}") + ] ) public func validate(file: SwiftLintFile, kind: SwiftDeclarationKind, @@ -44,10 +44,10 @@ public struct ProhibitedInterfaceBuilderRule: ConfigurationProviderRule, ASTRule } } -private func wrapExample(_ text: String) -> String { - return """ +private func wrapExample(_ text: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" class ViewController: UIViewController { \(text) } - """ + """, file: file, line: line) } diff --git a/Source/SwiftLintFramework/Rules/Lint/ProhibitedSuperRule.swift b/Source/SwiftLintFramework/Rules/Lint/ProhibitedSuperRule.swift index 766134f887..c0bf1a7a41 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ProhibitedSuperRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ProhibitedSuperRule.swift @@ -11,20 +11,20 @@ public struct ProhibitedSuperRule: ConfigurationProviderRule, ASTRule, OptInRule description: "Some methods should not call super", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" class VC: UIViewController { override func loadView() { } } - """, - """ + """), + Example(""" class NSView { func updateLayer() { self.method1() } } - """, - """ + """), + Example(""" public class FileProviderExtension: NSFileProviderExtension { override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) { guard let identifier = persistentIdentifierForItem(at: url) else { @@ -33,25 +33,25 @@ public struct ProhibitedSuperRule: ConfigurationProviderRule, ASTRule, OptInRule } } } - """ + """) ], triggeringExamples: [ - """ + Example(""" class VC: UIViewController { override func loadView() {↓ super.loadView() } } - """, - """ + """), + Example(""" class VC: NSFileProviderExtension { override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {↓ self.method1() super.providePlaceholder(at:url, completionHandler: completionHandler) } } - """, - """ + """), + Example(""" class VC: NSView { override func updateLayer() {↓ self.method1() @@ -59,8 +59,8 @@ public struct ProhibitedSuperRule: ConfigurationProviderRule, ASTRule, OptInRule self.method2() } } - """, - """ + """), + Example(""" class VC: NSView { override func updateLayer() {↓ defer { @@ -68,7 +68,7 @@ public struct ProhibitedSuperRule: ConfigurationProviderRule, ASTRule, OptInRule } } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedCallRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedCallRuleExamples.swift index cc60f7dfde..842258b27a 100644 --- a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedCallRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedCallRuleExamples.swift @@ -1,235 +1,283 @@ // swiftlint:disable type_body_length internal struct QuickDiscouragedCallRuleExamples { - static let nonTriggeringExamples: [String] = [ - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " beforeEach {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " beforeEach {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " afterEach {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " describe(\"bar\") {\n" + - " }\n" + - " context(\"bar\") {\n" + - " }\n" + - " it(\"bar\") {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " itBehavesLike(\"bar\")\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " it(\"does something\") {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " context(\"foo\") {\n" + - " afterEach { toto.append(foo) }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " xcontext(\"foo\") {\n" + - " afterEach { toto.append(foo) }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " xdescribe(\"foo\") {\n" + - " afterEach { toto.append(foo) }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " xit(\"does something\") {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " fcontext(\"foo\") {\n" + - " afterEach { toto.append(foo) }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " fdescribe(\"foo\") {\n" + - " afterEach { toto.append(foo) }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " fit(\"does something\") {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " fitBehavesLike(\"foo\")\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " xitBehavesLike(\"foo\")\n" + - " }\n" + - "}\n" + static let nonTriggeringExamples: [Example] = [ + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + beforeEach { + let foo = Foo() + foo.toto() + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + beforeEach { + let foo = Foo() + foo.toto() + } + afterEach { + let foo = Foo() + foo.toto() + } + describe("bar") { + } + context("bar") { + } + it("bar") { + let foo = Foo() + foo.toto() + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + itBehavesLike("bar") + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + it("does something") { + let foo = Foo() + foo.toto() + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + context("foo") { + afterEach { toto.append(foo) } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + xcontext("foo") { + afterEach { toto.append(foo) } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + xdescribe("foo") { + afterEach { toto.append(foo) } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + xit("does something") { + let foo = Foo() + foo.toto() + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + fcontext("foo") { + afterEach { toto.append(foo) } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + fdescribe("foo") { + afterEach { toto.append(foo) } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + fit("does something") { + let foo = Foo() + foo.toto() + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + fitBehavesLike("foo") + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + xitBehavesLike("foo") + } + } + """) ] - static let triggeringExamples: [String] = [ - "class TotoTests {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " let foo = Foo()\n" + - " }\n" + - " }\n" + - "}\n" + - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " context(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " context(\"bar\") {\n" + - " let foo = ↓Foo()\n" + - " ↓foo.bar()\n" + - " it(\"does something\") {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " context(\"foo\") {\n" + - " context(\"foo\") {\n" + - " beforeEach {\n" + - " let foo = Foo()\n" + - " foo.toto()\n" + - " }\n" + - " it(\"bar\") {\n" + - " }\n" + - " context(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " context(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " sharedExamples(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " ↓foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " context(\"foo\") {\n" + - " ↓foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " sharedExamples(\"foo\") {\n" + - " ↓foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " xdescribe(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " fdescribe(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " xcontext(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " fcontext(\"foo\") {\n" + - " let foo = ↓Foo()\n" + - " }\n" + - " }\n" + - "}\n" + static let triggeringExamples: [Example] = [ + Example(""" + class TotoTests { + override func spec() { + describe("foo") { + let foo = Foo() + } + } + } + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + let foo = ↓Foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + let foo = ↓Foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + context("foo") { + let foo = ↓Foo() + } + context("bar") { + let foo = ↓Foo() + ↓foo.bar() + it("does something") { + let foo = Foo() + foo.toto() + } + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + context("foo") { + context("foo") { + beforeEach { + let foo = Foo() + foo.toto() + } + it("bar") { + } + context("foo") { + let foo = ↓Foo() + } + } + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + context("foo") { + let foo = ↓Foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + sharedExamples("foo") { + let foo = ↓Foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + ↓foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + context("foo") { + ↓foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + sharedExamples("foo") { + ↓foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + xdescribe("foo") { + let foo = ↓Foo() + } + fdescribe("foo") { + let foo = ↓Foo() + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + xcontext("foo") { + let foo = ↓Foo() + } + fcontext("foo") { + let foo = ↓Foo() + } + } + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedFocusedTestRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedFocusedTestRuleExamples.swift index bd77e3dbe6..47ddfde032 100644 --- a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedFocusedTestRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedFocusedTestRuleExamples.swift @@ -1,62 +1,78 @@ internal struct QuickDiscouragedFocusedTestRuleExamples { static let nonTriggeringExamples = [ - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " describe(\"bar\") { } \n" + - " context(\"bar\") {\n" + - " it(\"bar\") { }\n" + - " }\n" + - " it(\"bar\") { }\n" + - " itBehavesLike(\"bar\")\n" + - " }\n" + - " }\n" + - "}\n" + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + describe("bar") { } + context("bar") { + it("bar") { } + } + it("bar") { } + itBehavesLike("bar") + } + } + } + """) ] static let triggeringExamples = [ - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓fdescribe(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓fcontext(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓fit(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " ↓fit(\"bar\") { }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " context(\"foo\") {\n" + - " ↓fit(\"bar\") { }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " context(\"bar\") {\n" + - " ↓fit(\"toto\") { }\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓fitBehavesLike(\"foo\")\n" + - " }\n" + - "}\n" + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓fdescribe("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓fcontext("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓fit("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + ↓fit("bar") { } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + context("foo") { + ↓fit("bar") { } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + context("bar") { + ↓fit("toto") { } + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓fitBehavesLike("foo") + } + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedPendingTestRuleExamples.swift b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedPendingTestRuleExamples.swift index ae621838a0..4a40e31764 100644 --- a/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedPendingTestRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Lint/QuickDiscouragedPendingTestRuleExamples.swift @@ -1,67 +1,85 @@ internal struct QuickDiscouragedPendingTestRuleExamples { static let nonTriggeringExamples = [ - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " describe(\"bar\") { } \n" + - " context(\"bar\") {\n" + - " it(\"bar\") { }\n" + - " }\n" + - " it(\"bar\") { }\n" + - " itBehavesLike(\"bar\")\n" + - " }\n" + - " }\n" + - "}\n" + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + describe("bar") { } + context("bar") { + it("bar") { } + } + it("bar") { } + itBehavesLike("bar") + } + } + } + """) ] static let triggeringExamples = [ - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓xdescribe(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓xcontext(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓xit(\"foo\") { }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " ↓xit(\"bar\") { }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " context(\"foo\") {\n" + - " ↓xit(\"bar\") { }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " describe(\"foo\") {\n" + - " context(\"bar\") {\n" + - " ↓xit(\"toto\") { }\n" + - " }\n" + - " }\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓pending(\"foo\")\n" + - " }\n" + - "}\n", - "class TotoTests: QuickSpec {\n" + - " override func spec() {\n" + - " ↓xitBehavesLike(\"foo\")\n" + - " }\n" + - "}\n" + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓xdescribe("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓xcontext("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓xit("foo") { } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + ↓xit("bar") { } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + context("foo") { + ↓xit("bar") { } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + describe("foo") { + context("bar") { + ↓xit("toto") { } + } + } + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓pending("foo") + } + } + """), + Example(""" + class TotoTests: QuickSpec { + override func spec() { + ↓xitBehavesLike("foo") + } + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Lint/RawValueForCamelCasedCodableEnumRule.swift b/Source/SwiftLintFramework/Rules/Lint/RawValueForCamelCasedCodableEnumRule.swift index b7c7ce590f..80b4eff2fc 100644 --- a/Source/SwiftLintFramework/Rules/Lint/RawValueForCamelCasedCodableEnumRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/RawValueForCamelCasedCodableEnumRule.swift @@ -12,74 +12,74 @@ public struct RawValueForCamelCasedCodableEnumRule: ASTRule, OptInRule, Configur description: "Camel cased cases of Codable String enums should have raw value.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" enum Numbers: Codable { case int(Int) case short(Int16) } - """, - """ + """), + Example(""" enum Numbers: Int, Codable { case one = 1 case two = 2 } - """, - """ + """), + Example(""" enum Numbers: Double, Codable { case one = 1.1 case two = 2.2 } - """, - """ + """), + Example(""" enum Numbers: String, Codable { case one = "one" case two = "two" } - """, - """ + """), + Example(""" enum Status: String { case ok case notAcceptable case maybeAcceptable = "maybe_acceptable" } - """, - """ + """), + Example(""" enum Status: Int, Codable { case ok case notAcceptable case maybeAcceptable = -1 } - """ + """) ], triggeringExamples: [ - """ + Example(""" enum Status: String, Codable { case ok case ↓notAcceptable case maybeAcceptable = "maybe_acceptable" } - """, - """ + """), + Example(""" enum Status: String, Decodable { case ok case ↓notAcceptable case maybeAcceptable = "maybe_acceptable" } - """, - """ + """), + Example(""" enum Status: String, Encodable { case ok case ↓notAcceptable case maybeAcceptable = "maybe_acceptable" } - """, - """ + """), + Example(""" enum Status: String, Codable { case ok case ↓notAcceptable case maybeAcceptable = "maybe_acceptable" } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/RequiredDeinitRule.swift b/Source/SwiftLintFramework/Rules/Lint/RequiredDeinitRule.swift index 275660bd1b..b40a8ec3d8 100644 --- a/Source/SwiftLintFramework/Rules/Lint/RequiredDeinitRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/RequiredDeinitRule.swift @@ -15,37 +15,37 @@ public struct RequiredDeinitRule: ASTRule, OptInRule, ConfigurationProviderRule, description: "Classes should have an explicit deinit method.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" class Apple { deinit { } } - """, - "enum Banana { }", - "protocol Cherry { }", - "struct Damson { }", - """ + """), + Example("enum Banana { }"), + Example("protocol Cherry { }"), + Example("struct Damson { }"), + Example(""" class Outer { deinit { print("Deinit Outer") } class Inner { deinit { print("Deinit Inner") } } } - """ + """) ], triggeringExamples: [ - "↓class Apple { }", - "↓class Banana: NSObject, Equatable { }", - """ + Example("↓class Apple { }"), + Example("↓class Banana: NSObject, Equatable { }"), + Example(""" ↓class Cherry { // deinit { } } - """, - """ + """), + Example(""" ↓class Damson { func deinitialize() { } } - """, - """ + """), + Example(""" class Outer { func hello() -> String { return "outer" } deinit { } @@ -53,8 +53,8 @@ public struct RequiredDeinitRule: ASTRule, OptInRule, ConfigurationProviderRule, func hello() -> String { return "inner" } } } - """, - """ + """), + Example(""" ↓class Outer { func hello() -> String { return "outer" } class Inner { @@ -62,7 +62,7 @@ public struct RequiredDeinitRule: ASTRule, OptInRule, ConfigurationProviderRule, deinit { } } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/RequiredEnumCaseRule.swift b/Source/SwiftLintFramework/Rules/Lint/RequiredEnumCaseRule.swift index 402aef238c..496504237c 100644 --- a/Source/SwiftLintFramework/Rules/Lint/RequiredEnumCaseRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/RequiredEnumCaseRule.swift @@ -124,38 +124,54 @@ public struct RequiredEnumCaseRule: ASTRule, OptInRule, ConfigurationProviderRul description: "Enums conforming to a specified protocol must implement a specific case(s).", kind: .lint, nonTriggeringExamples: [ - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success, error, notConnected \n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success, error, notConnected(error: Error) \n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success\n" + - " case error\n" + - " case notConnected\n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success\n" + - " case error\n" + - " case notConnected(error: Error)\n" + - "}" + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success, error, notConnected + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success, error, notConnected(error: Error) + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success + case error + case notConnected + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success + case error + case notConnected(error: Error) + } + """) ], triggeringExamples: [ - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success, error \n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success, error \n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success\n" + - " case error\n" + - "}", - "enum MyNetworkResponse: String, NetworkResponsable {\n" + - " case success\n" + - " case error\n" + - "}" + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success, error + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success, error + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success + case error + } + """), + Example(""" + enum MyNetworkResponse: String, NetworkResponsable { + case success + case error + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/StrongIBOutletRule.swift b/Source/SwiftLintFramework/Rules/Lint/StrongIBOutletRule.swift index 45570b9862..9673265d2a 100644 --- a/Source/SwiftLintFramework/Rules/Lint/StrongIBOutletRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/StrongIBOutletRule.swift @@ -11,14 +11,14 @@ public struct StrongIBOutletRule: ConfigurationProviderRule, ASTRule, OptInRule, description: "@IBOutlets shouldn't be declared as weak.", kind: .lint, nonTriggeringExamples: [ - "@IBOutlet var label: UILabel?", - "weak var label: UILabel?" - ].map(wrapExample), + wrapExample("@IBOutlet var label: UILabel?"), + wrapExample("weak var label: UILabel?") + ], triggeringExamples: [ - "@IBOutlet weak ↓var label: UILabel?", - "@IBOutlet unowned ↓var label: UILabel!", - "@IBOutlet weak ↓var textField: UITextField?" - ].map(wrapExample) + wrapExample("@IBOutlet weak ↓var label: UILabel?"), + wrapExample("@IBOutlet unowned ↓var label: UILabel!"), + wrapExample("@IBOutlet weak ↓var textField: UITextField?") + ] ) public func validate(file: SwiftLintFile, kind: SwiftDeclarationKind, @@ -40,10 +40,10 @@ public struct StrongIBOutletRule: ConfigurationProviderRule, ASTRule, OptInRule, } } -private func wrapExample(_ text: String) -> String { - return """ +private func wrapExample(_ text: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" class ViewController: UIViewController { \(text) } - """ + """, file: file, line: line) } diff --git a/Source/SwiftLintFramework/Rules/Lint/TodoRule.swift b/Source/SwiftLintFramework/Rules/Lint/TodoRule.swift index 58986c0907..ae10a62582 100644 --- a/Source/SwiftLintFramework/Rules/Lint/TodoRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/TodoRule.swift @@ -19,18 +19,18 @@ public struct TodoRule: ConfigurationProviderRule { description: "TODOs and FIXMEs should be resolved.", kind: .lint, nonTriggeringExamples: [ - "// notaTODO:\n", - "// notaFIXME:\n" + Example("// notaTODO:\n"), + Example("// notaFIXME:\n") ], triggeringExamples: [ - "// ↓TODO:\n", - "// ↓FIXME:\n", - "// ↓TODO(note)\n", - "// ↓FIXME(note)\n", - "/* ↓FIXME: */\n", - "/* ↓TODO: */\n", - "/** ↓FIXME: */\n", - "/** ↓TODO: */\n" + Example("// ↓TODO:\n"), + Example("// ↓FIXME:\n"), + Example("// ↓TODO(note)\n"), + Example("// ↓FIXME(note)\n"), + Example("/* ↓FIXME: */\n"), + Example("/* ↓TODO: */\n"), + Example("/** ↓FIXME: */\n"), + Example("/** ↓TODO: */\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnownedVariableCaptureRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnownedVariableCaptureRule.swift index d73d3e6898..ecfc50010d 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnownedVariableCaptureRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnownedVariableCaptureRule.swift @@ -13,17 +13,17 @@ public struct UnownedVariableCaptureRule: ASTRule, OptInRule, ConfigurationProvi kind: .lint, minSwiftVersion: .five, nonTriggeringExamples: [ - "foo { [weak self] in _ }", - "foo { [weak self] param in _ }", - "foo { [weak bar] in _ }", - "foo { [weak bar] param in _ }", - "foo { bar in _ }", - "foo { $0 }" + Example("foo { [weak self] in _ }"), + Example("foo { [weak self] param in _ }"), + Example("foo { [weak bar] in _ }"), + Example("foo { [weak bar] param in _ }"), + Example("foo { bar in _ }"), + Example("foo { $0 }") ], triggeringExamples: [ - "foo { [↓unowned self] in _ }", - "foo { [↓unowned bar] in _ }", - "foo { [bar, ↓unowned self] in _ }" + Example("foo { [↓unowned self] in _ }"), + Example("foo { [↓unowned bar] in _ }"), + Example("foo { [bar, ↓unowned self] in _ }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift index 6c9b8f8e59..f48b77e589 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift @@ -13,62 +13,62 @@ public struct UnusedCaptureListRule: ASTRule, ConfigurationProviderRule, Automat kind: .lint, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - """ + Example(""" [1, 2].map { [weak self] num in self?.handle(num) } - """, - """ + """), + Example(""" let failure: Failure = { [weak self, unowned delegate = self.delegate!] foo in delegate.handle(foo, self) } - """, - """ + """), + Example(""" numbers.forEach({ [weak handler] in handler?.handle($0) }) - """, - """ + """), + Example(""" withEnvironment(apiService: MockService(fetchProjectResponse: project)) { [Device.phone4_7inch, Device.phone5_8inch, Device.pad].forEach { device in device.handle() } } - """, - "{ [foo] _ in foo.bar() }()", - "sizes.max().flatMap { [(offset: offset, size: $0)] } ?? []" + """), + Example("{ [foo] _ in foo.bar() }()"), + Example("sizes.max().flatMap { [(offset: offset, size: $0)] } ?? []") ], triggeringExamples: [ - """ + Example(""" [1, 2].map { [↓weak self] num in print(num) } - """, - """ + """), + Example(""" let failure: Failure = { [weak self, ↓unowned delegate = self.delegate!] foo in self?.handle(foo) } - """, - """ + """), + Example(""" let failure: Failure = { [↓weak self, ↓unowned delegate = self.delegate!] foo in print(foo) } - """, - """ + """), + Example(""" numbers.forEach({ [weak handler] in print($0) }) - """, - """ + """), + Example(""" withEnvironment(apiService: MockService(fetchProjectResponse: project)) { [↓foo] in [Device.phone4_7inch, Device.phone5_8inch, Device.pad].forEach { device in device.handle() } } - """, - "{ [↓foo] in _ }()" + """), + Example("{ [↓foo] in _ }()") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedClosureParameterRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedClosureParameterRule.swift index f767c4b693..c5728e7368 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedClosureParameterRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedClosureParameterRule.swift @@ -13,88 +13,88 @@ public struct UnusedClosureParameterRule: SubstitutionCorrectableASTRule, Config description: "Unused parameter in a closure should be replaced with _.", kind: .lint, nonTriggeringExamples: [ - "[1, 2].map { $0 + 1 }\n", - "[1, 2].map({ $0 + 1 })\n", - "[1, 2].map { number in\n number + 1 \n}\n", - "[1, 2].map { _ in\n 3 \n}\n", - "[1, 2].something { number, idx in\n return number * idx\n}\n", - "let isEmpty = [1, 2].isEmpty()\n", - "violations.sorted(by: { lhs, rhs in \n return lhs.location > rhs.location\n})\n", - "rlmConfiguration.migrationBlock.map { rlmMigration in\n" + + Example("[1, 2].map { $0 + 1 }\n"), + Example("[1, 2].map({ $0 + 1 })\n"), + Example("[1, 2].map { number in\n number + 1 \n}\n"), + Example("[1, 2].map { _ in\n 3 \n}\n"), + Example("[1, 2].something { number, idx in\n return number * idx\n}\n"), + Example("let isEmpty = [1, 2].isEmpty()\n"), + Example("violations.sorted(by: { lhs, rhs in \n return lhs.location > rhs.location\n})\n"), + Example("rlmConfiguration.migrationBlock.map { rlmMigration in\n" + "return { migration, schemaVersion in\n" + "rlmMigration(migration.rlmMigration, schemaVersion)\n" + "}\n" + - "}", - "genericsFunc { (a: Type, b) in\n" + + "}"), + Example("genericsFunc { (a: Type, b) in\n" + "a + b\n" + - "}\n", - "var label: UILabel = { (lbl: UILabel) -> UILabel in\n" + + "}\n"), + Example("var label: UILabel = { (lbl: UILabel) -> UILabel in\n" + " lbl.backgroundColor = .red\n" + " return lbl\n" + - "}(UILabel())\n", - "hoge(arg: num) { num in\n" + + "}(UILabel())\n"), + Example("hoge(arg: num) { num in\n" + " return num\n" + - "}\n", - """ + "}\n"), + Example(""" ({ (manager: FileManager) in print(manager) })(FileManager.default) - """, - """ + """), + Example(""" withPostSideEffect { input in if true { print("\\(input)") } } - """, - """ + """), + Example(""" viewModel?.profileImage.didSet(weak: self) { (self, profileImage) in self.profileImageView.image = profileImage } - """ + """) ], triggeringExamples: [ - "[1, 2].map { ↓number in\n return 3\n}\n", - "[1, 2].map { ↓number in\n return numberWithSuffix\n}\n", - "[1, 2].map { ↓number in\n return 3 // number\n}\n", - "[1, 2].map { ↓number in\n return 3 \"number\"\n}\n", - "[1, 2].something { number, ↓idx in\n return number\n}\n", - "genericsFunc { (↓number: TypeA, idx: TypeB) in return idx\n}\n", - "hoge(arg: num) { ↓num in\n" + - "}\n", - "fooFunc { ↓아 in\n }", - "func foo () {\n bar { ↓number in\n return 3\n}\n", - """ + Example("[1, 2].map { ↓number in\n return 3\n}\n"), + Example("[1, 2].map { ↓number in\n return numberWithSuffix\n}\n"), + Example("[1, 2].map { ↓number in\n return 3 // number\n}\n"), + Example("[1, 2].map { ↓number in\n return 3 \"number\"\n}\n"), + Example("[1, 2].something { number, ↓idx in\n return number\n}\n"), + Example("genericsFunc { (↓number: TypeA, idx: TypeB) in return idx\n}\n"), + Example("hoge(arg: num) { ↓num in\n" + + "}\n"), + Example("fooFunc { ↓아 in\n }"), + Example("func foo () {\n bar { ↓number in\n return 3\n}\n"), + Example(""" viewModel?.profileImage.didSet(weak: self) { (↓self, profileImage) in profileImageView.image = profileImage } - """ + """) ], corrections: [ - "[1, 2].map { ↓number in\n return 3\n}\n": - "[1, 2].map { _ in\n return 3\n}\n", - "[1, 2].map { ↓number in\n return numberWithSuffix\n}\n": - "[1, 2].map { _ in\n return numberWithSuffix\n}\n", - "[1, 2].map { ↓number in\n return 3 // number\n}\n": - "[1, 2].map { _ in\n return 3 // number\n}\n", - "[1, 2].map { ↓number in\n return 3 \"number\"\n}\n": - "[1, 2].map { _ in\n return 3 \"number\"\n}\n", - "[1, 2].something { number, ↓idx in\n return number\n}\n": - "[1, 2].something { number, _ in\n return number\n}\n", - "genericsFunc(closure: { (↓int: Int) -> Void in // do something\n}\n": - "genericsFunc(closure: { (_: Int) -> Void in // do something\n}\n", - "genericsFunc { (↓a, ↓b: Type) -> Void in\n}\n": - "genericsFunc { (_, _: Type) -> Void in\n}\n", - "genericsFunc { (↓a: Type, ↓b: Type) -> Void in\n}\n": - "genericsFunc { (_: Type, _: Type) -> Void in\n}\n", - "genericsFunc { (↓a: Type, ↓b) -> Void in\n}\n": - "genericsFunc { (_: Type, _) -> Void in\n}\n", - "genericsFunc { (a: Type, ↓b) -> Void in\nreturn a\n}\n": - "genericsFunc { (a: Type, _) -> Void in\nreturn a\n}\n", - "hoge(arg: num) { ↓num in\n}\n": - "hoge(arg: num) { _ in\n}\n", - "func foo () {\n bar { ↓number in\n return 3\n}\n": - "func foo () {\n bar { _ in\n return 3\n}\n", - "class C {\n #if true\n func f() {\n [1, 2].map { ↓number in\n return 3\n }\n }\n #endif\n}": - "class C {\n #if true\n func f() {\n [1, 2].map { _ in\n return 3\n }\n }\n #endif\n}" + Example("[1, 2].map { ↓number in\n return 3\n}\n"): + Example("[1, 2].map { _ in\n return 3\n}\n"), + Example("[1, 2].map { ↓number in\n return numberWithSuffix\n}\n"): + Example("[1, 2].map { _ in\n return numberWithSuffix\n}\n"), + Example("[1, 2].map { ↓number in\n return 3 // number\n}\n"): + Example("[1, 2].map { _ in\n return 3 // number\n}\n"), + Example("[1, 2].map { ↓number in\n return 3 \"number\"\n}\n"): + Example("[1, 2].map { _ in\n return 3 \"number\"\n}\n"), + Example("[1, 2].something { number, ↓idx in\n return number\n}\n"): + Example("[1, 2].something { number, _ in\n return number\n}\n"), + Example("genericsFunc(closure: { (↓int: Int) -> Void in // do something\n}\n"): + Example("genericsFunc(closure: { (_: Int) -> Void in // do something\n}\n"), + Example("genericsFunc { (↓a, ↓b: Type) -> Void in\n}\n"): + Example("genericsFunc { (_, _: Type) -> Void in\n}\n"), + Example("genericsFunc { (↓a: Type, ↓b: Type) -> Void in\n}\n"): + Example("genericsFunc { (_: Type, _: Type) -> Void in\n}\n"), + Example("genericsFunc { (↓a: Type, ↓b) -> Void in\n}\n"): + Example("genericsFunc { (_: Type, _) -> Void in\n}\n"), + Example("genericsFunc { (a: Type, ↓b) -> Void in\nreturn a\n}\n"): + Example("genericsFunc { (a: Type, _) -> Void in\nreturn a\n}\n"), + Example("hoge(arg: num) { ↓num in\n}\n"): + Example("hoge(arg: num) { _ in\n}\n"), + Example("func foo () {\n bar { ↓number in\n return 3\n}\n"): + Example("func foo () {\n bar { _ in\n return 3\n}\n"), + Example("class C {\n #if true\n func f() {\n [1, 2].map { ↓number in\n return 3\n }\n }\n #endif\n}"): + Example("class C {\n #if true\n func f() {\n [1, 2].map { _ in\n return 3\n }\n }\n #endif\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift index e5970d580e..697ac4ae01 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift @@ -13,77 +13,77 @@ public struct UnusedControlFlowLabelRule: SubstitutionCorrectableASTRule, Config description: "Unused control flow label should be removed.", kind: .lint, nonTriggeringExamples: [ - "loop: while true { break loop }", - "loop: while true { continue loop }", - "loop:\n while true { break loop }", - "while true { break }", - "loop: for x in array { break loop }", - """ + Example("loop: while true { break loop }"), + Example("loop: while true { continue loop }"), + Example("loop:\n while true { break loop }"), + Example("while true { break }"), + Example("loop: for x in array { break loop }"), + Example(""" label: switch number { case 1: print("1") case 2: print("2") default: break label } - """, - """ + """), + Example(""" loop: repeat { if x == 10 { break loop } } while true - """ + """) ], triggeringExamples: [ - "↓loop: while true { break }", - "↓loop: while true { break loop1 }", - "↓loop: while true { break outerLoop }", - "↓loop: for x in array { break }", - """ + Example("↓loop: while true { break }"), + Example("↓loop: while true { break loop1 }"), + Example("↓loop: while true { break outerLoop }"), + Example("↓loop: for x in array { break }"), + Example(""" ↓label: switch number { case 1: print("1") case 2: print("2") default: break } - """, - """ + """), + Example(""" ↓loop: repeat { if x == 10 { break } } while true - """ + """) ], corrections: [ - "↓loop: while true { break }": "while true { break }", - "↓loop: while true { break loop1 }": "while true { break loop1 }", - "↓loop: while true { break outerLoop }": "while true { break outerLoop }", - "↓loop: for x in array { break }": "for x in array { break }", - """ + Example("↓loop: while true { break }"): Example("while true { break }"), + Example("↓loop: while true { break loop1 }"): Example("while true { break loop1 }"), + Example("↓loop: while true { break outerLoop }"): Example("while true { break outerLoop }"), + Example("↓loop: for x in array { break }"): Example("for x in array { break }"), + Example(""" ↓label: switch number { case 1: print("1") case 2: print("2") default: break } - """: """ + """): Example(""" switch number { case 1: print("1") case 2: print("2") default: break } - """, - """ + """), + Example(""" ↓loop: repeat { if x == 10 { break } } while true - """: """ + """): Example(""" repeat { if x == 10 { break } } while true - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedDeclarationRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedDeclarationRule.swift index 1bdc14d562..4f812fb131 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedDeclarationRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedDeclarationRule.swift @@ -20,11 +20,11 @@ public struct UnusedDeclarationRule: AutomaticTestableRule, ConfigurationProvide description: "Declarations should be referenced at least once within all files linted.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" let kConstant = 0 _ = kConstant - """, - """ + """), + Example(""" enum Change { case insert(T) case delete(T) @@ -44,8 +44,8 @@ public struct UnusedDeclarationRule: AutomaticTestableRule, ConfigurationProvide let changes = [Change.insert(0), .delete(0)] changes.deletes() - """, - """ + """), + Example(""" struct Item {} struct ResponseModel: Codable { let items: [Item] @@ -56,20 +56,20 @@ public struct UnusedDeclarationRule: AutomaticTestableRule, ConfigurationProvide } _ = ResponseModel(items: [Item()]).items - """, - """ + """), + Example(""" class ResponseModel { @objc func foo() { } } _ = ResponseModel() - """ + """) ], triggeringExamples: [ - """ + Example(""" let ↓kConstant = 0 - """, - """ + """), + Example(""" struct Item {} struct ↓ResponseModel: Codable { let ↓items: [Item] @@ -78,13 +78,13 @@ public struct UnusedDeclarationRule: AutomaticTestableRule, ConfigurationProvide case items = "ResponseItems" } } - """, - """ + """), + Example(""" class ↓ResponseModel { func ↓foo() { } } - """ + """) ], requiresFileOnDisk: true ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedImportRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedImportRule.swift index 086bfe2148..2cb88cbee5 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedImportRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedImportRule.swift @@ -12,39 +12,39 @@ public struct UnusedImportRule: CorrectableRule, ConfigurationProviderRule, Anal description: "All imported modules should be required to make the file compile.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" import Dispatch // This is used dispatchMain() - """, - """ + """), + Example(""" @testable import Dispatch dispatchMain() - """, - """ + """), + Example(""" import Foundation @objc class A {} - """, - """ + """), + Example(""" import UnknownModule func foo(error: Swift.Error) {} - """, - """ + """), + Example(""" import Foundation import ObjectiveC let 👨‍👩‍👧‍👦 = #selector(NSArray.contains(_:)) 👨‍👩‍👧‍👦 == 👨‍👩‍👧‍👦 - """ + """) ], triggeringExamples: [ - """ + Example(""" ↓import Dispatch struct A { static func dispatchMain() {} } A.dispatchMain() - """, - """ + """), + Example(""" ↓import Foundation // This is unused struct A { static func dispatchMain() {} @@ -52,37 +52,36 @@ public struct UnusedImportRule: CorrectableRule, ConfigurationProviderRule, Anal A.dispatchMain() ↓import Dispatch - """, - """ + """), + Example(""" ↓import Foundation dispatchMain() - """, - """ + """), + Example(""" ↓import Foundation // @objc class A {} - """, - """ + """), + Example(""" ↓import Foundation import UnknownModule func foo(error: Swift.Error) {} - """ + """) ], corrections: [ - """ + Example(""" ↓import Dispatch struct A { static func dispatchMain() {} } A.dispatchMain() - """: - """ + """): Example(""" struct A { static func dispatchMain() {} } A.dispatchMain() - """, - """ + """), + Example(""" ↓import Foundation // This is unused struct A { static func dispatchMain() {} @@ -90,59 +89,53 @@ public struct UnusedImportRule: CorrectableRule, ConfigurationProviderRule, Anal A.dispatchMain() ↓import Dispatch - """: - """ + """): Example(""" struct A { static func dispatchMain() {} } A.dispatchMain() - """, - """ + """), + Example(""" ↓import Foundation dispatchMain() - """: - """ + """): Example(""" dispatchMain() - """, - """ + """), + Example(""" ↓@testable import Foundation import Dispatch dispatchMain() - """: - """ + """): Example(""" import Dispatch dispatchMain() - """, - """ + """), + Example(""" ↓@_exported import Foundation import Dispatch dispatchMain() - """: - """ + """): Example(""" import Dispatch dispatchMain() - """, - """ + """), + Example(""" ↓import Foundation // @objc class A {} - """: - """ + """): Example(""" // @objc class A {} - """, - """ + """), + Example(""" @testable import Foundation ↓import Dispatch @objc class A {} - """: - """ + """): Example(""" @testable import Foundation @objc class A {} - """ + """) ], requiresFileOnDisk: true ) diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedSetterValueRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedSetterValueRule.swift index e4bd8f5251..67614f9b12 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedSetterValueRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedSetterValueRule.swift @@ -12,7 +12,7 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl description: "Setter value is not used.", kind: .lint, nonTriggeringExamples: [ - """ + Example(""" var aValue: String { get { return Persister.shared.aValue @@ -21,8 +21,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = newValue } } - """, - """ + """), + Example(""" var aValue: String { set { Persister.shared.aValue = newValue @@ -31,8 +31,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl return Persister.shared.aValue } } - """, - """ + """), + Example(""" var aValue: String { get { return Persister.shared.aValue @@ -41,10 +41,10 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = value } } - """ + """) ], triggeringExamples: [ - """ + Example(""" var aValue: String { get { return Persister.shared.aValue @@ -53,8 +53,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = aValue } } - """, - """ + """), + Example(""" var aValue: String { ↓set { Persister.shared.aValue = aValue @@ -63,8 +63,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl return Persister.shared.aValue } } - """, - """ + """), + Example(""" var aValue: String { get { return Persister.shared.aValue @@ -73,8 +73,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = aValue } } - """, - """ + """), + Example(""" var aValue: String { get { let newValue = Persister.shared.aValue @@ -84,8 +84,8 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = aValue } } - """, - """ + """), + Example(""" var aValue: String { get { return Persister.shared.aValue @@ -94,7 +94,7 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl Persister.shared.aValue = aValue } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/ValidIBInspectableRule.swift b/Source/SwiftLintFramework/Rules/Lint/ValidIBInspectableRule.swift index 0e55675c40..4fc5aec09c 100644 --- a/Source/SwiftLintFramework/Rules/Lint/ValidIBInspectableRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/ValidIBInspectableRule.swift @@ -14,24 +14,24 @@ public struct ValidIBInspectableRule: ASTRule, ConfigurationProviderRule, Automa "and be of a supported type", kind: .lint, nonTriggeringExamples: [ - "class Foo {\n @IBInspectable private var x: Int\n}\n", - "class Foo {\n @IBInspectable private var x: String?\n}\n", - "class Foo {\n @IBInspectable private var x: String!\n}\n", - "class Foo {\n @IBInspectable private var count: Int = 0\n}\n", - "class Foo {\n private var notInspectable = 0\n}\n", - "class Foo {\n private let notInspectable: Int\n}\n", - "class Foo {\n private let notInspectable: UInt8\n}\n" + Example("class Foo {\n @IBInspectable private var x: Int\n}\n"), + Example("class Foo {\n @IBInspectable private var x: String?\n}\n"), + Example("class Foo {\n @IBInspectable private var x: String!\n}\n"), + Example("class Foo {\n @IBInspectable private var count: Int = 0\n}\n"), + Example("class Foo {\n private var notInspectable = 0\n}\n"), + Example("class Foo {\n private let notInspectable: Int\n}\n"), + Example("class Foo {\n private let notInspectable: UInt8\n}\n") ], triggeringExamples: [ - "class Foo {\n @IBInspectable private ↓let count: Int\n}\n", - "class Foo {\n @IBInspectable private ↓var insets: UIEdgeInsets\n}\n", - "class Foo {\n @IBInspectable private ↓var count = 0\n}\n", - "class Foo {\n @IBInspectable private ↓var count: Int?\n}\n", - "class Foo {\n @IBInspectable private ↓var count: Int!\n}\n", - "class Foo {\n @IBInspectable private ↓var x: ImplicitlyUnwrappedOptional\n}\n", - "class Foo {\n @IBInspectable private ↓var count: Optional\n}\n", - "class Foo {\n @IBInspectable private ↓var x: Optional\n}\n", - "class Foo {\n @IBInspectable private ↓var x: ImplicitlyUnwrappedOptional\n}\n" + Example("class Foo {\n @IBInspectable private ↓let count: Int\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var insets: UIEdgeInsets\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var count = 0\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var count: Int?\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var count: Int!\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var x: ImplicitlyUnwrappedOptional\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var count: Optional\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var x: Optional\n}\n"), + Example("class Foo {\n @IBInspectable private ↓var x: ImplicitlyUnwrappedOptional\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/WeakDelegateRule.swift b/Source/SwiftLintFramework/Rules/Lint/WeakDelegateRule.swift index 84a750e548..9298580a97 100644 --- a/Source/SwiftLintFramework/Rules/Lint/WeakDelegateRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/WeakDelegateRule.swift @@ -13,28 +13,29 @@ public struct WeakDelegateRule: ASTRule, SubstitutionCorrectableASTRule, Configu description: "Delegates should be weak to avoid reference cycles.", kind: .lint, nonTriggeringExamples: [ - "class Foo {\n weak var delegate: SomeProtocol?\n}\n", - "class Foo {\n weak var someDelegate: SomeDelegateProtocol?\n}\n", - "class Foo {\n weak var delegateScroll: ScrollDelegate?\n}\n", + Example("class Foo {\n weak var delegate: SomeProtocol?\n}\n"), + Example("class Foo {\n weak var someDelegate: SomeDelegateProtocol?\n}\n"), + Example("class Foo {\n weak var delegateScroll: ScrollDelegate?\n}\n"), // We only consider properties to be a delegate if it has "delegate" in its name - "class Foo {\n var scrollHandler: ScrollDelegate?\n}\n", + Example("class Foo {\n var scrollHandler: ScrollDelegate?\n}\n"), // Only trigger on instance variables, not local variables - "func foo() {\n var delegate: SomeDelegate\n}\n", + Example("func foo() {\n var delegate: SomeDelegate\n}\n"), // Only trigger when variable has the suffix "-delegate" to avoid false positives - "class Foo {\n var delegateNotified: Bool?\n}\n", + Example("class Foo {\n var delegateNotified: Bool?\n}\n"), // There's no way to declare a property weak in a protocol - "protocol P {\n var delegate: AnyObject? { get set }\n}\n", - "class Foo {\n protocol P {\n var delegate: AnyObject? { get set }\n}\n}\n", - "class Foo {\n var computedDelegate: ComputedDelegate {\n return bar() \n} \n}" + Example("protocol P {\n var delegate: AnyObject? { get set }\n}\n"), + Example("class Foo {\n protocol P {\n var delegate: AnyObject? { get set }\n}\n}\n"), + Example("class Foo {\n var computedDelegate: ComputedDelegate {\n return bar() \n} \n}") ], triggeringExamples: [ - "class Foo {\n ↓var delegate: SomeProtocol?\n}\n", - "class Foo {\n ↓var scrollDelegate: ScrollDelegate?\n}\n" + Example("class Foo {\n ↓var delegate: SomeProtocol?\n}\n"), + Example("class Foo {\n ↓var scrollDelegate: ScrollDelegate?\n}\n") ], corrections: [ - "class Foo {\n ↓var delegate: SomeProtocol?\n}\n": "class Foo {\n weak var delegate: SomeProtocol?\n}\n", - "class Foo {\n ↓var scrollDelegate: ScrollDelegate?\n}\n": - "class Foo {\n weak var scrollDelegate: ScrollDelegate?\n}\n" + Example("class Foo {\n ↓var delegate: SomeProtocol?\n}\n"): + Example("class Foo {\n weak var delegate: SomeProtocol?\n}\n"), + Example("class Foo {\n ↓var scrollDelegate: ScrollDelegate?\n}\n"): + Example("class Foo {\n weak var scrollDelegate: ScrollDelegate?\n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Lint/YodaConditionRule.swift b/Source/SwiftLintFramework/Rules/Lint/YodaConditionRule.swift index 04df94c61f..e7801794c3 100644 --- a/Source/SwiftLintFramework/Rules/Lint/YodaConditionRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/YodaConditionRule.swift @@ -38,24 +38,24 @@ public struct YodaConditionRule: ASTRule, OptInRule, ConfigurationProviderRule, description: "The variable should be placed on the left, the constant on the right of a comparison operator.", kind: .lint, nonTriggeringExamples: [ - "if foo == 42 {}\n", - "if foo <= 42.42 {}\n", - "guard foo >= 42 else { return }\n", - "guard foo != \"str str\" else { return }", - "while foo < 10 { }\n", - "while foo > 1 { }\n", - "while foo + 1 == 2", - "if optionalValue?.property ?? 0 == 2", - "if foo == nil" + Example("if foo == 42 {}\n"), + Example("if foo <= 42.42 {}\n"), + Example("guard foo >= 42 else { return }\n"), + Example("guard foo != \"str str\" else { return }"), + Example("while foo < 10 { }\n"), + Example("while foo > 1 { }\n"), + Example("while foo + 1 == 2"), + Example("if optionalValue?.property ?? 0 == 2"), + Example("if foo == nil") ], triggeringExamples: [ - "↓if 42 == foo {}\n", - "↓if 42.42 >= foo {}\n", - "↓guard 42 <= foo else { return }\n", - "↓guard \"str str\" != foo else { return }", - "↓while 10 > foo { }", - "↓while 1 < foo { }", - "↓if nil == foo" + Example("↓if 42 == foo {}\n"), + Example("↓if 42.42 >= foo {}\n"), + Example("↓guard 42 <= foo else { return }\n"), + Example("↓guard \"str str\" != foo else { return }"), + Example("↓while 10 > foo { }"), + Example("↓while 1 < foo { }"), + Example("↓if nil == foo") ]) public func validate(file: SwiftLintFile, diff --git a/Source/SwiftLintFramework/Rules/Metrics/ClosureBodyLengthRuleExamples.swift b/Source/SwiftLintFramework/Rules/Metrics/ClosureBodyLengthRuleExamples.swift index 87f8831ada..c615af9621 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/ClosureBodyLengthRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/ClosureBodyLengthRuleExamples.swift @@ -1,5 +1,5 @@ internal struct ClosureBodyLengthRuleExamples { - static let nonTriggeringExamples: [String] = [ + static let nonTriggeringExamples: [Example] = [ singleLineClosure(), trailingClosure(codeLinesCount: 0, commentLinesCount: 0, emptyLinesCount: 0), trailingClosure(codeLinesCount: 1, commentLinesCount: 10, emptyLinesCount: 10), @@ -16,7 +16,7 @@ internal struct ClosureBodyLengthRuleExamples { lazyInitialization(codeLinesCount: 18) ] - static let triggeringExamples: [String] = [ + static let triggeringExamples: [Example] = [ trailingClosure("↓", codeLinesCount: 21, commentLinesCount: 0, emptyLinesCount: 0), trailingClosure("↓", codeLinesCount: 21, commentLinesCount: 10, emptyLinesCount: 10), argumentClosure("↓", codeLinesCount: 21), @@ -29,65 +29,82 @@ internal struct ClosureBodyLengthRuleExamples { // MARK: - Private -private func singleLineClosure() -> String { - return "foo.bar { $0 }" +private func singleLineClosure(file: StaticString = #file, line: UInt = #line) -> Example { + return Example("foo.bar { $0 }", file: file, line: line) } private func trailingClosure(_ violationSymbol: String = "", codeLinesCount: Int, commentLinesCount: Int, - emptyLinesCount: Int) -> String { - return """ + emptyLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" foo.bar \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ \(repeatElement("\t// toto\n", count: commentLinesCount).joined())\ \(repeatElement("\t\n", count: emptyLinesCount).joined())\ } - """ + """, file: file, line: line) } -private func argumentClosure(_ violationSymbol: String = "", codeLinesCount: Int) -> String { - return """ +private func argumentClosure(_ violationSymbol: String = "", + codeLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" foo.bar(\(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ }) - """ + """, file: file, line: line) } -private func labeledArgumentClosure(_ violationSymbol: String = "", codeLinesCount: Int) -> String { - return """ +private func labeledArgumentClosure(_ violationSymbol: String = "", + codeLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" foo.bar(label: \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ }) - """ + """, file: file, line: line) } -private func multiLabeledArgumentClosures(_ violationSymbol: String = "", codeLinesCount: Int) -> String { - return """ +private func multiLabeledArgumentClosures(_ violationSymbol: String = "", + codeLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" foo.bar(label: \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ }, anotherLabel: \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ }) - """ + """, file: file, line: line) } -private func labeledAndTrailingClosures(_ violationSymbol: String = "", codeLinesCount: Int) -> String { - return """ +private func labeledAndTrailingClosures(_ violationSymbol: String = "", + codeLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" foo.bar(label: \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ }) \(violationSymbol){ toto in \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ } - """ + """, file: file, line: line) } -private func lazyInitialization(_ violationSymbol: String = "", codeLinesCount: Int) -> String { - return """ +private func lazyInitialization(_ violationSymbol: String = "", + codeLinesCount: Int, + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example(""" let foo: Bar = \(violationSymbol){ toto in \tlet bar = Bar() \(repeatElement("\tlet a = 0\n", count: codeLinesCount).joined())\ \treturn bar }() - """ + """, file: file, line: line) } diff --git a/Source/SwiftLintFramework/Rules/Metrics/CyclomaticComplexityRule.swift b/Source/SwiftLintFramework/Rules/Metrics/CyclomaticComplexityRule.swift index 27d1815c85..d67ea16c6a 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/CyclomaticComplexityRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/CyclomaticComplexityRule.swift @@ -12,22 +12,63 @@ public struct CyclomaticComplexityRule: ASTRule, ConfigurationProviderRule { description: "Complexity of function bodies should be limited.", kind: .metrics, nonTriggeringExamples: [ - "func f1() {\nif true {\nfor _ in 1..5 { } }\nif false { }\n}", - "func f(code: Int) -> Int {" + - "switch code {\n case 0: fallthrough\ncase 0: return 1\ncase 0: return 1\n" + - "case 0: return 1\ncase 0: return 1\ncase 0: return 1\ncase 0: return 1\n" + - "case 0: return 1\ncase 0: return 1\ndefault: return 1}}", - "func f1() {" + - "if true {}; if true {}; if true {}; if true {}; if true {}; if true {}\n" + - "func f2() {\n" + - "if true {}; if true {}; if true {}; if true {}; if true {}\n" + - "}}" + Example(""" + func f1() { + if true { + for _ in 1..5 { } + } + if false { } + } + """), + Example(""" + func f(code: Int) -> Int { + switch code { + case 0: fallthrough + case 0: return 1 + case 0: return 1 + case 0: return 1 + case 0: return 1 + case 0: return 1 + case 0: return 1 + case 0: return 1 + case 0: return 1 + default: return 1 + } + } + """), + Example(""" + func f1() { + if true {}; if true {}; if true {}; if true {}; if true {}; if true {} + func f2() { + if true {}; if true {}; if true {}; if true {}; if true {} + } + } + """) ], triggeringExamples: [ - "↓func f1() {\n if true {\n if true {\n if false {}\n }\n" + - " }\n if false {}\n let i = 0\n\n switch i {\n case 1: break\n" + - " case 2: break\n case 3: break\n case 4: break\n default: break\n }\n" + - " for _ in 1...5 {\n guard true else {\n return\n }\n }\n}\n" + Example(""" + ↓func f1() { + if true { + if true { + if false {} + } + } + if false {} + let i = 0 + switch i { + case 1: break + case 2: break + case 3: break + case 4: break + default: break + } + for _ in 1...5 { + guard true else { + return + } + } + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/EnumCaseAssociatedValuesLengthRule.swift b/Source/SwiftLintFramework/Rules/Metrics/EnumCaseAssociatedValuesLengthRule.swift index af84ec902f..d10b779b67 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/EnumCaseAssociatedValuesLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/EnumCaseAssociatedValuesLengthRule.swift @@ -11,30 +11,30 @@ public struct EnumCaseAssociatedValuesLengthRule: ASTRule, OptInRule, Configurat description: "Number of associated values in an enum case should be low", kind: .metrics, nonTriggeringExamples: [ - """ + Example(""" enum Employee { case fullTime(name: String, retirement: Date, designation: String, contactNumber: Int) case partTime(name: String, age: Int, contractEndDate: Date) } - """, - """ + """), + Example(""" enum Barcode { case upc(Int, Int, Int, Int) } - """ + """) ], triggeringExamples: [ - """ + Example(""" enum Employee { case ↓fullTime(name: String, retirement: Date, age: Int, designation: String, contactNumber: Int) case ↓partTime(name: String, contractEndDate: Date, age: Int, designation: String, contactNumber: Int) } - """, - """ + """), + Example(""" enum Barcode { case ↓upc(Int, Int, Int, Int, Int, Int) } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/FileLengthRule.swift b/Source/SwiftLintFramework/Rules/Metrics/FileLengthRule.swift index f076ce6554..ddb8d321ff 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/FileLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/FileLengthRule.swift @@ -11,11 +11,11 @@ public struct FileLengthRule: ConfigurationProviderRule { description: "Files should not span too many lines.", kind: .metrics, nonTriggeringExamples: [ - repeatElement("print(\"swiftlint\")\n", count: 400).joined() + Example(repeatElement("print(\"swiftlint\")\n", count: 400).joined()) ], triggeringExamples: [ - repeatElement("print(\"swiftlint\")\n", count: 401).joined(), - (repeatElement("print(\"swiftlint\")\n", count: 400) + ["//\n"]).joined() + Example(repeatElement("print(\"swiftlint\")\n", count: 401).joined()), + Example((repeatElement("print(\"swiftlint\")\n", count: 400) + ["//\n"]).joined()) ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/FunctionParameterCountRule.swift b/Source/SwiftLintFramework/Rules/Metrics/FunctionParameterCountRule.swift index 80f28ee921..5b21a14228 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/FunctionParameterCountRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/FunctionParameterCountRule.swift @@ -12,25 +12,29 @@ public struct FunctionParameterCountRule: ASTRule, ConfigurationProviderRule { description: "Number of function parameters should be low.", kind: .metrics, nonTriggeringExamples: [ - "init(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "init (a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "`init`(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "init?(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "init?(a: T, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "init?(a: T, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "func f2(p1: Int, p2: Int) { }", - "func f(a: Int, b: Int, c: Int, d: Int, x: Int = 42) {}", - "func f(a: [Int], b: Int, c: Int, d: Int, f: Int) -> [Int] {\n" + - "let s = a.flatMap { $0 as? [String: Int] } ?? []}}", - "override func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}" + Example("init(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("init (a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("`init`(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("init?(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("init?(a: T, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("init?(a: T, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("func f2(p1: Int, p2: Int) { }"), + Example("func f(a: Int, b: Int, c: Int, d: Int, x: Int = 42) {}"), + Example(""" + func f(a: [Int], b: Int, c: Int, d: Int, f: Int) -> [Int] { + let s = a.flatMap { $0 as? [String: Int] } ?? []}} + """), + Example("override func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}") ], triggeringExamples: [ - "↓func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "↓func initialValue(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}", - "↓func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 2, g: Int) {}", - "struct Foo {\n" + - "init(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}\n" + - "↓func bar(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}}" + Example("↓func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("↓func initialValue(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}"), + Example("↓func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 2, g: Int) {}"), + Example(""" + struct Foo { + init(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {} + ↓func bar(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}} + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/LargeTupleRule.swift b/Source/SwiftLintFramework/Rules/Metrics/LargeTupleRule.swift index 2a87161714..dc172f5530 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/LargeTupleRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/LargeTupleRule.swift @@ -21,36 +21,36 @@ public struct LargeTupleRule: ASTRule, ConfigurationProviderRule, AutomaticTesta description: "Tuples shouldn't have too many members. Create a custom type instead.", kind: .metrics, nonTriggeringExamples: [ - "let foo: (Int, Int)\n", - "let foo: (start: Int, end: Int)\n", - "let foo: (Int, (Int, String))\n", - "func foo() -> (Int, Int)\n", - "func foo() -> (Int, Int) {}\n", - "func foo(bar: String) -> (Int, Int)\n", - "func foo(bar: String) -> (Int, Int) {}\n", - "func foo() throws -> (Int, Int)\n", - "func foo() throws -> (Int, Int) {}\n", - "let foo: (Int, Int, Int) -> Void\n", - "let foo: (Int, Int, Int) throws -> Void\n", - "func foo(bar: (Int, String, Float) -> Void)\n", - "func foo(bar: (Int, String, Float) throws -> Void)\n", - "var completionHandler: ((_ data: Data?, _ resp: URLResponse?, _ e: NSError?) -> Void)!\n", - "func getDictionaryAndInt() -> (Dictionary, Int)?\n", - "func getGenericTypeAndInt() -> (Type, Int)?\n" + Example("let foo: (Int, Int)\n"), + Example("let foo: (start: Int, end: Int)\n"), + Example("let foo: (Int, (Int, String))\n"), + Example("func foo() -> (Int, Int)\n"), + Example("func foo() -> (Int, Int) {}\n"), + Example("func foo(bar: String) -> (Int, Int)\n"), + Example("func foo(bar: String) -> (Int, Int) {}\n"), + Example("func foo() throws -> (Int, Int)\n"), + Example("func foo() throws -> (Int, Int) {}\n"), + Example("let foo: (Int, Int, Int) -> Void\n"), + Example("let foo: (Int, Int, Int) throws -> Void\n"), + Example("func foo(bar: (Int, String, Float) -> Void)\n"), + Example("func foo(bar: (Int, String, Float) throws -> Void)\n"), + Example("var completionHandler: ((_ data: Data?, _ resp: URLResponse?, _ e: NSError?) -> Void)!\n"), + Example("func getDictionaryAndInt() -> (Dictionary, Int)?\n"), + Example("func getGenericTypeAndInt() -> (Type, Int)?\n") ], triggeringExamples: [ - "↓let foo: (Int, Int, Int)\n", - "↓let foo: (start: Int, end: Int, value: String)\n", - "↓let foo: (Int, (Int, Int, Int))\n", - "func foo(↓bar: (Int, Int, Int))\n", - "func foo() -> ↓(Int, Int, Int)\n", - "func foo() -> ↓(Int, Int, Int) {}\n", - "func foo(bar: String) -> ↓(Int, Int, Int)\n", - "func foo(bar: String) -> ↓(Int, Int, Int) {}\n", - "func foo() throws -> ↓(Int, Int, Int)\n", - "func foo() throws -> ↓(Int, Int, Int) {}\n", - "func foo() throws -> ↓(Int, ↓(String, String, String), Int) {}\n", - "func getDictionaryAndInt() -> (Dictionary, Int)?\n" + Example("↓let foo: (Int, Int, Int)\n"), + Example("↓let foo: (start: Int, end: Int, value: String)\n"), + Example("↓let foo: (Int, (Int, Int, Int))\n"), + Example("func foo(↓bar: (Int, Int, Int))\n"), + Example("func foo() -> ↓(Int, Int, Int)\n"), + Example("func foo() -> ↓(Int, Int, Int) {}\n"), + Example("func foo(bar: String) -> ↓(Int, Int, Int)\n"), + Example("func foo(bar: String) -> ↓(Int, Int, Int) {}\n"), + Example("func foo() throws -> ↓(Int, Int, Int)\n"), + Example("func foo() throws -> ↓(Int, Int, Int) {}\n"), + Example("func foo() throws -> ↓(Int, ↓(String, String, String), Int) {}\n"), + Example("func getDictionaryAndInt() -> (Dictionary, Int)?\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/Metrics/LineLengthRule.swift index c3ba612d69..a1a6e08d5f 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/LineLengthRule.swift @@ -16,14 +16,14 @@ public struct LineLengthRule: ConfigurationProviderRule { description: "Lines should not span too many characters.", kind: .metrics, nonTriggeringExamples: [ - String(repeating: "/", count: 120) + "\n", - String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 120) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n" + Example(String(repeating: "/", count: 120) + "\n"), + Example(String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 120) + "\n"), + Example(String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n") ], triggeringExamples: [ - String(repeating: "/", count: 121) + "\n", - String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 121) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n" + Example(String(repeating: "/", count: 121) + "\n"), + Example(String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 121) + "\n"), + Example(String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/NestingRule.swift b/Source/SwiftLintFramework/Rules/Metrics/NestingRule.swift index fa13522b52..da102dc83d 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/NestingRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/NestingRule.swift @@ -14,18 +14,44 @@ public struct NestingRule: ASTRule, ConfigurationProviderRule, AutomaticTestable description: "Types should be nested at most 1 level deep, " + "and statements should be nested at most 5 levels deep.", kind: .metrics, - nonTriggeringExamples: ["class", "struct", "enum"].flatMap { kind -> [String] in + nonTriggeringExamples: ["class", "struct", "enum"].flatMap { kind -> [Example] in [ - "\(kind) Class0 { \(kind) Class1 {} }\n", - "func func0() {\nfunc func1() {\nfunc func2() {\nfunc func3() {\nfunc func4() { " + - "func func5() {\n}\n}\n}\n}\n}\n}\n" + Example("\(kind) Class0 { \(kind) Class1 {} }\n"), + Example(""" + func func0() { + func func1() { + func func2() { + func func3() { + func func4() { + func func5() { + } + } + } + } + } + } + """) ] - } + ["enum Enum0 { enum Enum1 { case Case } }"], - triggeringExamples: ["class", "struct", "enum"].map { kind -> String in - return "\(kind) A { \(kind) B { ↓\(kind) C {} } }\n" + } + [Example("enum Enum0 { enum Enum1 { case Case } }")], + triggeringExamples: ["class", "struct", "enum"].map { kind -> Example in + return Example("\(kind) A { \(kind) B { ↓\(kind) C {} } }\n") } + [ - "func func0() {\nfunc func1() {\nfunc func2() {\nfunc func3() {\nfunc func4() { " + - "func func5() {\n↓func func6() {\n}\n}\n}\n}\n}\n}\n}\n" + Example(""" + func func0() { + func func1() { + func func2() { + func func3() { + func func4() { + func func5() { + ↓func func6() { + } + } + } + } + } + } + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Metrics/TypeBodyLengthRule.swift b/Source/SwiftLintFramework/Rules/Metrics/TypeBodyLengthRule.swift index 7dd1f1b01b..9100864312 100644 --- a/Source/SwiftLintFramework/Rules/Metrics/TypeBodyLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/Metrics/TypeBodyLengthRule.swift @@ -1,11 +1,15 @@ import SourceKittenFramework -private func example(_ type: String, - _ template: String, - _ count: Int, - _ add: String = "") -> String { - return "\(type) Abc {\n" + - repeatElement(template, count: count).joined() + "\(add)}\n" +private func wrapExample( + prefix: String = "", + _ type: String, + _ template: String, + _ count: Int, + _ add: String = "", + file: StaticString = #file, + line: UInt = #line) -> Example { + return Example("\(prefix)\(type) Abc {\n" + + repeatElement(template, count: count).joined() + "\(add)}\n") } public struct TypeBodyLengthRule: ASTRule, ConfigurationProviderRule, AutomaticTestableRule { @@ -20,14 +24,14 @@ public struct TypeBodyLengthRule: ASTRule, ConfigurationProviderRule, AutomaticT kind: .metrics, nonTriggeringExamples: ["class", "struct", "enum"].flatMap({ type in [ - example(type, "let abc = 0\n", 199), - example(type, "\n", 201), - example(type, "// this is a comment\n", 201), - example(type, "let abc = 0\n", 199, "\n/* this is\na multiline comment\n*/\n") + wrapExample(type, "let abc = 0\n", 199), + wrapExample(type, "\n", 201), + wrapExample(type, "// this is a comment\n", 201), + wrapExample(type, "let abc = 0\n", 199, "\n/* this is\na multiline comment\n*/\n") ] }), triggeringExamples: ["class", "struct", "enum"].map({ type in - "↓" + example(type, "let abc = 0\n", 201) + wrapExample(prefix: "↓", type, "let abc = 0\n", 201) }) ) diff --git a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterCountRule.swift b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterCountRule.swift index b3024b5685..19d9593f13 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterCountRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterCountRule.swift @@ -12,20 +12,20 @@ public struct ContainsOverFilterCountRule: CallPairRule, OptInRule, Configuratio kind: .performance, nonTriggeringExamples: [">", "==", "!="].flatMap { operation in return [ - "let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 1\n", - "let result = myList.filter { $0 % 2 == 0 }.count \(operation) 1\n", - "let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 01\n" + Example("let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 1\n"), + Example("let result = myList.filter { $0 % 2 == 0 }.count \(operation) 1\n"), + Example("let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 01\n") ] } + [ - "let result = myList.contains(where: { $0 % 2 == 0 })\n", - "let result = !myList.contains(where: { $0 % 2 == 0 })\n", - "let result = myList.contains(10)\n" + Example("let result = myList.contains(where: { $0 % 2 == 0 })\n"), + Example("let result = !myList.contains(where: { $0 % 2 == 0 })\n"), + Example("let result = myList.contains(10)\n") ], triggeringExamples: [">", "==", "!="].flatMap { operation in return [ - "let result = ↓myList.filter(where: { $0 % 2 == 0 }).count \(operation) 0\n", - "let result = ↓myList.filter { $0 % 2 == 0 }.count \(operation) 0\n", - "let result = ↓myList.filter(where: someFunction).count \(operation) 0\n" + Example("let result = ↓myList.filter(where: { $0 % 2 == 0 }).count \(operation) 0\n"), + Example("let result = ↓myList.filter { $0 % 2 == 0 }.count \(operation) 0\n"), + Example("let result = ↓myList.filter(where: someFunction).count \(operation) 0\n") ] } ) diff --git a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterIsEmptyRule.swift b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterIsEmptyRule.swift index 6c691c2005..2737de4afd 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterIsEmptyRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFilterIsEmptyRule.swift @@ -12,19 +12,19 @@ public struct ContainsOverFilterIsEmptyRule: CallPairRule, OptInRule, Configurat kind: .performance, nonTriggeringExamples: [">", "==", "!="].flatMap { operation in return [ - "let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 1\n", - "let result = myList.filter { $0 % 2 == 0 }.count \(operation) 1\n" + Example("let result = myList.filter(where: { $0 % 2 == 0 }).count \(operation) 1\n"), + Example("let result = myList.filter { $0 % 2 == 0 }.count \(operation) 1\n") ] } + [ - "let result = myList.contains(where: { $0 % 2 == 0 })\n", - "let result = !myList.contains(where: { $0 % 2 == 0 })\n", - "let result = myList.contains(10)\n" + Example("let result = myList.contains(where: { $0 % 2 == 0 })\n"), + Example("let result = !myList.contains(where: { $0 % 2 == 0 })\n"), + Example("let result = myList.contains(10)\n") ], triggeringExamples: [ - "let result = ↓myList.filter(where: { $0 % 2 == 0 }).isEmpty\n", - "let result = !↓myList.filter(where: { $0 % 2 == 0 }).isEmpty\n", - "let result = ↓myList.filter { $0 % 2 == 0 }.isEmpty\n", - "let result = ↓myList.filter(where: someFunction).isEmpty\n" + Example("let result = ↓myList.filter(where: { $0 % 2 == 0 }).isEmpty\n"), + Example("let result = !↓myList.filter(where: { $0 % 2 == 0 }).isEmpty\n"), + Example("let result = ↓myList.filter { $0 % 2 == 0 }.isEmpty\n"), + Example("let result = ↓myList.filter(where: someFunction).isEmpty\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFirstNotNilRule.swift b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFirstNotNilRule.swift index 0be04ba9a3..02713bb998 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ContainsOverFirstNotNilRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ContainsOverFirstNotNilRule.swift @@ -12,19 +12,19 @@ public struct ContainsOverFirstNotNilRule: CallPairRule, OptInRule, Configuratio kind: .performance, nonTriggeringExamples: ["first", "firstIndex"].flatMap { method in return [ - "let \(method) = myList.\(method)(where: { $0 % 2 == 0 })\n", - "let \(method) = myList.\(method) { $0 % 2 == 0 }\n" + Example("let \(method) = myList.\(method)(where: { $0 % 2 == 0 })\n"), + Example("let \(method) = myList.\(method) { $0 % 2 == 0 }\n") ] }, triggeringExamples: ["first", "firstIndex"].flatMap { method in return ["!=", "=="].flatMap { comparison in return [ - "↓myList.\(method) { $0 % 2 == 0 } \(comparison) nil\n", - "↓myList.\(method)(where: { $0 % 2 == 0 }) \(comparison) nil\n", - "↓myList.map { $0 + 1 }.\(method)(where: { $0 % 2 == 0 }) \(comparison) nil\n", - "↓myList.\(method)(where: someFunction) \(comparison) nil\n", - "↓myList.map { $0 + 1 }.\(method) { $0 % 2 == 0 } \(comparison) nil\n", - "(↓myList.\(method) { $0 % 2 == 0 }) \(comparison) nil\n" + Example("↓myList.\(method) { $0 % 2 == 0 } \(comparison) nil\n"), + Example("↓myList.\(method)(where: { $0 % 2 == 0 }) \(comparison) nil\n"), + Example("↓myList.map { $0 + 1 }.\(method)(where: { $0 % 2 == 0 }) \(comparison) nil\n"), + Example("↓myList.\(method)(where: someFunction) \(comparison) nil\n"), + Example("↓myList.map { $0 + 1 }.\(method) { $0 % 2 == 0 } \(comparison) nil\n"), + Example("(↓myList.\(method) { $0 % 2 == 0 }) \(comparison) nil\n") ] } } diff --git a/Source/SwiftLintFramework/Rules/Performance/ContainsOverRangeNilComparisonRule.swift b/Source/SwiftLintFramework/Rules/Performance/ContainsOverRangeNilComparisonRule.swift index af80e9dd61..6c526f9ba5 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ContainsOverRangeNilComparisonRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ContainsOverRangeNilComparisonRule.swift @@ -12,14 +12,14 @@ public struct ContainsOverRangeNilComparisonRule: CallPairRule, OptInRule, Confi description: "Prefer `contains` over `range(of:) != nil` and `range(of:) == nil`.", kind: .performance, nonTriggeringExamples: [ - "let range = myString.range(of: \"Test\")", - "myString.contains(\"Test\")", - "!myString.contains(\"Test\")", - "resourceString.range(of: rule.regex, options: .regularExpression) != nil" + Example("let range = myString.range(of: \"Test\")"), + Example("myString.contains(\"Test\")"), + Example("!myString.contains(\"Test\")"), + Example("resourceString.range(of: rule.regex, options: .regularExpression) != nil") ], triggeringExamples: ["!=", "=="].flatMap { comparison in return [ - "↓myString.range(of: \"Test\") \(comparison) nil" + Example("↓myString.range(of: \"Test\") \(comparison) nil") ] } ) diff --git a/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift b/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift index 3c5ac96bf7..9ffbd7d227 100644 --- a/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift @@ -11,20 +11,20 @@ public struct EmptyCollectionLiteralRule: ConfigurationProviderRule, OptInRule, description: "Prefer checking `isEmpty` over comparing collection to an empty array or dictionary literal.", kind: .performance, nonTriggeringExamples: [ - "myArray = []", - "myArray.isEmpty", - "!myArray.isEmpty", - "myDict = [:]" + Example("myArray = []"), + Example("myArray.isEmpty"), + Example("!myArray.isEmpty"), + Example("myDict = [:]") ], triggeringExamples: [ - "myArray↓ == []", - "myArray↓ != []", - "myArray↓ == [ ]", - "myDict↓ == [:]", - "myDict↓ != [:]", - "myDict↓ == [: ]", - "myDict↓ == [ :]", - "myDict↓ == [ : ]" + Example("myArray↓ == []"), + Example("myArray↓ != []"), + Example("myArray↓ == [ ]"), + Example("myDict↓ == [:]"), + Example("myDict↓ != [:]"), + Example("myDict↓ == [: ]"), + Example("myDict↓ == [ :]"), + Example("myDict↓ == [ : ]") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/EmptyCountRule.swift b/Source/SwiftLintFramework/Rules/Performance/EmptyCountRule.swift index 349a88e7dd..a55111f504 100644 --- a/Source/SwiftLintFramework/Rules/Performance/EmptyCountRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/EmptyCountRule.swift @@ -11,25 +11,25 @@ public struct EmptyCountRule: ConfigurationProviderRule, OptInRule, AutomaticTes description: "Prefer checking `isEmpty` over comparing `count` to zero.", kind: .performance, nonTriggeringExamples: [ - "var count = 0\n", - "[Int]().isEmpty\n", - "[Int]().count > 1\n", - "[Int]().count == 1\n", - "[Int]().count == 0xff\n", - "[Int]().count == 0b01\n", - "[Int]().count == 0o07\n", - "discount == 0\n", - "order.discount == 0\n" + Example("var count = 0\n"), + Example("[Int]().isEmpty\n"), + Example("[Int]().count > 1\n"), + Example("[Int]().count == 1\n"), + Example("[Int]().count == 0xff\n"), + Example("[Int]().count == 0b01\n"), + Example("[Int]().count == 0o07\n"), + Example("discount == 0\n"), + Example("order.discount == 0\n") ], triggeringExamples: [ - "[Int]().↓count == 0\n", - "[Int]().↓count > 0\n", - "[Int]().↓count != 0\n", - "[Int]().↓count == 0x0\n", - "[Int]().↓count == 0x00_00\n", - "[Int]().↓count == 0b00\n", - "[Int]().↓count == 0o00\n", - "↓count == 0\n" + Example("[Int]().↓count == 0\n"), + Example("[Int]().↓count > 0\n"), + Example("[Int]().↓count != 0\n"), + Example("[Int]().↓count == 0x0\n"), + Example("[Int]().↓count == 0x00_00\n"), + Example("[Int]().↓count == 0b00\n"), + Example("[Int]().↓count == 0o00\n"), + Example("↓count == 0\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift b/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift index 5c1047a70e..1662df55ac 100644 --- a/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift @@ -11,12 +11,12 @@ public struct EmptyStringRule: ConfigurationProviderRule, OptInRule, AutomaticTe description: "Prefer checking `isEmpty` over comparing `string` to an empty string literal.", kind: .performance, nonTriggeringExamples: [ - "myString.isEmpty", - "!myString.isEmpty" + Example("myString.isEmpty"), + Example("!myString.isEmpty") ], triggeringExamples: [ - "myString↓ == \"\"", - "myString↓ != \"\"" + Example("myString↓ == \"\""), + Example("myString↓ != \"\"") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/FirstWhereRule.swift b/Source/SwiftLintFramework/Rules/Performance/FirstWhereRule.swift index 7c0d8efda2..14f2a45efc 100644 --- a/Source/SwiftLintFramework/Rules/Performance/FirstWhereRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/FirstWhereRule.swift @@ -11,22 +11,22 @@ public struct FirstWhereRule: CallPairRule, OptInRule, ConfigurationProviderRule description: "Prefer using `.first(where:)` over `.filter { }.first` in collections.", kind: .performance, nonTriggeringExamples: [ - "kinds.filter(excludingKinds.contains).isEmpty && kinds.first == .identifier\n", - "myList.first(where: { $0 % 2 == 0 })\n", - "match(pattern: pattern).filter { $0.first == .identifier }\n", - "(myList.filter { $0 == 1 }.suffix(2)).first\n", - "collection.filter(\"stringCol = '3'\").first", - "realm?.objects(User.self).filter(NSPredicate(format: \"email ==[c] %@\", email)).first", - "if let pause = timeTracker.pauses.filter(\"beginDate < %@\", beginDate).first { print(pause) }" + Example("kinds.filter(excludingKinds.contains).isEmpty && kinds.first == .identifier\n"), + Example("myList.first(where: { $0 % 2 == 0 })\n"), + Example("match(pattern: pattern).filter { $0.first == .identifier }\n"), + Example("(myList.filter { $0 == 1 }.suffix(2)).first\n"), + Example("collection.filter(\"stringCol = '3'\").first"), + Example("realm?.objects(User.self).filter(NSPredicate(format: \"email ==[c] %@\", email)).first"), + Example("if let pause = timeTracker.pauses.filter(\"beginDate < %@\", beginDate).first { print(pause) }") ], triggeringExamples: [ - "↓myList.filter { $0 % 2 == 0 }.first\n", - "↓myList.filter({ $0 % 2 == 0 }).first\n", - "↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first\n", - "↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first?.something()\n", - "↓myList.filter(someFunction).first\n", - "↓myList.filter({ $0 % 2 == 0 })\n.first\n", - "(↓myList.filter { $0 == 1 }).first\n" + Example("↓myList.filter { $0 % 2 == 0 }.first\n"), + Example("↓myList.filter({ $0 % 2 == 0 }).first\n"), + Example("↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first\n"), + Example("↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first?.something()\n"), + Example("↓myList.filter(someFunction).first\n"), + Example("↓myList.filter({ $0 % 2 == 0 })\n.first\n"), + Example("(↓myList.filter { $0 == 1 }).first\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/FlatMapOverMapReduceRule.swift b/Source/SwiftLintFramework/Rules/Performance/FlatMapOverMapReduceRule.swift index 70257e0695..cdb04f17c5 100644 --- a/Source/SwiftLintFramework/Rules/Performance/FlatMapOverMapReduceRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/FlatMapOverMapReduceRule.swift @@ -11,11 +11,11 @@ public struct FlatMapOverMapReduceRule: CallPairRule, OptInRule, ConfigurationPr description: "Prefer `flatMap` over `map` followed by `reduce([], +)`.", kind: .performance, nonTriggeringExamples: [ - "let foo = bar.map { $0.count }.reduce(0, +)", - "let foo = bar.flatMap { $0.array }" + Example("let foo = bar.map { $0.count }.reduce(0, +)"), + Example("let foo = bar.flatMap { $0.array }") ], triggeringExamples: [ - "let foo = ↓bar.map { $0.array }.reduce([], +)" + Example("let foo = ↓bar.map { $0.array }.reduce([], +)") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/LastWhereRule.swift b/Source/SwiftLintFramework/Rules/Performance/LastWhereRule.swift index 2b6dad8a0b..69f4492b7b 100644 --- a/Source/SwiftLintFramework/Rules/Performance/LastWhereRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/LastWhereRule.swift @@ -12,20 +12,20 @@ public struct LastWhereRule: CallPairRule, OptInRule, ConfigurationProviderRule, kind: .performance, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - "kinds.filter(excludingKinds.contains).isEmpty && kinds.last == .identifier\n", - "myList.last(where: { $0 % 2 == 0 })\n", - "match(pattern: pattern).filter { $0.last == .identifier }\n", - "(myList.filter { $0 == 1 }.suffix(2)).last\n", - "collection.filter(\"stringCol = '3'\").last" + Example("kinds.filter(excludingKinds.contains).isEmpty && kinds.last == .identifier\n"), + Example("myList.last(where: { $0 % 2 == 0 })\n"), + Example("match(pattern: pattern).filter { $0.last == .identifier }\n"), + Example("(myList.filter { $0 == 1 }.suffix(2)).last\n"), + Example("collection.filter(\"stringCol = '3'\").last") ], triggeringExamples: [ - "↓myList.filter { $0 % 2 == 0 }.last\n", - "↓myList.filter({ $0 % 2 == 0 }).last\n", - "↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).last\n", - "↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).last?.something()\n", - "↓myList.filter(someFunction).last\n", - "↓myList.filter({ $0 % 2 == 0 })\n.last\n", - "(↓myList.filter { $0 == 1 }).last\n" + Example("↓myList.filter { $0 % 2 == 0 }.last\n"), + Example("↓myList.filter({ $0 % 2 == 0 }).last\n"), + Example("↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).last\n"), + Example("↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).last?.something()\n"), + Example("↓myList.filter(someFunction).last\n"), + Example("↓myList.filter({ $0 % 2 == 0 })\n.last\n"), + Example("(↓myList.filter { $0 == 1 }).last\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/ReduceBooleanRule.swift b/Source/SwiftLintFramework/Rules/Performance/ReduceBooleanRule.swift index 4de4195943..6ad330cffd 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ReduceBooleanRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ReduceBooleanRule.swift @@ -12,18 +12,18 @@ public struct ReduceBooleanRule: Rule, ConfigurationProviderRule, AutomaticTesta kind: .performance, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - "nums.reduce(0) { $0.0 + $0.1 }", - "nums.reduce(0.0) { $0.0 + $0.1 }" + Example("nums.reduce(0) { $0.0 + $0.1 }"), + Example("nums.reduce(0.0) { $0.0 + $0.1 }") ], triggeringExamples: [ - "let allNines = nums.↓reduce(true) { $0.0 && $0.1 == 9 }", - "let anyNines = nums.↓reduce(false) { $0.0 || $0.1 == 9 }", - "let allValid = validators.↓reduce(true) { $0 && $1(input) }", - "let anyValid = validators.↓reduce(false) { $0 || $1(input) }", - "let allNines = nums.↓reduce(true, { $0.0 && $0.1 == 9 })", - "let anyNines = nums.↓reduce(false, { $0.0 || $0.1 == 9 })", - "let allValid = validators.↓reduce(true, { $0 && $1(input) })", - "let anyValid = validators.↓reduce(false, { $0 || $1(input) })" + Example("let allNines = nums.↓reduce(true) { $0.0 && $0.1 == 9 }"), + Example("let anyNines = nums.↓reduce(false) { $0.0 || $0.1 == 9 }"), + Example("let allValid = validators.↓reduce(true) { $0 && $1(input) }"), + Example("let anyValid = validators.↓reduce(false) { $0 || $1(input) }"), + Example("let allNines = nums.↓reduce(true, { $0.0 && $0.1 == 9 })"), + Example("let anyNines = nums.↓reduce(false, { $0.0 || $0.1 == 9 })"), + Example("let allValid = validators.↓reduce(true, { $0 && $1(input) })"), + Example("let anyValid = validators.↓reduce(false, { $0 || $1(input) })") ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/ReduceIntoRule.swift b/Source/SwiftLintFramework/Rules/Performance/ReduceIntoRule.swift index 3c5abb3c42..a015fe87e4 100644 --- a/Source/SwiftLintFramework/Rules/Performance/ReduceIntoRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/ReduceIntoRule.swift @@ -13,84 +13,84 @@ public struct ReduceIntoRule: ASTRule, ConfigurationProviderRule, OptInRule, Aut kind: .performance, minSwiftVersion: .four, nonTriggeringExamples: [ - """ + Example(""" let foo = values.reduce(into: "abc") { $0 += "\\($1)" } - """, - """ + """), + Example(""" values.reduce(into: Array()) { result, value in result.append(value) } - """, - """ + """), + Example(""" let rows = violations.enumerated().reduce(into: "") { rows, indexAndViolation in rows.append(generateSingleRow(for: indexAndViolation.1, at: indexAndViolation.0 + 1)) } - """, - """ + """), + Example(""" zip(group, group.dropFirst()).reduce(into: []) { result, pair in result.append(pair.0 + pair.1) } - """, - """ + """), + Example(""" let foo = values.reduce(into: [String: Int]()) { result, value in result["\\(value)"] = value } - """, - """ + """), + Example(""" let foo = values.reduce(into: Dictionary.init()) { result, value in result["\\(value)"] = value } - """, - """ + """), + Example(""" let foo = values.reduce(into: [Int](repeating: 0, count: 10)) { result, value in result.append(value) } - """, - """ + """), + Example(""" let foo = values.reduce(MyClass()) { result, value in result.handleValue(value) return result } - """ + """) ], triggeringExamples: [ - """ + Example(""" let bar = values.↓reduce("abc") { $0 + "\\($1)" } - """, - """ + """), + Example(""" values.↓reduce(Array()) { result, value in result += [value] } - """, - """ + """), + Example(""" let rows = violations.enumerated().↓reduce("") { rows, indexAndViolation in return rows + generateSingleRow(for: indexAndViolation.1, at: indexAndViolation.0 + 1) } - """, - """ + """), + Example(""" zip(group, group.dropFirst()).↓reduce([]) { result, pair in result + [pair.0 + pair.1] } - """, - """ + """), + Example(""" let foo = values.↓reduce([String: Int]()) { result, value in var result = result result["\\(value)"] = value return result } - """, - """ + """), + Example(""" let bar = values.↓reduce(Dictionary.init()) { result, value in var result = result result["\\(value)"] = value return result } - """, - """ + """), + Example(""" let bar = values.↓reduce([Int](repeating: 0, count: 10)) { result, value in return result + [value] } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Performance/SortedFirstLastRule.swift b/Source/SwiftLintFramework/Rules/Performance/SortedFirstLastRule.swift index 332ff633cc..0a372f7076 100644 --- a/Source/SwiftLintFramework/Rules/Performance/SortedFirstLastRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/SortedFirstLastRule.swift @@ -11,34 +11,34 @@ public struct SortedFirstLastRule: CallPairRule, OptInRule, ConfigurationProvide description: "Prefer using `min()` or `max()` over `sorted().first` or `sorted().last`", kind: .performance, nonTriggeringExamples: [ - "let min = myList.min()\n", - "let min = myList.min(by: { $0 < $1 })\n", - "let min = myList.min(by: >)\n", - "let max = myList.max()\n", - "let max = myList.max(by: { $0 < $1 })\n", - "let message = messages.sorted(byKeyPath: #keyPath(Message.timestamp)).last", - "let message = messages.sorted(byKeyPath: \"timestamp\", ascending: false).first", - "myList.sorted().firstIndex(of: key)", - "myList.sorted().lastIndex(of: key)", - "myList.sorted().firstIndex(where: someFunction)", - "myList.sorted().lastIndex(where: someFunction)", - "myList.sorted().firstIndex { $0 == key }", - "myList.sorted().lastIndex { $0 == key }" + Example("let min = myList.min()\n"), + Example("let min = myList.min(by: { $0 < $1 })\n"), + Example("let min = myList.min(by: >)\n"), + Example("let max = myList.max()\n"), + Example("let max = myList.max(by: { $0 < $1 })\n"), + Example("let message = messages.sorted(byKeyPath: #keyPath(Message.timestamp)).last"), + Example("let message = messages.sorted(byKeyPath: \"timestamp\", ascending: false).first"), + Example("myList.sorted().firstIndex(of: key)"), + Example("myList.sorted().lastIndex(of: key)"), + Example("myList.sorted().firstIndex(where: someFunction)"), + Example("myList.sorted().lastIndex(where: someFunction)"), + Example("myList.sorted().firstIndex { $0 == key }"), + Example("myList.sorted().lastIndex { $0 == key }") ], triggeringExamples: [ - "↓myList.sorted().first\n", - "↓myList.sorted(by: { $0.description < $1.description }).first\n", - "↓myList.sorted(by: >).first\n", - "↓myList.map { $0 + 1 }.sorted().first\n", - "↓myList.sorted(by: someFunction).first\n", - "↓myList.map { $0 + 1 }.sorted { $0.description < $1.description }.first\n", - "↓myList.sorted().last\n", - "↓myList.sorted().last?.something()\n", - "↓myList.sorted(by: { $0.description < $1.description }).last\n", - "↓myList.map { $0 + 1 }.sorted().last\n", - "↓myList.sorted(by: someFunction).last\n", - "↓myList.map { $0 + 1 }.sorted { $0.description < $1.description }.last\n", - "↓myList.map { $0 + 1 }.sorted { $0.first < $1.first }.last\n" + Example("↓myList.sorted().first\n"), + Example("↓myList.sorted(by: { $0.description < $1.description }).first\n"), + Example("↓myList.sorted(by: >).first\n"), + Example("↓myList.map { $0 + 1 }.sorted().first\n"), + Example("↓myList.sorted(by: someFunction).first\n"), + Example("↓myList.map { $0 + 1 }.sorted { $0.description < $1.description }.first\n"), + Example("↓myList.sorted().last\n"), + Example("↓myList.sorted().last?.something()\n"), + Example("↓myList.sorted(by: { $0.description < $1.description }).last\n"), + Example("↓myList.map { $0 + 1 }.sorted().last\n"), + Example("↓myList.sorted(by: someFunction).last\n"), + Example("↓myList.map { $0 + 1 }.sorted { $0.description < $1.description }.last\n"), + Example("↓myList.map { $0 + 1 }.sorted { $0.first < $1.first }.last\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/AttributesRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/AttributesRuleExamples.swift index fd6d6b692d..84c166bc6c 100644 --- a/Source/SwiftLintFramework/Rules/Style/AttributesRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/AttributesRuleExamples.swift @@ -1,85 +1,85 @@ internal struct AttributesRuleExamples { static let nonTriggeringExamples = [ - "@objc var x: String", - "@objc private var x: String", - "@nonobjc var x: String", - "@IBOutlet private var label: UILabel", - "@IBOutlet @objc private var label: UILabel", - "@NSCopying var name: NSString", - "@NSManaged var name: String?", - "@IBInspectable var cornerRadius: CGFloat", - "@available(iOS 9.0, *)\n let stackView: UIStackView", - "@NSManaged func addSomeObject(book: SomeObject)", - "@IBAction func buttonPressed(button: UIButton)", - "@objc\n @IBAction func buttonPressed(button: UIButton)", - "@available(iOS 9.0, *)\n func animate(view: UIStackView)", - "@available(iOS 9.0, *, message=\"A message\")\n func animate(view: UIStackView)", - "@nonobjc\n final class X", - "@available(iOS 9.0, *)\n class UIStackView", - "@NSApplicationMain\n class AppDelegate: NSObject, NSApplicationDelegate", - "@UIApplicationMain\n class AppDelegate: NSObject, UIApplicationDelegate", - "@IBDesignable\n class MyCustomView: UIView", - "@testable import SourceKittenFramework", - "@objc(foo_x)\n var x: String", - "@available(iOS 9.0, *)\n@objc(abc_stackView)\n let stackView: UIStackView", - "@objc(abc_addSomeObject:)\n @NSManaged func addSomeObject(book: SomeObject)", - "@objc(ABCThing)\n @available(iOS 9.0, *)\n class Thing", - "class Foo: NSObject {\n override var description: String { return \"\" }\n}", - "class Foo: NSObject {\n\n override func setUp() {}\n}", - "@objc\nclass ⽺ {}\n", + Example("@objc var x: String"), + Example("@objc private var x: String"), + Example("@nonobjc var x: String"), + Example("@IBOutlet private var label: UILabel"), + Example("@IBOutlet @objc private var label: UILabel"), + Example("@NSCopying var name: NSString"), + Example("@NSManaged var name: String?"), + Example("@IBInspectable var cornerRadius: CGFloat"), + Example("@available(iOS 9.0, *)\n let stackView: UIStackView"), + Example("@NSManaged func addSomeObject(book: SomeObject)"), + Example("@IBAction func buttonPressed(button: UIButton)"), + Example("@objc\n @IBAction func buttonPressed(button: UIButton)"), + Example("@available(iOS 9.0, *)\n func animate(view: UIStackView)"), + Example("@available(iOS 9.0, *, message=\"A message\")\n func animate(view: UIStackView)"), + Example("@nonobjc\n final class X"), + Example("@available(iOS 9.0, *)\n class UIStackView"), + Example("@NSApplicationMain\n class AppDelegate: NSObject, NSApplicationDelegate"), + Example("@UIApplicationMain\n class AppDelegate: NSObject, UIApplicationDelegate"), + Example("@IBDesignable\n class MyCustomView: UIView"), + Example("@testable import SourceKittenFramework"), + Example("@objc(foo_x)\n var x: String"), + Example("@available(iOS 9.0, *)\n@objc(abc_stackView)\n let stackView: UIStackView"), + Example("@objc(abc_addSomeObject:)\n @NSManaged func addSomeObject(book: SomeObject)"), + Example("@objc(ABCThing)\n @available(iOS 9.0, *)\n class Thing"), + Example("class Foo: NSObject {\n override var description: String { return \"\" }\n}"), + Example("class Foo: NSObject {\n\n override func setUp() {}\n}"), + Example("@objc\nclass ⽺ {}\n"), // attribute with allowed empty new line above - "extension Property {\n\n @available(*, unavailable, renamed: \"isOptional\")\n" + - "public var optional: Bool { fatalError() }\n}", - "@GKInspectable var maxSpeed: Float", - "@discardableResult\n func a() -> Int", - "@objc\n @discardableResult\n func a() -> Int", - "func increase(f: @autoclosure () -> Int) -> Int", - "func foo(completionHandler: @escaping () -> Void)", - "private struct DefaultError: Error {}", - "@testable import foo\n\nprivate let bar = 1", - """ + Example("extension Property {\n\n @available(*, unavailable, renamed: \"isOptional\")\n" + + "public var optional: Bool { fatalError() }\n}"), + Example("@GKInspectable var maxSpeed: Float"), + Example("@discardableResult\n func a() -> Int"), + Example("@objc\n @discardableResult\n func a() -> Int"), + Example("func increase(f: @autoclosure () -> Int) -> Int"), + Example("func foo(completionHandler: @escaping () -> Void)"), + Example("private struct DefaultError: Error {}"), + Example("@testable import foo\n\nprivate let bar = 1"), + Example(""" import XCTest @testable import DeleteMe @available (iOS 11.0, *) class DeleteMeTests: XCTestCase { } - """ + """) ] static let triggeringExamples = [ - "@objc\n ↓var x: String", - "@objc\n\n ↓var x: String", - "@objc\n private ↓var x: String", - "@nonobjc\n ↓var x: String", - "@IBOutlet\n private ↓var label: UILabel", - "@IBOutlet\n\n private ↓var label: UILabel", - "@NSCopying\n ↓var name: NSString", - "@NSManaged\n ↓var name: String?", - "@IBInspectable\n ↓var cornerRadius: CGFloat", - "@available(iOS 9.0, *) ↓let stackView: UIStackView", - "@NSManaged\n ↓func addSomeObject(book: SomeObject)", - "@IBAction\n ↓func buttonPressed(button: UIButton)", - "@IBAction\n @objc\n ↓func buttonPressed(button: UIButton)", - "@available(iOS 9.0, *) ↓func animate(view: UIStackView)", - "@nonobjc final ↓class X", - "@available(iOS 9.0, *) ↓class UIStackView", - "@available(iOS 9.0, *)\n @objc ↓class UIStackView", - "@available(iOS 9.0, *) @objc\n ↓class UIStackView", - "@available(iOS 9.0, *)\n\n ↓class UIStackView", - "@UIApplicationMain ↓class AppDelegate: NSObject, UIApplicationDelegate", - "@IBDesignable ↓class MyCustomView: UIView", - "@testable\n↓import SourceKittenFramework", - "@testable\n\n\n↓import SourceKittenFramework", - "@objc(foo_x) ↓var x: String", - "@available(iOS 9.0, *) @objc(abc_stackView)\n ↓let stackView: UIStackView", - "@objc(abc_addSomeObject:) @NSManaged\n ↓func addSomeObject(book: SomeObject)", - "@objc(abc_addSomeObject:)\n @NSManaged\n ↓func addSomeObject(book: SomeObject)", - "@available(iOS 9.0, *)\n @objc(ABCThing) ↓class Thing", - "@GKInspectable\n ↓var maxSpeed: Float", - "@discardableResult ↓func a() -> Int", - "@objc\n @discardableResult ↓func a() -> Int", - "@objc\n\n @discardableResult\n ↓func a() -> Int" + Example("@objc\n ↓var x: String"), + Example("@objc\n\n ↓var x: String"), + Example("@objc\n private ↓var x: String"), + Example("@nonobjc\n ↓var x: String"), + Example("@IBOutlet\n private ↓var label: UILabel"), + Example("@IBOutlet\n\n private ↓var label: UILabel"), + Example("@NSCopying\n ↓var name: NSString"), + Example("@NSManaged\n ↓var name: String?"), + Example("@IBInspectable\n ↓var cornerRadius: CGFloat"), + Example("@available(iOS 9.0, *) ↓let stackView: UIStackView"), + Example("@NSManaged\n ↓func addSomeObject(book: SomeObject)"), + Example("@IBAction\n ↓func buttonPressed(button: UIButton)"), + Example("@IBAction\n @objc\n ↓func buttonPressed(button: UIButton)"), + Example("@available(iOS 9.0, *) ↓func animate(view: UIStackView)"), + Example("@nonobjc final ↓class X"), + Example("@available(iOS 9.0, *) ↓class UIStackView"), + Example("@available(iOS 9.0, *)\n @objc ↓class UIStackView"), + Example("@available(iOS 9.0, *) @objc\n ↓class UIStackView"), + Example("@available(iOS 9.0, *)\n\n ↓class UIStackView"), + Example("@UIApplicationMain ↓class AppDelegate: NSObject, UIApplicationDelegate"), + Example("@IBDesignable ↓class MyCustomView: UIView"), + Example("@testable\n↓import SourceKittenFramework"), + Example("@testable\n\n\n↓import SourceKittenFramework"), + Example("@objc(foo_x) ↓var x: String"), + Example("@available(iOS 9.0, *) @objc(abc_stackView)\n ↓let stackView: UIStackView"), + Example("@objc(abc_addSomeObject:) @NSManaged\n ↓func addSomeObject(book: SomeObject)"), + Example("@objc(abc_addSomeObject:)\n @NSManaged\n ↓func addSomeObject(book: SomeObject)"), + Example("@available(iOS 9.0, *)\n @objc(ABCThing) ↓class Thing"), + Example("@GKInspectable\n ↓var maxSpeed: Float"), + Example("@discardableResult ↓func a() -> Int"), + Example("@objc\n @discardableResult ↓func a() -> Int"), + Example("@objc\n\n @discardableResult\n ↓func a() -> Int") ] } diff --git a/Source/SwiftLintFramework/Rules/Style/ClosingBraceRule.swift b/Source/SwiftLintFramework/Rules/Style/ClosingBraceRule.swift index 6a72134331..9414213d58 100644 --- a/Source/SwiftLintFramework/Rules/Style/ClosingBraceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ClosingBraceRule.swift @@ -13,15 +13,15 @@ public struct ClosingBraceRule: SubstitutionCorrectableRule, ConfigurationProvid "should not have any whitespaces in the middle.", kind: .style, nonTriggeringExamples: [ - "[].map({ })", - "[].map(\n { }\n)" + Example("[].map({ })"), + Example("[].map(\n { }\n)") ], triggeringExamples: [ - "[].map({ ↓} )", - "[].map({ ↓}\t)" + Example("[].map({ ↓} )"), + Example("[].map({ ↓}\t)") ], corrections: [ - "[].map({ ↓} )\n": "[].map({ })\n" + Example("[].map({ ↓} )\n"): Example("[].map({ })\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ClosureEndIndentationRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/ClosureEndIndentationRuleExamples.swift index 9e07fbbcf8..35ac46966f 100644 --- a/Source/SwiftLintFramework/Rules/Style/ClosureEndIndentationRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/ClosureEndIndentationRuleExamples.swift @@ -1,183 +1,172 @@ internal struct ClosureEndIndentationRuleExamples { static let nonTriggeringExamples = [ - "SignalProducer(values: [1, 2, 3])\n" + + Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + - " }\n", - "[1, 2].map { $0 + 1 }\n", - "return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + + " }\n"), + Example("[1, 2].map { $0 + 1 }\n"), + Example("return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + " return Command(string: contents, range: range)\n" + "}.flatMap { command in\n" + " return command.expand()\n" + - "}\n", - "foo(foo: bar,\n" + - " options: baz) { _ in }\n", - "someReallyLongProperty.chainingWithAnotherProperty\n" + - " .foo { _ in }", - "foo(abc, 123)\n" + - "{ _ in }\n", - "function(\n" + + "}\n"), + Example("foo(foo: bar,\n" + + " options: baz) { _ in }\n"), + Example("someReallyLongProperty.chainingWithAnotherProperty\n" + + " .foo { _ in }"), + Example("foo(abc, 123)\n" + + "{ _ in }\n"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })", - "function(parameter: param,\n" + + " })"), + Example("function(parameter: param,\n" + " closure: { x in\n" + " print(x)\n" + - "})", - "function(parameter: param, closure: { x in\n" + + "})"), + Example("function(parameter: param, closure: { x in\n" + " print(x)\n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })" + " })") ] static let triggeringExamples = [ - "SignalProducer(values: [1, 2, 3])\n" + + Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + - "↓}\n", - "return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + + "↓}\n"), + Example("return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + " return Command(string: contents, range: range)\n" + " ↓}.flatMap { command in\n" + " return command.expand()\n" + - "↓}\n", - "function(\n" + + "↓}\n"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "↓},\n" + " anotherClosure: { y in\n" + " print(y)\n" + - "↓})" + "↓})") ] static let corrections = [ - "SignalProducer(values: [1, 2, 3])\n" + + Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + - "↓}\n": - "SignalProducer(values: [1, 2, 3])\n" + + "↓}\n"): Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + - " }\n", - "SignalProducer(values: [1, 2, 3])\n" + + " }\n"), + Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + "↓}.another { x in\n" + " print(x)\n" + "↓}.yetAnother { y in\n" + " print(y)\n" + - "↓})": - "SignalProducer(values: [1, 2, 3])\n" + + "↓})"): Example("SignalProducer(values: [1, 2, 3])\n" + " .startWithNext { number in\n" + " print(number)\n" + " }.another { x in\n" + " print(x)\n" + " }.yetAnother { y in\n" + " print(y)\n" + - " })", - "return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + + " })"), + Example("return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + " return Command(string: contents, range: range)\n" + "↓ }.flatMap { command in\n" + " return command.expand()\n" + - "↓}\n": - "return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + + "↓}\n"): Example("return match(pattern: pattern, with: [.comment]).flatMap { range in\n" + " return Command(string: contents, range: range)\n" + "}.flatMap { command in\n" + " return command.expand()\n" + - "}\n", - "function(\n" + + "}\n"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + - "↓})": - "function(\n" + + "↓})"): Example("function(\n" + " closure: { x in\n" + " print(x)\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + - "↓ print(x) })": - "function(\n" + + "↓ print(x) })"): Example("function(\n" + " closure: { x in\n" + " print(x) \n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + - "↓ab})": - "function(\n" + + "↓ab})"): Example("function(\n" + " closure: { x in\n" + "ab\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "↓},\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })": - "function(\n" + + " })"): Example("function(\n" + " closure: { x in\n" + " print(x)\n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "↓ },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })": - "function(\n" + + " })"): Example("function(\n" + " closure: { x in\n" + " print(x)\n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "↓ab},\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })": - "function(\n" + + " })"): Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "ab\n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + "↓ print(x) },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })": - "function(\n" + + " })"): Example("function(\n" + " closure: { x in\n" + " print(x) \n" + " },\n" + " anotherClosure: { y in\n" + " print(y)\n" + - " })", - "function(\n" + + " })"), + Example("function(\n" + " closure: { x in\n" + " print(x)\n" + "↓}, anotherClosure: { y in\n" + " print(y)\n" + - "↓})": - "function(\n" + + "↓})"): Example("function(\n" + " closure: { x in\n" + " print(x)\n" + " }, anotherClosure: { y in\n" + " print(y)\n" + - " })" + " })") ] } diff --git a/Source/SwiftLintFramework/Rules/Style/ClosureParameterPositionRule.swift b/Source/SwiftLintFramework/Rules/Style/ClosureParameterPositionRule.swift index 180ad8e4c6..bb202e03a2 100644 --- a/Source/SwiftLintFramework/Rules/Style/ClosureParameterPositionRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ClosureParameterPositionRule.swift @@ -12,32 +12,36 @@ public struct ClosureParameterPositionRule: ASTRule, ConfigurationProviderRule, description: "Closure parameters should be on the same line as opening brace.", kind: .style, nonTriggeringExamples: [ - "[1, 2].map { $0 + 1 }\n", - "[1, 2].map({ $0 + 1 })\n", - "[1, 2].map { number in\n number + 1 \n}\n", - "[1, 2].map { number -> Int in\n number + 1 \n}\n", - "[1, 2].map { (number: Int) -> Int in\n number + 1 \n}\n", - "[1, 2].map { [weak self] number in\n number + 1 \n}\n", - "[1, 2].something(closure: { number in\n number + 1 \n})\n", - "let isEmpty = [1, 2].isEmpty()\n", - "rlmConfiguration.migrationBlock.map { rlmMigration in\n" + - "return { migration, schemaVersion in\n" + - "rlmMigration(migration.rlmMigration, schemaVersion)\n" + - "}\n" + - "}", - "let mediaView: UIView = { [weak self] index in\n" + - " return UIView()\n" + - "}(index)\n" + Example("[1, 2].map { $0 + 1 }\n"), + Example("[1, 2].map({ $0 + 1 })\n"), + Example("[1, 2].map { number in\n number + 1 \n}\n"), + Example("[1, 2].map { number -> Int in\n number + 1 \n}\n"), + Example("[1, 2].map { (number: Int) -> Int in\n number + 1 \n}\n"), + Example("[1, 2].map { [weak self] number in\n number + 1 \n}\n"), + Example("[1, 2].something(closure: { number in\n number + 1 \n})\n"), + Example("let isEmpty = [1, 2].isEmpty()\n"), + Example(""" + rlmConfiguration.migrationBlock.map { rlmMigration in + return { migration, schemaVersion in + rlmMigration(migration.rlmMigration, schemaVersion) + } + } + """), + Example(""" + let mediaView: UIView = { [weak self] index in + return UIView() + }(index) + """) ], triggeringExamples: [ - "[1, 2].map {\n ↓number in\n number + 1 \n}\n", - "[1, 2].map {\n ↓number -> Int in\n number + 1 \n}\n", - "[1, 2].map {\n (↓number: Int) -> Int in\n number + 1 \n}\n", - "[1, 2].map {\n [weak self] ↓number in\n number + 1 \n}\n", - "[1, 2].map { [weak self]\n ↓number in\n number + 1 \n}\n", - "[1, 2].map({\n ↓number in\n number + 1 \n})\n", - "[1, 2].something(closure: {\n ↓number in\n number + 1 \n})\n", - "[1, 2].reduce(0) {\n ↓sum, ↓number in\n number + sum \n}\n" + Example("[1, 2].map {\n ↓number in\n number + 1 \n}\n"), + Example("[1, 2].map {\n ↓number -> Int in\n number + 1 \n}\n"), + Example("[1, 2].map {\n (↓number: Int) -> Int in\n number + 1 \n}\n"), + Example("[1, 2].map {\n [weak self] ↓number in\n number + 1 \n}\n"), + Example("[1, 2].map { [weak self]\n ↓number in\n number + 1 \n}\n"), + Example("[1, 2].map({\n ↓number in\n number + 1 \n})\n"), + Example("[1, 2].something(closure: {\n ↓number in\n number + 1 \n})\n"), + Example("[1, 2].reduce(0) {\n ↓sum, ↓number in\n number + sum \n}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ClosureSpacingRule.swift b/Source/SwiftLintFramework/Rules/Style/ClosureSpacingRule.swift index 91203c0d6c..4132bf7e65 100644 --- a/Source/SwiftLintFramework/Rules/Style/ClosureSpacingRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ClosureSpacingRule.swift @@ -27,33 +27,33 @@ public struct ClosureSpacingRule: CorrectableRule, ConfigurationProviderRule, Op description: "Closure expressions should have a single space inside each brace.", kind: .style, nonTriggeringExamples: [ - "[].map ({ $0.description })", - "[].filter { $0.contains(location) }", - "extension UITableViewCell: ReusableView { }", - "extension UITableViewCell: ReusableView {}" + Example("[].map ({ $0.description })"), + Example("[].filter { $0.contains(location) }"), + Example("extension UITableViewCell: ReusableView { }"), + Example("extension UITableViewCell: ReusableView {}") ], triggeringExamples: [ - "[].filter(↓{$0.contains(location)})", - "[].map(↓{$0})", - "(↓{each in return result.contains(where: ↓{e in return e}) }).count", - "filter ↓{ sorted ↓{ $0 < $1}}" + Example("[].filter(↓{$0.contains(location)})"), + Example("[].map(↓{$0})"), + Example("(↓{each in return result.contains(where: ↓{e in return e}) }).count"), + Example("filter ↓{ sorted ↓{ $0 < $1}}") ], corrections: [ - "[].filter(↓{$0.contains(location)})": - "[].filter({ $0.contains(location) })", - "[].map(↓{$0})": - "[].map({ $0 })", + Example("[].filter(↓{$0.contains(location)})"): + Example("[].filter({ $0.contains(location) })"), + Example("[].map(↓{$0})"): + Example("[].map({ $0 })"), // Nested braces `{ {} }` do not get corrected on the first pass. - "filter ↓{sorted { $0 < $1}}": - "filter { sorted { $0 < $1} }", + Example("filter ↓{sorted { $0 < $1}}"): + Example("filter { sorted { $0 < $1} }"), // The user has to run tool again to fix remaining nested violations. - "filter { sorted ↓{ $0 < $1} }": - "filter { sorted { $0 < $1 } }", - "(↓{each in return result.contains(where: {e in return 0})}).count": - "({ each in return result.contains(where: {e in return 0}) }).count", + Example("filter { sorted ↓{ $0 < $1} }"): + Example("filter { sorted { $0 < $1 } }"), + Example("(↓{each in return result.contains(where: {e in return 0})}).count"): + Example("({ each in return result.contains(where: {e in return 0}) }).count"), // second pass example - "({ each in return result.contains(where: ↓{e in return 0}) }).count": - "({ each in return result.contains(where: { e in return 0 }) }).count" + Example("({ each in return result.contains(where: ↓{e in return 0}) }).count"): + Example("({ each in return result.contains(where: { e in return 0 }) }).count") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/CollectionAlignmentRule.swift b/Source/SwiftLintFramework/Rules/Style/CollectionAlignmentRule.swift index 4db242928b..7a926ad0b4 100644 --- a/Source/SwiftLintFramework/Rules/Style/CollectionAlignmentRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/CollectionAlignmentRule.swift @@ -107,27 +107,27 @@ extension CollectionAlignmentRule { self.alignColons = alignColons } - var triggeringExamples: [String] { + var triggeringExamples: [Example] { let examples = alignColons ? alignColonsTriggeringExamples : alignLeftTriggeringExamples return examples + sharedTriggeringExamples } - var nonTriggeringExamples: [String] { + var nonTriggeringExamples: [Example] { let examples = alignColons ? alignColonsNonTriggeringExamples : alignLeftNonTriggeringExamples return examples + sharedNonTriggeringExamples } - private var alignColonsTriggeringExamples: [String] { + private var alignColonsTriggeringExamples: [Example] { return [ - """ + Example(""" doThings(arg: [ "foo": 1, "bar": 2, "fizz"↓: 2, "buzz"↓: 2 ]) - """, - """ + """), + Example(""" let abc = [ "alpha": "a", "beta"↓: "b", @@ -135,28 +135,28 @@ extension CollectionAlignmentRule { "delta": "d", "epsilon"↓: "e" ] - """, - """ + """), + Example(""" var weirdColons = [ "a" : 1, "b" ↓:2, "c" : 3 ] - """ + """) ] } - private var alignColonsNonTriggeringExamples: [String] { + private var alignColonsNonTriggeringExamples: [Example] { return [ - """ + Example(""" doThings(arg: [ "foo": 1, "bar": 2, "fizz": 2, "buzz": 2 ]) - """, - """ + """), + Example(""" let abc = [ "alpha": "a", "beta": "b", @@ -164,28 +164,28 @@ extension CollectionAlignmentRule { "delta": "d", "epsilon": "e" ] - """, - """ + """), + Example(""" var weirdColons = [ "a" : 1, "b" :2, "c" : 3 ] - """ + """) ] } - private var alignLeftTriggeringExamples: [String] { + private var alignLeftTriggeringExamples: [Example] { return [ - """ + Example(""" doThings(arg: [ "foo": 1, "bar": 2, ↓"fizz": 2, ↓"buzz": 2 ]) - """, - """ + """), + Example(""" let abc = [ "alpha": "a", ↓"beta": "b", @@ -193,28 +193,28 @@ extension CollectionAlignmentRule { "delta": "d", ↓"epsilon": "e" ] - """, - """ + """), + Example(""" let meals = [ "breakfast": "oatmeal", "lunch": "sandwich", ↓"dinner": "burger" ] - """ + """) ] } - private var alignLeftNonTriggeringExamples: [String] { + private var alignLeftNonTriggeringExamples: [Example] { return [ - """ + Example(""" doThings(arg: [ "foo": 1, "bar": 2, "fizz": 2, "buzz": 2 ]) - """, - """ + """), + Example(""" let abc = [ "alpha": "a", "beta": "b", @@ -222,65 +222,65 @@ extension CollectionAlignmentRule { "delta": "d", "epsilon": "e" ] - """, - """ + """), + Example(""" let meals = [ "breakfast": "oatmeal", "lunch": "sandwich", "dinner": "burger" ] - """ + """) ] } - private var sharedTriggeringExamples: [String] { + private var sharedTriggeringExamples: [Example] { return [ - """ + Example(""" let coordinates = [ CLLocationCoordinate2D(latitude: 0, longitude: 33), ↓CLLocationCoordinate2D(latitude: 0, longitude: 66), CLLocationCoordinate2D(latitude: 0, longitude: 99) ] - """, - """ + """), + Example(""" var evenNumbers: Set = [ 2, ↓4, 6 ] - """ + """) ] } - private var sharedNonTriggeringExamples: [String] { + private var sharedNonTriggeringExamples: [Example] { return [ - """ + Example(""" let coordinates = [ CLLocationCoordinate2D(latitude: 0, longitude: 33), CLLocationCoordinate2D(latitude: 0, longitude: 66), CLLocationCoordinate2D(latitude: 0, longitude: 99) ] - """, - """ + """), + Example(""" var evenNumbers: Set = [ 2, 4, 6 ] - """, - """ + """), + Example(""" let abc = [1, 2, 3, 4] - """, - """ + """), + Example(""" let abc = [ 1, 2, 3, 4 ] - """, - """ + """), + Example(""" let abc = [ "foo": "bar", "fizz": "buzz" ] - """ + """) ] } } diff --git a/Source/SwiftLintFramework/Rules/Style/ColonRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/ColonRuleExamples.swift index 1d60e14569..8147dd05d7 100644 --- a/Source/SwiftLintFramework/Rules/Style/ColonRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/ColonRuleExamples.swift @@ -1,157 +1,165 @@ internal struct ColonRuleExamples { static let nonTriggeringExamples = [ - "let abc: Void\n", - "let abc: [Void: Void]\n", - "let abc: (Void, Void)\n", - "let abc: ([Void], String, Int)\n", - "let abc: [([Void], String, Int)]\n", - "let abc: String=\"def\"\n", - "let abc: Int=0\n", - "let abc: Enum=Enum.Value\n", - "func abc(def: Void) {}\n", - "func abc(def: Void, ghi: Void) {}\n", - "let abc: String = \"abc:\"", - "let abc = [Void: Void]()\n", - "let abc = [1: [3: 2], 3: 4]\n", - "let abc = [\"string\": \"string\"]\n", - "let abc = [\"string:string\": \"string\"]\n", - "let abc: [String: Int]\n", - "func foo(bar: [String: Int]) {}\n", - "func foo() -> [String: Int] { return [:] }\n", - "let abc: Any\n", - "let abc: [Any: Int]\n", - "let abc: [String: Any]\n", - "class Foo: Bar {}\n", - "class Foo: Bar {}\n", - "class Foo: Bar {}\n", - "class Foo: Bar {}\n", - "class Foo {}\n", - "switch foo {\n" + - "case .bar:\n" + - " _ = something()\n" + - "}\n", - "object.method(x: 5, y: \"string\")\n", - "object.method(x: 5, y:\n" + - " \"string\")", - "object.method(5, y: \"string\")\n", - "func abc() { def(ghi: jkl) }", - "func abc(def: Void) { ghi(jkl: mno) }", - "class ABC { let def = ghi(jkl: mno) } }", - "func foo() { let dict = [1: 1] }", - "let aaa = Self.bbb ? Self.ccc : Self.ddd else {\n" + - "return nil\n" + - "}\n" + Example("let abc: Void\n"), + Example("let abc: [Void: Void]\n"), + Example("let abc: (Void, Void)\n"), + Example("let abc: ([Void], String, Int)\n"), + Example("let abc: [([Void], String, Int)]\n"), + Example("let abc: String=\"def\"\n"), + Example("let abc: Int=0\n"), + Example("let abc: Enum=Enum.Value\n"), + Example("func abc(def: Void) {}\n"), + Example("func abc(def: Void, ghi: Void) {}\n"), + Example("let abc: String = \"abc:\""), + Example("let abc = [Void: Void]()\n"), + Example("let abc = [1: [3: 2], 3: 4]\n"), + Example("let abc = [\"string\": \"string\"]\n"), + Example("let abc = [\"string:string\": \"string\"]\n"), + Example("let abc: [String: Int]\n"), + Example("func foo(bar: [String: Int]) {}\n"), + Example("func foo() -> [String: Int] { return [:] }\n"), + Example("let abc: Any\n"), + Example("let abc: [Any: Int]\n"), + Example("let abc: [String: Any]\n"), + Example("class Foo: Bar {}\n"), + Example("class Foo: Bar {}\n"), + Example("class Foo: Bar {}\n"), + Example("class Foo: Bar {}\n"), + Example("class Foo {}\n"), + Example(""" + switch foo { + case .bar: + _ = something() + } + """), + Example("object.method(x: 5, y: \"string\")\n"), + Example(""" + object.method(x: 5, y: + "string") + """), + Example("object.method(5, y: \"string\")\n"), + Example("func abc() { def(ghi: jkl) }"), + Example("func abc(def: Void) { ghi(jkl: mno) }"), + Example("class ABC { let def = ghi(jkl: mno) } }"), + Example("func foo() { let dict = [1: 1] }"), + Example(""" + let aaa = Self.bbb ? Self.ccc : Self.ddd else { + return nil + Example("} + """) ] static let triggeringExamples = [ - "let ↓abc:Void\n", - "let ↓abc: Void\n", - "let ↓abc :Void\n", - "let ↓abc : Void\n", - "let ↓abc : [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n", - "let ↓abc: (Void, String, Int)\n", - "let ↓abc: ([Void], String, Int)\n", - "let ↓abc: [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n", - "let ↓abc :Int=0\n", - "let ↓abc :Int = 0\n", - "let ↓abc:Int=0\n", - "let ↓abc:Int = 0\n", - "let ↓abc:Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n", - "func abc(↓def: Void) {}\n", - "func abc(↓def :Void) {}\n", - "func abc(↓def : Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n", - "let abc = [Void↓:Void]()\n", - "let abc = [Void↓ : Void]()\n", - "let abc = [Void↓: Void]()\n", - "let abc = [Void↓ : Void]()\n", - "let abc = [1: [3↓ : 2], 3: 4]\n", - "let abc = [1: [3↓ : 2], 3↓: 4]\n", - "let abc: [↓String : Int]\n", - "let abc: [↓String:Int]\n", - "func foo(bar: [↓String : Int]) {}\n", - "func foo(bar: [↓String:Int]) {}\n", - "func foo() -> [↓String : Int] { return [:] }\n", - "func foo() -> [↓String:Int] { return [:] }\n", - "let ↓abc : Any\n", - "let abc: [↓Any : Int]\n", - "let abc: [↓String : Any]\n", - "class ↓Foo : Bar {}\n", - "class ↓Foo:Bar {}\n", - "class ↓Foo : Bar {}\n", - "class ↓Foo:Bar {}\n", - "class ↓Foo:Bar {}\n", - "class ↓Foo:Bar {}\n", - "class Foo<↓T:Equatable> {}\n", - "class Foo<↓T : Equatable> {}\n", - "object.method(x: 5, y↓ : \"string\")\n", - "object.method(x↓:5, y: \"string\")\n", - "object.method(x↓: 5, y: \"string\")\n", - "func abc() { def(ghi↓:jkl) }", - "func abc(def: Void) { ghi(jkl↓:mno) }", - "class ABC { let def = ghi(jkl↓:mno) } }", - "func foo() { let dict = [1↓ : 1] }" + Example("let ↓abc:Void\n"), + Example("let ↓abc: Void\n"), + Example("let ↓abc :Void\n"), + Example("let ↓abc : Void\n"), + Example("let ↓abc : [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"), + Example("let ↓abc: (Void, String, Int)\n"), + Example("let ↓abc: ([Void], String, Int)\n"), + Example("let ↓abc: [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"), + Example("let ↓abc :Int=0\n"), + Example("let ↓abc :Int = 0\n"), + Example("let ↓abc:Int=0\n"), + Example("let ↓abc:Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"), + Example("func abc(↓def: Void) {}\n"), + Example("func abc(↓def :Void) {}\n"), + Example("func abc(↓def : Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n"), + Example("let abc = [Void↓:Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"), + Example("let abc = [Void↓: Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n"), + Example("let abc = [1: [3↓ : 2], 3↓: 4]\n"), + Example("let abc: [↓String : Int]\n"), + Example("let abc: [↓String:Int]\n"), + Example("func foo(bar: [↓String : Int]) {}\n"), + Example("func foo(bar: [↓String:Int]) {}\n"), + Example("func foo() -> [↓String : Int] { return [:] }\n"), + Example("func foo() -> [↓String:Int] { return [:] }\n"), + Example("let ↓abc : Any\n"), + Example("let abc: [↓Any : Int]\n"), + Example("let abc: [↓String : Any]\n"), + Example("class ↓Foo : Bar {}\n"), + Example("class ↓Foo:Bar {}\n"), + Example("class ↓Foo : Bar {}\n"), + Example("class ↓Foo:Bar {}\n"), + Example("class ↓Foo:Bar {}\n"), + Example("class ↓Foo:Bar {}\n"), + Example("class Foo<↓T:Equatable> {}\n"), + Example("class Foo<↓T : Equatable> {}\n"), + Example("object.method(x: 5, y↓ : \"string\")\n"), + Example("object.method(x↓:5, y: \"string\")\n"), + Example("object.method(x↓: 5, y: \"string\")\n"), + Example("func abc() { def(ghi↓:jkl) }"), + Example("func abc(def: Void) { ghi(jkl↓:mno) }"), + Example("class ABC { let def = ghi(jkl↓:mno) } }"), + Example("func foo() { let dict = [1↓ : 1] }") ] static let corrections = [ - "let ↓abc:Void\n": "let abc: Void\n", - "let ↓abc: Void\n": "let abc: Void\n", - "let ↓abc :Void\n": "let abc: Void\n", - "let ↓abc : Void\n": "let abc: Void\n", - "let ↓abc : [Void: Void]\n": "let abc: [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n": "let abc: (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n": "let abc: ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n": "let abc: [([Void], String, Int)]\n", - "let ↓abc: (Void, String, Int)\n": "let abc: (Void, String, Int)\n", - "let ↓abc: ([Void], String, Int)\n": "let abc: ([Void], String, Int)\n", - "let ↓abc: [([Void], String, Int)]\n": "let abc: [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n": "let abc: String=\"def\"\n", - "let ↓abc :Int=0\n": "let abc: Int=0\n", - "let ↓abc :Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Int=0\n": "let abc: Int=0\n", - "let ↓abc:Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Enum=Enum.Value\n": "let abc: Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def: Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def :Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def : Void) {}\n": "func abc(def: Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n": "func abc(def: Void, ghi: Void) {}\n", - "let abc = [Void↓:Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [Void↓ : Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [Void↓: Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [Void↓ : Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [1: [3↓ : 2], 3: 4]\n": "let abc = [1: [3: 2], 3: 4]\n", - "let abc = [1: [3↓ : 2], 3↓: 4]\n": "let abc = [1: [3: 2], 3: 4]\n", - "let abc: [↓String : Int]\n": "let abc: [String: Int]\n", - "let abc: [↓String:Int]\n": "let abc: [String: Int]\n", - "func foo(bar: [↓String : Int]) {}\n": "func foo(bar: [String: Int]) {}\n", - "func foo(bar: [↓String:Int]) {}\n": "func foo(bar: [String: Int]) {}\n", - "func foo() -> [↓String : Int] { return [:] }\n": "func foo() -> [String: Int] { return [:] }\n", - "func foo() -> [↓String:Int] { return [:] }\n": "func foo() -> [String: Int] { return [:] }\n", - "let ↓abc : Any\n": "let abc: Any\n", - "let abc: [↓Any : Int]\n": "let abc: [Any: Int]\n", - "let abc: [↓String : Any]\n": "let abc: [String: Any]\n", - "class ↓Foo : Bar {}\n": "class Foo: Bar {}\n", - "class ↓Foo:Bar {}\n": "class Foo: Bar {}\n", - "class ↓Foo : Bar {}\n": "class Foo: Bar {}\n", - "class ↓Foo:Bar {}\n": "class Foo: Bar {}\n", - "class ↓Foo:Bar {}\n": "class Foo: Bar {}\n", - "class ↓Foo:Bar {}\n": "class Foo: Bar {}\n", - "class Foo<↓T:Equatable> {}\n": "class Foo {}\n", - "class Foo<↓T : Equatable> {}\n": "class Foo {}\n", - "object.method(x: 5, y↓ : \"string\")\n": "object.method(x: 5, y: \"string\")\n", - "object.method(x↓:5, y: \"string\")\n": "object.method(x: 5, y: \"string\")\n", - "object.method(x↓: 5, y: \"string\")\n": "object.method(x: 5, y: \"string\")\n", - "func abc() { def(ghi↓:jkl) }": "func abc() { def(ghi: jkl) }", - "func abc(def: Void) { ghi(jkl↓:mno) }": "func abc(def: Void) { ghi(jkl: mno) }", - "class ABC { let def = ghi(jkl↓:mno) } }": "class ABC { let def = ghi(jkl: mno) } }", - "func foo() { let dict = [1↓ : 1] }": "func foo() { let dict = [1: 1] }", - "class Foo {\n #if false\n #else\n let bar = [\"key\"↓ : \"value\"]\n #endif\n}": - "class Foo {\n #if false\n #else\n let bar = [\"key\": \"value\"]\n #endif\n}" + Example("let ↓abc:Void\n"): Example("let abc: Void\n"), + Example("let ↓abc: Void\n"): Example("let abc: Void\n"), + Example("let ↓abc :Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : [Void: Void]\n"): Example("let abc: [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"): Example("let abc: (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"): Example("let abc: ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"): Example("let abc: [([Void], String, Int)]\n"), + Example("let ↓abc: (Void, String, Int)\n"): Example("let abc: (Void, String, Int)\n"), + Example("let ↓abc: ([Void], String, Int)\n"): Example("let abc: ([Void], String, Int)\n"), + Example("let ↓abc: [([Void], String, Int)]\n"): Example("let abc: [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"): Example("let abc: String=\"def\"\n"), + Example("let ↓abc :Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc :Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc:Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"): Example("let abc: Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def: Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def :Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def : Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n"): Example("func abc(def: Void, ghi: Void) {}\n"), + Example("let abc = [Void↓:Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void↓: Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n"): Example("let abc = [1: [3: 2], 3: 4]\n"), + Example("let abc = [1: [3↓ : 2], 3↓: 4]\n"): Example("let abc = [1: [3: 2], 3: 4]\n"), + Example("let abc: [↓String : Int]\n"): Example("let abc: [String: Int]\n"), + Example("let abc: [↓String:Int]\n"): Example("let abc: [String: Int]\n"), + Example("func foo(bar: [↓String : Int]) {}\n"): Example("func foo(bar: [String: Int]) {}\n"), + Example("func foo(bar: [↓String:Int]) {}\n"): Example("func foo(bar: [String: Int]) {}\n"), + Example("func foo() -> [↓String : Int] { return [:] }\n"): + Example("func foo() -> [String: Int] { return [:] }\n"), + Example("func foo() -> [↓String:Int] { return [:] }\n"): + Example("func foo() -> [String: Int] { return [:] }\n"), + Example("let ↓abc : Any\n"): Example("let abc: Any\n"), + Example("let abc: [↓Any : Int]\n"): Example("let abc: [Any: Int]\n"), + Example("let abc: [↓String : Any]\n"): Example("let abc: [String: Any]\n"), + Example("class ↓Foo : Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class ↓Foo:Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class ↓Foo : Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class ↓Foo:Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class ↓Foo:Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class ↓Foo:Bar {}\n"): Example("class Foo: Bar {}\n"), + Example("class Foo<↓T:Equatable> {}\n"): Example("class Foo {}\n"), + Example("class Foo<↓T : Equatable> {}\n"): Example("class Foo {}\n"), + Example("object.method(x: 5, y↓ : \"string\")\n"): Example("object.method(x: 5, y: \"string\")\n"), + Example("object.method(x↓:5, y: \"string\")\n"): Example("object.method(x: 5, y: \"string\")\n"), + Example("object.method(x↓: 5, y: \"string\")\n"): Example("object.method(x: 5, y: \"string\")\n"), + Example("func abc() { def(ghi↓:jkl) }"): Example("func abc() { def(ghi: jkl) }"), + Example("func abc(def: Void) { ghi(jkl↓:mno) }"): Example("func abc(def: Void) { ghi(jkl: mno) }"), + Example("class ABC { let def = ghi(jkl↓:mno) } }"): Example("class ABC { let def = ghi(jkl: mno) } }"), + Example("func foo() { let dict = [1↓ : 1] }"): Example("func foo() { let dict = [1: 1] }"), + Example("class Foo {\n #if false\n #else\n let bar = [\"key\"↓ : \"value\"]\n #endif\n}"): + Example("class Foo {\n #if false\n #else\n let bar = [\"key\": \"value\"]\n #endif\n}") ] } diff --git a/Source/SwiftLintFramework/Rules/Style/CommaRule.swift b/Source/SwiftLintFramework/Rules/Style/CommaRule.swift index 5dcdb681b0..3dae8241b1 100644 --- a/Source/SwiftLintFramework/Rules/Style/CommaRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/CommaRule.swift @@ -12,27 +12,27 @@ public struct CommaRule: SubstitutionCorrectableRule, ConfigurationProviderRule, description: "There should be no space before and one after any comma.", kind: .style, nonTriggeringExamples: [ - "func abc(a: String, b: String) { }", - "abc(a: \"string\", b: \"string\"", - "enum a { case a, b, c }", - "func abc(\n a: String, // comment\n bcd: String // comment\n) {\n}\n", - "func abc(\n a: String,\n bcd: String\n) {\n}\n", - "#imageLiteral(resourceName: \"foo,bar,baz\")" + Example("func abc(a: String, b: String) { }"), + Example("abc(a: \"string\", b: \"string\""), + Example("enum a { case a, b, c }"), + Example("func abc(\n a: String, // comment\n bcd: String // comment\n) {\n}\n"), + Example("func abc(\n a: String,\n bcd: String\n) {\n}\n"), + Example("#imageLiteral(resourceName: \"foo,bar,baz\")") ], triggeringExamples: [ - "func abc(a: String↓ ,b: String) { }", - "func abc(a: String↓ ,b: String↓ ,c: String↓ ,d: String) { }", - "abc(a: \"string\"↓,b: \"string\"", - "enum a { case a↓ ,b }", - "let result = plus(\n first: 3↓ , // #683\n second: 4\n)\n" + Example("func abc(a: String↓ ,b: String) { }"), + Example("func abc(a: String↓ ,b: String↓ ,c: String↓ ,d: String) { }"), + Example("abc(a: \"string\"↓,b: \"string\""), + Example("enum a { case a↓ ,b }"), + Example("let result = plus(\n first: 3↓ , // #683\n second: 4\n)\n") ], corrections: [ - "func abc(a: String↓,b: String) {}\n": "func abc(a: String, b: String) {}\n", - "abc(a: \"string\"↓,b: \"string\"\n": "abc(a: \"string\", b: \"string\"\n", - "abc(a: \"string\"↓ , b: \"string\"\n": "abc(a: \"string\", b: \"string\"\n", - "enum a { case a↓ ,b }\n": "enum a { case a, b }\n", - "let a = [1↓,1]\nlet b = 1\nf(1, b)\n": "let a = [1, 1]\nlet b = 1\nf(1, b)\n", - "let a = [1↓,1↓,1↓,1]\n": "let a = [1, 1, 1, 1]\n" + Example("func abc(a: String↓,b: String) {}\n"): Example("func abc(a: String, b: String) {}\n"), + Example("abc(a: \"string\"↓,b: \"string\"\n"): Example("abc(a: \"string\", b: \"string\"\n"), + Example("abc(a: \"string\"↓ , b: \"string\"\n"): Example("abc(a: \"string\", b: \"string\"\n"), + Example("enum a { case a↓ ,b }\n"): Example("enum a { case a, b }\n"), + Example("let a = [1↓,1]\nlet b = 1\nf(1, b)\n"): Example("let a = [1, 1]\nlet b = 1\nf(1, b)\n"), + Example("let a = [1↓,1↓,1↓,1]\n"): Example("let a = [1, 1, 1, 1]\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ConditionalReturnsOnNewlineRule.swift b/Source/SwiftLintFramework/Rules/Style/ConditionalReturnsOnNewlineRule.swift index 5f8965858c..e558998e26 100644 --- a/Source/SwiftLintFramework/Rules/Style/ConditionalReturnsOnNewlineRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ConditionalReturnsOnNewlineRule.swift @@ -12,20 +12,20 @@ public struct ConditionalReturnsOnNewlineRule: ConfigurationProviderRule, Rule, description: "Conditional statements should always return on the next line", kind: .style, nonTriggeringExamples: [ - "guard true else {\n return true\n}", - "guard true,\n let x = true else {\n return true\n}", - "if true else {\n return true\n}", - "if true,\n let x = true else {\n return true\n}", - "if textField.returnKeyType == .Next {", - "if true { // return }", - "/*if true { */ return }" + Example("guard true else {\n return true\n}"), + Example("guard true,\n let x = true else {\n return true\n}"), + Example("if true else {\n return true\n}"), + Example("if true,\n let x = true else {\n return true\n}"), + Example("if textField.returnKeyType == .Next {"), + Example("if true { // return }"), + Example("/*if true { */ return }") ], triggeringExamples: [ - "↓guard true else { return }", - "↓if true { return }", - "↓if true { break } else { return }", - "↓if true { break } else { return }", - "↓if true { return \"YES\" } else { return \"NO\" }" + Example("↓guard true else { return }"), + Example("↓if true { return }"), + Example("↓if true { break } else { return }"), + Example("↓if true { break } else { return }"), + Example("↓if true { return \"YES\" } else { return \"NO\" }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ControlStatementRule.swift b/Source/SwiftLintFramework/Rules/Style/ControlStatementRule.swift index 8dfda32c26..eec41ee342 100644 --- a/Source/SwiftLintFramework/Rules/Style/ControlStatementRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ControlStatementRule.swift @@ -14,67 +14,69 @@ public struct ControlStatementRule: ConfigurationProviderRule, AutomaticTestable "conditionals or arguments in parentheses.", kind: .style, nonTriggeringExamples: [ - "if condition {\n", - "if (a, b) == (0, 1) {\n", - "if (a || b) && (c || d) {\n", - "if (min...max).contains(value) {\n", - "if renderGif(data) {\n", - "renderGif(data)\n", - "for item in collection {\n", - "for (key, value) in dictionary {\n", - "for (index, value) in enumerate(array) {\n", - "for var index = 0; index < 42; index++ {\n", - "guard condition else {\n", - "while condition {\n", - "} while condition {\n", - "do { ; } while condition {\n", - "switch foo {\n", - "do {\n} catch let error as NSError {\n}", - "foo().catch(all: true) {}", - "if max(a, b) < c {\n", - "switch (lhs, rhs) {\n" + Example("if condition {\n"), + Example("if (a, b) == (0, 1) {\n"), + Example("if (a || b) && (c || d) {\n"), + Example("if (min...max).contains(value) {\n"), + Example("if renderGif(data) {\n"), + Example("renderGif(data)\n"), + Example("for item in collection {\n"), + Example("for (key, value) in dictionary {\n"), + Example("for (index, value) in enumerate(array) {\n"), + Example("for var index = 0; index < 42; index++ {\n"), + Example("guard condition else {\n"), + Example("while condition {\n"), + Example("} while condition {\n"), + Example("do { ; } while condition {\n"), + Example("switch foo {\n"), + Example("do {\n} catch let error as NSError {\n}"), + Example("foo().catch(all: true) {}"), + Example("if max(a, b) < c {\n"), + Example("switch (lhs, rhs) {\n") ], triggeringExamples: [ - "↓if (condition) {\n", - "↓if(condition) {\n", - "↓if (condition == endIndex) {\n", - "↓if ((a || b) && (c || d)) {\n", - "↓if ((min...max).contains(value)) {\n", - "↓for (item in collection) {\n", - "↓for (var index = 0; index < 42; index++) {\n", - "↓for(item in collection) {\n", - "↓for(var index = 0; index < 42; index++) {\n", - "↓guard (condition) else {\n", - "↓while (condition) {\n", - "↓while(condition) {\n", - "} ↓while (condition) {\n", - "} ↓while(condition) {\n", - "do { ; } ↓while(condition) {\n", - "do { ; } ↓while (condition) {\n", - "↓switch (foo) {\n", - "do {\n} ↓catch(let error as NSError) {\n}", - "↓if (max(a, b) < c) {\n" + Example("↓if (condition) {\n"), + Example("↓if(condition) {\n"), + Example("↓if (condition == endIndex) {\n"), + Example("↓if ((a || b) && (c || d)) {\n"), + Example("↓if ((min...max).contains(value)) {\n"), + Example("↓for (item in collection) {\n"), + Example("↓for (var index = 0; index < 42; index++) {\n"), + Example("↓for(item in collection) {\n"), + Example("↓for(var index = 0; index < 42; index++) {\n"), + Example("↓guard (condition) else {\n"), + Example("↓while (condition) {\n"), + Example("↓while(condition) {\n"), + Example("} ↓while (condition) {\n"), + Example("} ↓while(condition) {\n"), + Example("do { ; } ↓while(condition) {\n"), + Example("do { ; } ↓while (condition) {\n"), + Example("↓switch (foo) {\n"), + Example("do {\n} ↓catch(let error as NSError) {\n}"), + Example("↓if (max(a, b) < c) {\n") ], corrections: [ - "↓if (condition) {\n": "if condition {\n", - "↓if(condition) {\n": "if condition {\n", - "↓if (condition == endIndex) {\n": "if condition == endIndex {\n", - "↓if ((a || b) && (c || d)) {\n": "if (a || b) && (c || d) {\n", - "↓if ((min...max).contains(value)) {\n": "if (min...max).contains(value) {\n", - "↓for (item in collection) {\n": "for item in collection {\n", - "↓for (var index = 0; index < 42; index++) {\n": "for var index = 0; index < 42; index++ {\n", - "↓for(item in collection) {\n": "for item in collection {\n", - "↓for(var index = 0; index < 42; index++) {\n": "for var index = 0; index < 42; index++ {\n", - "↓guard (condition) else {\n": "guard condition else {\n", - "↓while (condition) {\n": "while condition {\n", - "↓while(condition) {\n": "while condition {\n", - "} ↓while (condition) {\n": "} while condition {\n", - "} ↓while(condition) {\n": "} while condition {\n", - "do { ; } ↓while(condition) {\n": "do { ; } while condition {\n", - "do { ; } ↓while (condition) {\n": "do { ; } while condition {\n", - "↓switch (foo) {\n": "switch foo {\n", - "do {\n} ↓catch(let error as NSError) {\n}": "do {\n} catch let error as NSError {\n}", - "↓if (max(a, b) < c) {\n": "if max(a, b) < c {\n" + Example("↓if (condition) {\n"): Example("if condition {\n"), + Example("↓if(condition) {\n"): Example("if condition {\n"), + Example("↓if (condition == endIndex) {\n"): Example("if condition == endIndex {\n"), + Example("↓if ((a || b) && (c || d)) {\n"): Example("if (a || b) && (c || d) {\n"), + Example("↓if ((min...max).contains(value)) {\n"): Example("if (min...max).contains(value) {\n"), + Example("↓for (item in collection) {\n"): Example("for item in collection {\n"), + Example("↓for (var index = 0; index < 42; index++) {\n"): + Example("for var index = 0; index < 42; index++ {\n"), + Example("↓for(item in collection) {\n"): Example("for item in collection {\n"), + Example("↓for(var index = 0; index < 42; index++) {\n"): + Example("for var index = 0; index < 42; index++ {\n"), + Example("↓guard (condition) else {\n"): Example("guard condition else {\n"), + Example("↓while (condition) {\n"): Example("while condition {\n"), + Example("↓while(condition) {\n"): Example("while condition {\n"), + Example("} ↓while (condition) {\n"): Example("} while condition {\n"), + Example("} ↓while(condition) {\n"): Example("} while condition {\n"), + Example("do { ; } ↓while(condition) {\n"): Example("do { ; } while condition {\n"), + Example("do { ; } ↓while (condition) {\n"): Example("do { ; } while condition {\n"), + Example("↓switch (foo) {\n"): Example("switch foo {\n"), + Example("do {\n} ↓catch(let error as NSError) {\n}"): Example("do {\n} catch let error as NSError {\n}"), + Example("↓if (max(a, b) < c) {\n"): Example("if max(a, b) < c {\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/EmptyEnumArgumentsRule.swift b/Source/SwiftLintFramework/Rules/Style/EmptyEnumArgumentsRule.swift index 0bda13a818..ab6004dfca 100644 --- a/Source/SwiftLintFramework/Rules/Style/EmptyEnumArgumentsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/EmptyEnumArgumentsRule.swift @@ -1,21 +1,27 @@ import Foundation import SourceKittenFramework -private func wrapInSwitch(variable: String = "foo", _ str: String) -> String { - return "switch \(variable) {\n" + - " \(str): break\n" + - "}" +private func wrapInSwitch( + variable: String = "foo", + _ str: String, + file: StaticString = #file, line: UInt = #line) -> Example { + return Example( + """ + switch \(variable) { + \(str): break + } + """, file: file, line: line) } -private func wrapInFunc(_ str: String) -> String { - return """ +private func wrapInFunc(_ str: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" func example(foo: Foo) { switch foo { case \(str): break } } - """ + """, file: file, line: line) } public struct EmptyEnumArgumentsRule: SubstitutionCorrectableASTRule, ConfigurationProviderRule, AutomaticTestableRule { diff --git a/Source/SwiftLintFramework/Rules/Style/EmptyParametersRule.swift b/Source/SwiftLintFramework/Rules/Style/EmptyParametersRule.swift index f201736a4f..5a73b83a3a 100644 --- a/Source/SwiftLintFramework/Rules/Style/EmptyParametersRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/EmptyParametersRule.swift @@ -12,25 +12,25 @@ public struct EmptyParametersRule: ConfigurationProviderRule, SubstitutionCorrec description: "Prefer `() -> ` over `Void -> `.", kind: .style, nonTriggeringExamples: [ - "let abc: () -> Void = {}\n", - "func foo(completion: () -> Void)\n", - "func foo(completion: () thows -> Void)\n", - "let foo: (ConfigurationTests) -> Void throws -> Void)\n", - "let foo: (ConfigurationTests) -> Void throws -> Void)\n", - "let foo: (ConfigurationTests) ->Void throws -> Void)\n" + Example("let abc: () -> Void = {}\n"), + Example("func foo(completion: () -> Void)\n"), + Example("func foo(completion: () thows -> Void)\n"), + Example("let foo: (ConfigurationTests) -> Void throws -> Void)\n"), + Example("let foo: (ConfigurationTests) -> Void throws -> Void)\n"), + Example("let foo: (ConfigurationTests) ->Void throws -> Void)\n") ], triggeringExamples: [ - "let abc: ↓(Void) -> Void = {}\n", - "func foo(completion: ↓(Void) -> Void)\n", - "func foo(completion: ↓(Void) throws -> Void)\n", - "let foo: ↓(Void) -> () throws -> Void)\n" + Example("let abc: ↓(Void) -> Void = {}\n"), + Example("func foo(completion: ↓(Void) -> Void)\n"), + Example("func foo(completion: ↓(Void) throws -> Void)\n"), + Example("let foo: ↓(Void) -> () throws -> Void)\n") ], corrections: [ - "let abc: ↓(Void) -> Void = {}\n": "let abc: () -> Void = {}\n", - "func foo(completion: ↓(Void) -> Void)\n": "func foo(completion: () -> Void)\n", - "func foo(completion: ↓(Void) throws -> Void)\n": - "func foo(completion: () throws -> Void)\n", - "let foo: ↓(Void) -> () throws -> Void)\n": "let foo: () -> () throws -> Void)\n" + Example("let abc: ↓(Void) -> Void = {}\n"): Example("let abc: () -> Void = {}\n"), + Example("func foo(completion: ↓(Void) -> Void)\n"): Example("func foo(completion: () -> Void)\n"), + Example("func foo(completion: ↓(Void) throws -> Void)\n"): + Example("func foo(completion: () throws -> Void)\n"), + Example("let foo: ↓(Void) -> () throws -> Void)\n"): Example("let foo: () -> () throws -> Void)\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/EmptyParenthesesWithTrailingClosureRule.swift b/Source/SwiftLintFramework/Rules/Style/EmptyParenthesesWithTrailingClosureRule.swift index b7380174f3..1cc23a61d1 100644 --- a/Source/SwiftLintFramework/Rules/Style/EmptyParenthesesWithTrailingClosureRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/EmptyParenthesesWithTrailingClosureRule.swift @@ -14,33 +14,37 @@ public struct EmptyParenthesesWithTrailingClosureRule: SubstitutionCorrectableAS "after the method call.", kind: .style, nonTriggeringExamples: [ - "[1, 2].map { $0 + 1 }\n", - "[1, 2].map({ $0 + 1 })\n", - "[1, 2].reduce(0) { $0 + $1 }", - "[1, 2].map { number in\n number + 1 \n}\n", - "let isEmpty = [1, 2].isEmpty()\n", - "UIView.animateWithDuration(0.3, animations: {\n" + - " self.disableInteractionRightView.alpha = 0\n" + - "}, completion: { _ in\n" + - " ()\n" + - "})" + Example("[1, 2].map { $0 + 1 }\n"), + Example("[1, 2].map({ $0 + 1 })\n"), + Example("[1, 2].reduce(0) { $0 + $1 }"), + Example("[1, 2].map { number in\n number + 1 \n}\n"), + Example("let isEmpty = [1, 2].isEmpty()\n"), + Example(""" + UIView.animateWithDuration(0.3, animations: { + self.disableInteractionRightView.alpha = 0 + }, completion: { _ in + () + }) + """) ], triggeringExamples: [ - "[1, 2].map↓() { $0 + 1 }\n", - "[1, 2].map↓( ) { $0 + 1 }\n", - "[1, 2].map↓() { number in\n number + 1 \n}\n", - "[1, 2].map↓( ) { number in\n number + 1 \n}\n", - "func foo() -> [Int] {\n return [1, 2].map↓() { $0 + 1 }\n}\n" + Example("[1, 2].map↓() { $0 + 1 }\n"), + Example("[1, 2].map↓( ) { $0 + 1 }\n"), + Example("[1, 2].map↓() { number in\n number + 1 \n}\n"), + Example("[1, 2].map↓( ) { number in\n number + 1 \n}\n"), + Example("func foo() -> [Int] {\n return [1, 2].map↓() { $0 + 1 }\n}\n") ], corrections: [ - "[1, 2].map↓() { $0 + 1 }\n": "[1, 2].map { $0 + 1 }\n", - "[1, 2].map↓( ) { $0 + 1 }\n": "[1, 2].map { $0 + 1 }\n", - "[1, 2].map↓() { number in\n number + 1 \n}\n": "[1, 2].map { number in\n number + 1 \n}\n", - "[1, 2].map↓( ) { number in\n number + 1 \n}\n": "[1, 2].map { number in\n number + 1 \n}\n", - "func foo() -> [Int] {\n return [1, 2].map↓() { $0 + 1 }\n}\n": - "func foo() -> [Int] {\n return [1, 2].map { $0 + 1 }\n}\n", - "class C {\n#if true\nfunc f() {\n[1, 2].map↓() { $0 + 1 }\n}\n#endif\n}": - "class C {\n#if true\nfunc f() {\n[1, 2].map { $0 + 1 }\n}\n#endif\n}" + Example("[1, 2].map↓() { $0 + 1 }\n"): Example("[1, 2].map { $0 + 1 }\n"), + Example("[1, 2].map↓( ) { $0 + 1 }\n"): Example("[1, 2].map { $0 + 1 }\n"), + Example("[1, 2].map↓() { number in\n number + 1 \n}\n"): + Example("[1, 2].map { number in\n number + 1 \n}\n"), + Example("[1, 2].map↓( ) { number in\n number + 1 \n}\n"): + Example("[1, 2].map { number in\n number + 1 \n}\n"), + Example("func foo() -> [Int] {\n return [1, 2].map↓() { $0 + 1 }\n}\n"): + Example("func foo() -> [Int] {\n return [1, 2].map { $0 + 1 }\n}\n"), + Example("class C {\n#if true\nfunc f() {\n[1, 2].map↓() { $0 + 1 }\n}\n#endif\n}"): + Example("class C {\n#if true\nfunc f() {\n[1, 2].map { $0 + 1 }\n}\n#endif\n}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ExplicitSelfRule.swift b/Source/SwiftLintFramework/Rules/Style/ExplicitSelfRule.swift index 2ee11a11e6..2362122146 100644 --- a/Source/SwiftLintFramework/Rules/Style/ExplicitSelfRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ExplicitSelfRule.swift @@ -12,74 +12,74 @@ public struct ExplicitSelfRule: CorrectableRule, ConfigurationProviderRule, Anal description: "Instance variables and functions should be explicitly accessed with 'self.'.", kind: .style, nonTriggeringExamples: [ - """ + Example(""" struct A { func f1() {} func f2() { self.f1() } } - """, - """ + """), + Example(""" struct A { let p1: Int func f1() { _ = self.p1 } } - """ + """) ], triggeringExamples: [ - """ + Example(""" struct A { func f1() {} func f2() { ↓f1() } } - """, - """ + """), + Example(""" struct A { let p1: Int func f1() { _ = ↓p1 } } - """ + """) ], corrections: [ - """ + Example(""" struct A { func f1() {} func f2() { ↓f1() } } - """: - """ + """): + Example(""" struct A { func f1() {} func f2() { self.f1() } } - """, - """ + """), + Example(""" struct A { let p1: Int func f1() { _ = ↓p1 } } - """: - """ + """): + Example(""" struct A { let p1: Int func f1() { _ = self.p1 } } - """ + """) ], requiresFileOnDisk: true ) diff --git a/Source/SwiftLintFramework/Rules/Style/FileHeaderRule.swift b/Source/SwiftLintFramework/Rules/Style/FileHeaderRule.swift index 756b76c287..32f87bfd8a 100644 --- a/Source/SwiftLintFramework/Rules/Style/FileHeaderRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/FileHeaderRule.swift @@ -14,20 +14,22 @@ public struct FileHeaderRule: ConfigurationProviderRule, OptInRule { "required and forbidden patterns. It will be replaced by the real file name.", kind: .style, nonTriggeringExamples: [ - "let foo = \"Copyright\"", - "let foo = 2 // Copyright", - "let foo = 2\n // Copyright" + Example("let foo = \"Copyright\""), + Example("let foo = 2 // Copyright"), + Example("let foo = 2\n // Copyright") ], triggeringExamples: [ - "// ↓Copyright\n", - "//\n// ↓Copyright", - "//\n" + - "// FileHeaderRule.swift\n" + - "// SwiftLint\n" + - "//\n" + - "// Created by Marcelo Fabri on 27/11/16.\n" + - "// ↓Copyright © 2016 Realm. All rights reserved.\n" + - "//" + Example("// ↓Copyright\n"), + Example("//\n// ↓Copyright"), + Example(""" + // + // FileHeaderRule.swift + // SwiftLint + // + // Created by Marcelo Fabri on 27/11/16. + // ↓Copyright © 2016 Realm. All rights reserved. + // + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/FileTypesOrderRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/FileTypesOrderRuleExamples.swift index 7c4745714c..792818a49c 100644 --- a/Source/SwiftLintFramework/Rules/Style/FileTypesOrderRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/FileTypesOrderRuleExamples.swift @@ -124,25 +124,25 @@ internal struct FileTypesOrderRuleExamples { ] static let nonTriggeringExamples = [ - FileTypesOrderRuleExamples.defaultOrderParts.joined(separator: "\n\n"), - """ + Example(FileTypesOrderRuleExamples.defaultOrderParts.joined(separator: "\n\n")), + Example(""" // Only extensions extension Foo {} extension Bar { } - """ + """) ] static let triggeringExamples = [ - """ + Example(""" ↓class TestViewController: UIViewController {} // Supporting Types protocol TestViewControllerDelegate { func didPressTrackedButton() } - """, - """ + """), + Example(""" // Extensions ↓extension TestViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -155,8 +155,8 @@ internal struct FileTypesOrderRuleExamples { } class TestViewController: UIViewController {} - """, - """ + """), + Example(""" // Supporting Types protocol TestViewControllerDelegate { func didPressTrackedButton() @@ -168,8 +168,8 @@ internal struct FileTypesOrderRuleExamples { protocol TestViewControllerDelegate { func didPressTrackedButton() } - """, - """ + """), + Example(""" // Supporting Types protocol TestViewControllerDelegate { func didPressTrackedButton() @@ -198,6 +198,6 @@ internal struct FileTypesOrderRuleExamples { return UITableViewCell() } } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Style/IdentifierNameRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/IdentifierNameRuleExamples.swift index f3157e2d9c..aa00228d09 100644 --- a/Source/SwiftLintFramework/Rules/Style/IdentifierNameRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/IdentifierNameRuleExamples.swift @@ -1,32 +1,32 @@ internal struct IdentifierNameRuleExamples { static let nonTriggeringExamples = [ - "let myLet = 0", - "var myVar = 0", - "private let _myLet = 0", - "class Abc { static let MyLet = 0 }", - "let URL: NSURL? = nil", - "let XMLString: String? = nil", - "override var i = 0", - "enum Foo { case myEnum }", - "func isOperator(name: String) -> Bool", - "func typeForKind(_ kind: SwiftDeclarationKind) -> String", - "func == (lhs: SyntaxToken, rhs: SyntaxToken) -> Bool", - "override func IsOperator(name: String) -> Bool", - "enum Foo { case `private` }", - "enum Foo { case value(String) }" + Example("let myLet = 0"), + Example("var myVar = 0"), + Example("private let _myLet = 0"), + Example("class Abc { static let MyLet = 0 }"), + Example("let URL: NSURL? = nil"), + Example("let XMLString: String? = nil"), + Example("override var i = 0"), + Example("enum Foo { case myEnum }"), + Example("func isOperator(name: String) -> Bool"), + Example("func typeForKind(_ kind: SwiftDeclarationKind) -> String"), + Example("func == (lhs: SyntaxToken, rhs: SyntaxToken) -> Bool"), + Example("override func IsOperator(name: String) -> Bool"), + Example("enum Foo { case `private` }"), + Example("enum Foo { case value(String) }") ] static let triggeringExamples = [ - "↓let MyLet = 0", - "↓let _myLet = 0", - "private ↓let myLet_ = 0", - "↓let myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0", - "↓var myExtremelyVeryVeryVeryVeryVeryVeryLongVar = 0", - "private ↓let _myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0", - "↓let i = 0", - "↓var id = 0", - "private ↓let _i = 0", - "↓func IsOperator(name: String) -> Bool", - "enum Foo { case ↓MyEnum }" + Example("↓let MyLet = 0"), + Example("↓let _myLet = 0"), + Example("private ↓let myLet_ = 0"), + Example("↓let myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0"), + Example("↓var myExtremelyVeryVeryVeryVeryVeryVeryLongVar = 0"), + Example("private ↓let _myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0"), + Example("↓let i = 0"), + Example("↓var id = 0"), + Example("private ↓let _i = 0"), + Example("↓func IsOperator(name: String) -> Bool"), + Example("enum Foo { case ↓MyEnum }") ] } diff --git a/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRule.swift b/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRule.swift index d668ed74ef..cb272d2ba6 100644 --- a/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRule.swift @@ -10,170 +10,10 @@ public struct ImplicitGetterRule: ConfigurationProviderRule, AutomaticTestableRu name: "Implicit Getter", description: "Computed read-only properties and subscripts should avoid using the get keyword.", kind: .style, - nonTriggeringExamples: ImplicitGetterRule.nonTriggeringExamples, - triggeringExamples: ImplicitGetterRule.triggeringExamples + nonTriggeringExamples: ImplicitGetterRuleExamples.nonTriggeringExamples, + triggeringExamples: ImplicitGetterRuleExamples.triggeringExamples ) - private static var nonTriggeringExamples: [String] { - let commonExamples = [ - """ - class Foo { - var foo: Int { - get { return 3 } - set { _abc = newValue } - } - } - """, - """ - class Foo { - var foo: Int { - return 20 - } - } - """, - """ - class Foo { - static var foo: Int { - return 20 - } - } - """, - """ - class Foo { - static var foo: Int { - get { return 3 } - set { _abc = newValue } - } - } - """, - "class Foo {\n var foo: Int\n}", - """ - class Foo { - var foo: Int { - return getValueFromDisk() - } - } - """, - """ - class Foo { - var foo: String { - return "get" - } - } - """, - "protocol Foo {\n var foo: Int { get }\n", - "protocol Foo {\n var foo: Int { get set }\n", - """ - class Foo { - var foo: Int { - struct Bar { - var bar: Int { - get { return 1 } - set { _ = newValue } - } - } - - return Bar().bar - } - } - """, - """ - var _objCTaggedPointerBits: UInt { - @inline(__always) get { return 0 } - } - """, - """ - var next: Int? { - mutating get { - defer { self.count += 1 } - return self.count - } - } - """ - ] - - guard SwiftVersion.current >= .fourDotOne else { - return commonExamples - } - - return commonExamples + [ - """ - class Foo { - subscript(i: Int) -> Int { - return 20 - } - } - """, - """ - class Foo { - subscript(i: Int) -> Int { - get { return 3 } - set { _abc = newValue } - } - } - """, - "protocol Foo {\n subscript(i: Int) -> Int { get }\n}", - "protocol Foo {\n subscript(i: Int) -> Int { get set }\n}" - ] - } - - private static var triggeringExamples: [String] { - let commonExamples = [ - """ - class Foo { - var foo: Int { - ↓get { - return 20 - } - } - } - """, - """ - class Foo { - var foo: Int { - ↓get{ return 20 } - } - } - """, - """ - class Foo { - static var foo: Int { - ↓get { - return 20 - } - } - } - """, - "var foo: Int {\n ↓get { return 20 }\n}", - """ - class Foo { - @objc func bar() {} - var foo: Int { - ↓get { - return 20 - } - } - } - """ - ] - - guard SwiftVersion.current >= .fourDotOne else { - return commonExamples - } - - return commonExamples + [ - """ - class Foo { - subscript(i: Int) -> Int { - ↓get { - return 20 - } - } - } - """ - ] - } - public func validate(file: SwiftLintFile) -> [StyleViolation] { let pattern = "\\{[^\\{]*?\\s+get\\b" let attributesKinds: Set = [.attributeBuiltin, .attributeID] diff --git a/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRuleExamples.swift new file mode 100644 index 0000000000..30d932fdcb --- /dev/null +++ b/Source/SwiftLintFramework/Rules/Style/ImplicitGetterRuleExamples.swift @@ -0,0 +1,183 @@ +struct ImplicitGetterRuleExamples { + static var nonTriggeringExamples: [Example] { + let commonExamples = [ + Example(""" + class Foo { + var foo: Int { + get { return 3 } + set { _abc = newValue } + } + } + """), + Example(""" + class Foo { + var foo: Int { + return 20 + } + } + """), + Example(""" + class Foo { + static var foo: Int { + return 20 + } + } + """), + Example(""" + class Foo { + static var foo: Int { + get { return 3 } + set { _abc = newValue } + } + } + """), + Example(""" + class Foo { + var foo: Int + } + """), + Example(""" + class Foo { + var foo: Int { + return getValueFromDisk() + } + } + """), + Example(""" + class Foo { + var foo: String { + return "get" + } + } + """), + Example(""" + protocol Foo { + var foo: Int { get } + """), + Example(""" + protocol Foo { + var foo: Int { get set } + """), + Example(""" + class Foo { + var foo: Int { + struct Bar { + var bar: Int { + get { return 1 } + set { _ = newValue } + } + } + + return Bar().bar + } + } + """), + Example(""" + var _objCTaggedPointerBits: UInt { + @inline(__always) get { return 0 } + } + """), + Example(""" + var next: Int? { + mutating get { + defer { self.count += 1 } + return self.count + } + } + """) + ] + + guard SwiftVersion.current >= .fourDotOne else { + return commonExamples + } + + return commonExamples + [ + Example(""" + class Foo { + subscript(i: Int) -> Int { + return 20 + } + } + """), + Example(""" + class Foo { + subscript(i: Int) -> Int { + get { return 3 } + set { _abc = newValue } + } + } + """), + Example(""" + protocol Foo { + subscript(i: Int) -> Int { get } + } + """), + Example(""" + protocol Foo { + subscript(i: Int) -> Int { get set } + } + """) + ] + } + + static var triggeringExamples: [Example] { + let commonExamples = [ + Example(""" + class Foo { + var foo: Int { + ↓get { + return 20 + } + } + } + """), + Example(""" + class Foo { + var foo: Int { + ↓get{ return 20 } + } + } + """), + Example(""" + class Foo { + static var foo: Int { + ↓get { + return 20 + } + } + } + """), + Example(""" + var foo: Int { + ↓get { return 20 } + } + """), + Example(""" + class Foo { + @objc func bar() {} + var foo: Int { + ↓get { + return 20 + } + } + } + """) + ] + + guard SwiftVersion.current >= .fourDotOne else { + return commonExamples + } + + return commonExamples + [ + Example(""" + class Foo { + subscript(i: Int) -> Int { + ↓get { + return 20 + } + } + } + """) + ] + } +} diff --git a/Source/SwiftLintFramework/Rules/Style/ImplicitReturnRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/ImplicitReturnRuleExamples.swift index 401562d6ec..fff7e06025 100644 --- a/Source/SwiftLintFramework/Rules/Style/ImplicitReturnRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/ImplicitReturnRuleExamples.swift @@ -1,85 +1,85 @@ internal struct ImplicitReturnRuleExamples { internal struct GenericExamples { - static let nonTriggeringExamples = ["if foo {\n return 0\n}"] + static let nonTriggeringExamples = [Example("if foo {\n return 0\n}")] } internal struct ClosureExamples { static let nonTriggeringExamples = [ - "foo.map { $0 + 1 }", - "foo.map({ $0 + 1 })", - "foo.map { value in value + 1 }", - """ + Example("foo.map { $0 + 1 }"), + Example("foo.map({ $0 + 1 })"), + Example("foo.map { value in value + 1 }"), + Example(""" [1, 2].first(where: { true }) - """ + """) ] static let triggeringExamples = [ - """ + Example(""" foo.map { value in return value + 1 } - """, - """ + """), + Example(""" foo.map { return $0 + 1 } - """, - "foo.map({ return $0 + 1})", - """ + """), + Example("foo.map({ return $0 + 1})"), + Example(""" [1, 2].first(where: { return true }) - """ + """) ] static let corrections = [ - "foo.map { value in\n return value + 1\n}": "foo.map { value in\n value + 1\n}", - "foo.map {\n return $0 + 1\n}": "foo.map {\n $0 + 1\n}", - "foo.map({ return $0 + 1})": "foo.map({ $0 + 1})", - "[1, 2].first(where: {\n return true })": "[1, 2].first(where: {\n true })" + Example("foo.map { value in\n return value + 1\n}"): Example("foo.map { value in\n value + 1\n}"), + Example("foo.map {\n return $0 + 1\n}"): Example("foo.map {\n $0 + 1\n}"), + Example("foo.map({ return $0 + 1})"): Example("foo.map({ $0 + 1})"), + Example("[1, 2].first(where: {\n return true })"): Example("[1, 2].first(where: {\n true })") ] } internal struct FunctionExamples { static let nonTriggeringExamples = [ - """ + Example(""" func foo() -> Int { 0 } - """, - """ + """), + Example(""" class Foo { func foo() -> Int { 0 } } - """ + """) ] static let triggeringExamples = [ - """ + Example(""" func foo() -> Int { return 0 } - """, - """ + """), + Example(""" class Foo { func foo() -> Int { return 0 } } - """ + """) ] static let corrections = [ - "func foo() -> Int {\n return 0\n}": "func foo() -> Int {\n 0\n}", + Example("func foo() -> Int {\n return 0\n}"): Example("func foo() -> Int {\n 0\n}"), // swiftlint:disable:next line_length - "class Foo {\n func foo() -> Int {\n return 0\n }\n}": "class Foo {\n func foo() -> Int {\n 0\n }\n}" + Example("class Foo {\n func foo() -> Int {\n return 0\n }\n}"): Example("class Foo {\n func foo() -> Int {\n 0\n }\n}") ] } internal struct GetterExamples { static let nonTriggeringExamples = [ - "var foo: Bool { true }", - """ + Example("var foo: Bool { true }"), + Example(""" class Foo { var bar: Int { get { @@ -87,19 +87,19 @@ internal struct ImplicitReturnRuleExamples { } } } - """, - """ + """), + Example(""" class Foo { static var bar: Int { 0 } } - """ + """) ] static let triggeringExamples = [ - "var foo: Bool { return true }", - """ + Example("var foo: Bool { return true }"), + Example(""" class Foo { var bar: Int { get { @@ -107,20 +107,20 @@ internal struct ImplicitReturnRuleExamples { } } } - """, - """ + """), + Example(""" class Foo { static var bar: Int { return 0 } } - """ + """) ] static let corrections = [ - "var foo: Bool { return true }": "var foo: Bool { true }", + Example("var foo: Bool { return true }"): Example("var foo: Bool { true }"), // swiftlint:disable:next line_length - "class Foo {\n var bar: Int {\n get {\n return 0\n }\n }\n}": "class Foo {\n var bar: Int {\n get {\n 0\n }\n }\n}" + Example("class Foo {\n var bar: Int {\n get {\n return 0\n }\n }\n}"): Example("class Foo {\n var bar: Int {\n get {\n 0\n }\n }\n}") ] } @@ -133,8 +133,8 @@ internal struct ImplicitReturnRuleExamples { FunctionExamples.triggeringExamples + GetterExamples.triggeringExamples - static var corrections: [String: String] { - let corrections: [[String: String]] = [ + static var corrections: [Example: Example] { + let corrections: [[Example: Example]] = [ ClosureExamples.corrections, FunctionExamples.corrections, GetterExamples.corrections diff --git a/Source/SwiftLintFramework/Rules/Style/IndentationWidthRule.swift b/Source/SwiftLintFramework/Rules/Style/IndentationWidthRule.swift index ef3bb0fb6c..ec95971eb6 100644 --- a/Source/SwiftLintFramework/Rules/Style/IndentationWidthRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/IndentationWidthRule.swift @@ -28,17 +28,17 @@ public struct IndentationWidthRule: ConfigurationProviderRule, OptInRule { "unindent to match previous indentations. Don't indent the first line.", kind: .style, nonTriggeringExamples: [ - "firstLine\nsecondLine", - "firstLine\n secondLine", - "firstLine\n\tsecondLine\n\t\tthirdLine\n\n\t\tfourthLine", - "firstLine\n\tsecondLine\n\t\tthirdLine\n//test\n\t\tfourthLine", - "firstLine\n secondLine\n thirdLine\nfourthLine" + Example("firstLine\nsecondLine"), + Example("firstLine\n secondLine"), + Example("firstLine\n\tsecondLine\n\t\tthirdLine\n\n\t\tfourthLine"), + Example("firstLine\n\tsecondLine\n\t\tthirdLine\n//test\n\t\tfourthLine"), + Example("firstLine\n secondLine\n thirdLine\nfourthLine") ], triggeringExamples: [ - " firstLine", - "firstLine\n secondLine", - "firstLine\n\tsecondLine\n\n\t\t\tfourthLine", - "firstLine\n secondLine\n thirdLine\n fourthLine" + Example(" firstLine"), + Example("firstLine\n secondLine"), + Example("firstLine\n\tsecondLine\n\n\t\t\tfourthLine"), + Example("firstLine\n secondLine\n thirdLine\n fourthLine") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/LeadingWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/LeadingWhitespaceRule.swift index 03c39687d3..2f87bec624 100644 --- a/Source/SwiftLintFramework/Rules/Style/LeadingWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/LeadingWhitespaceRule.swift @@ -11,9 +11,9 @@ public struct LeadingWhitespaceRule: CorrectableRule, ConfigurationProviderRule, name: "Leading Whitespace", description: "Files should not contain leading whitespace.", kind: .style, - nonTriggeringExamples: [ "//\n" ], - triggeringExamples: [ "\n", " //\n" ], - corrections: ["\n //": "//"] + nonTriggeringExamples: [ Example("//\n") ], + triggeringExamples: [ Example("\n"), Example(" //\n") ], + corrections: [Example("\n //"): Example("//")] ) public func validate(file: SwiftLintFile) -> [StyleViolation] { diff --git a/Source/SwiftLintFramework/Rules/Style/LetVarWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/LetVarWhitespaceRule.swift index ae97ec4cea..04bd271f47 100644 --- a/Source/SwiftLintFramework/Rules/Style/LetVarWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/LetVarWhitespaceRule.swift @@ -12,30 +12,35 @@ public struct LetVarWhitespaceRule: ConfigurationProviderRule, OptInRule, Automa description: "Let and var should be separated from other statements by a blank line.", kind: .style, nonTriggeringExamples: [ - "let a = 0\nvar x = 1\n\nx = 2\n", - "a = 5\n\nvar x = 1\n", - "struct X {\n\tvar a = 0\n}\n", - "let a = 1 +\n\t2\nlet b = 5\n", - "var x: Int {\n\treturn 0\n}\n", - "var x: Int {\n\tlet a = 0\n\n\treturn a\n}\n", - "#if os(macOS)\nlet a = 0\n#endif\n", - "#warning(\"TODO: remove it\")\nlet a = 0\n", - "#error(\"TODO: remove it\")\nlet a = 0\n", - "@available(swift 4)\nlet a = 0\n", - "class C {\n\t@objc\n\tvar s: String = \"\"\n}", - "class C {\n\t@objc\n\tfunc a() {}\n}", - "class C {\n\tvar x = 0\n\tlazy\n\tvar y = 0\n}\n", - "@available(OSX, introduced: 10.6)\n@available(*, deprecated)\nvar x = 0\n", - "// swiftlint:disable superfluous_disable_command\n// swiftlint:disable force_cast\n\nlet x = bar as! Bar", - "var x: Int {\n\tlet a = 0\n\treturn a\n}\n" // don't trigger on local vars + Example("let a = 0\nvar x = 1\n\nx = 2\n"), + Example("a = 5\n\nvar x = 1\n"), + Example("struct X {\n\tvar a = 0\n}\n"), + Example("let a = 1 +\n\t2\nlet b = 5\n"), + Example("var x: Int {\n\treturn 0\n}\n"), + Example("var x: Int {\n\tlet a = 0\n\n\treturn a\n}\n"), + Example("#if os(macOS)\nlet a = 0\n#endif\n"), + Example("#warning(\"TODO: remove it\")\nlet a = 0\n"), + Example("#error(\"TODO: remove it\")\nlet a = 0\n"), + Example("@available(swift 4)\nlet a = 0\n"), + Example("class C {\n\t@objc\n\tvar s: String = \"\"\n}"), + Example("class C {\n\t@objc\n\tfunc a() {}\n}"), + Example("class C {\n\tvar x = 0\n\tlazy\n\tvar y = 0\n}\n"), + Example("@available(OSX, introduced: 10.6)\n@available(*, deprecated)\nvar x = 0\n"), + Example(""" + // swiftlint:disable superfluous_disable_command + // swiftlint:disable force_cast + + let x = bar as! Bar + """), + Example("var x: Int {\n\tlet a = 0\n\treturn a\n}\n") // don't trigger on local vars ], triggeringExamples: [ - "var x = 1\n↓x = 2\n", - "\na = 5\n↓var x = 1\n", - "struct X {\n\tlet a\n\t↓func x() {}\n}\n", - "var x = 0\n↓@objc func f() {}\n", - "var x = 0\n↓@objc\n\tfunc f() {}\n", - "@objc func f() {\n}\n↓var x = 0\n" + Example("var x = 1\n↓x = 2\n"), + Example("\na = 5\n↓var x = 1\n"), + Example("struct X {\n\tlet a\n\t↓func x() {}\n}\n"), + Example("var x = 0\n↓@objc func f() {}\n"), + Example("var x = 0\n↓@objc\n\tfunc f() {}\n"), + Example("@objc func f() {\n}\n↓var x = 0\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/LiteralExpressionEndIdentationRule.swift b/Source/SwiftLintFramework/Rules/Style/LiteralExpressionEndIdentationRule.swift index 9f0241ffc4..c413318beb 100644 --- a/Source/SwiftLintFramework/Rules/Style/LiteralExpressionEndIdentationRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/LiteralExpressionEndIdentationRule.swift @@ -12,80 +12,114 @@ public struct LiteralExpressionEndIdentationRule: Rule, ConfigurationProviderRul description: "Array and dictionary literal end should have the same indentation as the line that started it.", kind: .style, nonTriggeringExamples: [ - "[1, 2, 3]", - "[1,\n" + - " 2\n" + - "]", - "[\n" + - " 1,\n" + - " 2\n" + - "]", - "[\n" + - " 1,\n" + - " 2]\n", - " let x = [\n" + - " 1,\n" + - " 2\n" + - " ]", - "[key: 2, key2: 3]", - "[key: 1,\n" + - " key2: 2\n" + - "]", - "[\n" + - " key: 0,\n" + - " key2: 20\n" + - "]" + Example(""" + [1, 2, 3] + """), + Example(""" + [1, + 2 + ] + """), + Example(""" + [ + 1, + 2 + ] + """), + Example(""" + [ + 1, + 2] + """), + Example(""" + let x = [ + 1, + 2 + ] + """), + Example(""" + [key: 2, key2: 3] + """), + Example(""" + [key: 1, + key2: 2 + ] + """), + Example(""" + [ + key: 0, + key2: 20 + ] + """) ], triggeringExamples: [ - "let x = [\n" + - " 1,\n" + - " 2\n" + - " ↓]", - " let x = [\n" + - " 1,\n" + - " 2\n" + - "↓]", - "let x = [\n" + - " key: value\n" + - " ↓]" + Example(""" + let x = [ + 1, + 2 + ↓] + """), + Example(""" + let x = [ + 1, + 2 + ↓] + """), + Example(""" + let x = [ + key: value + ↓] + """) ], corrections: [ - "let x = [\n" + - " key: value\n" + - "↓ ]": - "let x = [\n" + - " key: value\n" + - "]", - " let x = [\n" + - " 1,\n" + - " 2\n" + - "↓]": - " let x = [\n" + - " 1,\n" + - " 2\n" + - " ]", - "let x = [\n" + - " 1,\n" + - " 2\n" + - "↓ ]": - "let x = [\n" + - " 1,\n" + - " 2\n" + - "]", - "let x = [\n" + - " 1,\n" + - " 2\n" + - "↓ ] + [\n" + - " 3,\n" + - " 4\n" + - "↓ ]": - "let x = [\n" + - " 1,\n" + - " 2\n" + - "] + [\n" + - " 3,\n" + - " 4\n" + - "]" + Example(""" + let x = [ + key: value + ↓ ] + """): Example(""" + let x = [ + key: value + ] + """), + Example(""" + let x = [ + 1, + 2 + ↓] + """): Example(""" + let x = [ + 1, + 2 + ] + """), + Example(""" + let x = [ + 1, + 2 + ↓ ] + """): Example(""" + let x = [ + 1, + 2 + ] + """), + Example(""" + let x = [ + 1, + 2 + ↓ ] + [ + 3, + 4 + ↓ ] + """): Example(""" + let x = [ + 1, + 2 + ] + [ + 3, + 4 + ] + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ModifierOrderRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/ModifierOrderRuleExamples.swift index 7adbb9f871..37f0402570 100644 --- a/Source/SwiftLintFramework/Rules/Style/ModifierOrderRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/ModifierOrderRuleExamples.swift @@ -1,160 +1,229 @@ +// swiftlint:disable type_body_length internal struct ModifierOrderRuleExamples { static let nonTriggeringExamples = [ - "public class Foo { \n" + - " public convenience required init() {} \n" + - "}", - "public class Foo { \n" + - " public static let bar = 42 \n" + - "}", - "public class Foo { \n" + - " public static var bar: Int { \n" + - " return 42" + - " }" + - "}", - "public class Foo { \n" + - " public class var bar: Int { \n" + - " return 42 \n" + - " } \n" + - "}", - "public class Bar { \n" + - " public class var foo: String { \n" + - " return \"foo\" \n" + - " } \n" + - "} \n" + - "public class Foo: Bar { \n" + - " override public final class var foo: String { \n" + - " return \"bar\" \n" + - " } \n" + - "}", - "open class Bar { \n" + - " public var foo: Int? { \n" + - " return 42 \n" + - " } \n" + - "} \n" + - "open class Foo: Bar { \n" + - " override public var foo: Int? { \n" + - " return 43 \n" + - " } \n" + - "}", - "open class Bar { \n" + - " open class func foo() -> Int { \n" + - " return 42 \n" + - " } \n" + - "} \n" + - "class Foo: Bar { \n" + - " override open class func foo() -> Int { \n" + - " return 43 \n" + - " } \n" + - "}", - "protocol Foo: class {} \n" + - "class Bar { \n" + - " public private(set) weak var foo: Foo? \n" + - "} \n", - "@objc \n" + - "public final class Foo: NSObject {} \n", - "@objcMembers \n" + - "public final class Foo: NSObject {} \n", - "@objc \n" + - "override public private(set) weak var foo: Bar? \n", - "@objc \n" + - "public final class Foo: NSObject {} \n", - "@objc \n" + - "open final class Foo: NSObject { \n" + - " open weak var weakBar: NSString? = nil \n" + - "}", - "public final class Foo {}", - "class Bar { \n" + - " func bar() {} \n" + - "}", - "internal class Foo: Bar { \n" + - " override internal func bar() {} \n" + - "}", - "public struct Foo { \n" + - " internal weak var weakBar: NSObject? = nil \n" + - "}", - "class Foo { \n" + - " internal lazy var bar: String = \"foo\" \n" + - "}" + Example(""" + public class Foo { + public convenience required init() {} + } + """), + Example(""" + public class Foo { + public static let bar = 42 + } + """), + Example(""" + public class Foo { + public static var bar: Int { + return + } + } + """), + Example(""" + public class Foo { + public class var bar: Int { + return 42 + } + } + """), + Example(""" + public class Bar { + public class var foo: String { + return "foo" + } + } + public class Foo: Bar { + override public final class var foo: String { + return "bar" + } + } + """), + Example(""" + open class Bar { + public var foo: Int? { + return 42 + } + } + open class Foo: Bar { + override public var foo: Int? { + return 43 + } + } + """), + Example(""" + open class Bar { + open class func foo() -> Int { + return 42 + } + } + class Foo: Bar { + override open class func foo() -> Int { + return 43 + } + } + """), + Example(""" + protocol Foo: class {} + class Bar { + public private(set) weak var foo: Foo? + } + """), + Example(""" + @objc + public final class Foo: NSObject {} + """), + Example(""" + @objcMembers + public final class Foo: NSObject {} + """), + Example(""" + @objc + override public private(set) weak var foo: Bar? + """), + Example(""" + @objc + public final class Foo: NSObject {} + """), + Example(""" + @objc + open final class Foo: NSObject { + open weak var weakBar: NSString? = nil + } + """), + Example(""" + public final class Foo {} + """), + Example(""" + class Bar { + func bar() {} + } + """), + Example(""" + internal class Foo: Bar { + override internal func bar() {} + } + """), + Example(""" + public struct Foo { + internal weak var weakBar: NSObject? = nil + } + """), + Example(""" + class Foo { + internal lazy var bar: String = "foo" + } + """) ] static let triggeringExamples = [ - "class Foo { \n" + - " convenience required public init() {} \n" + - "}", - "public class Foo { \n" + - " static public let bar = 42 \n" + - "}", - "public class Foo { \n" + - " static public var bar: Int { \n" + - " return 42 \n" + - " } \n" + - "} \n", - "public class Foo { \n" + - " class public var bar: Int { \n" + - " return 42 \n" + - " } \n" + - "}", - "public class RootFoo { \n" + - " class public var foo: String { \n" + - " return \"foo\" \n" + - " } \n" + - "} \n" + - "public class Foo: RootFoo { \n" + - " override final class public var foo: String { \n" + - " return \"bar\" \n" + - " } \n" + - "}", - "open class Bar { \n" + - " public var foo: Int? { \n" + - " return 42 \n" + - " } \n" + - "} \n" + - "open class Foo: Bar { \n" + - " public override var foo: Int? { \n" + - " return 43 \n" + - " } \n" + - "}", - "protocol Foo: class {} \n" + - "class Bar { \n" + - " private(set) public weak var foo: Foo? \n" + - "} \n", - "open class Bar { \n" + - " open class func foo() -> Int { \n" + - " return 42 \n" + - " } \n" + - "} \n" + - "class Foo: Bar { \n" + - " class open override func foo() -> Int { \n" + - " return 43 \n" + - " } \n" + - "}", - "open class Bar { \n" + - " open class func foo() -> Int { \n" + - " return 42 \n" + - " } \n" + - "} \n" + - "class Foo: Bar { \n" + - " open override class func foo() -> Int { \n" + - " return 43 \n" + - " } \n" + - "}", - "@objc \n" + - "final public class Foo: NSObject {}", - "@objcMembers \n" + - "final public class Foo: NSObject {}", - "@objc \n" + - "final open class Foo: NSObject { \n" + - " weak open var weakBar: NSString? = nil \n" + - "}", - "final public class Foo {} \n", - "internal class Foo: Bar { \n" + - " internal override func bar() {} \n" + - "}", - "public struct Foo { \n" + - " weak internal var weakBar: NSObjetc? = nil \n" + - "}", - "class Foo { \n" + - " lazy internal var bar: String = \"foo\" \n" + - "}" + Example(""" + class Foo { + convenience required public init() {} + } + """), + Example(""" + public class Foo { + static public let bar = 42 + } + """), + Example(""" + public class Foo { + static public var bar: Int { + return 42 + } + } + """), + Example(""" + public class Foo { + class public var bar: Int { + return 42 + } + } + """), + Example(""" + public class RootFoo { + class public var foo: String { + return "foo" + } + } + public class Foo: RootFoo { + override final class public var foo: String + return "bar" + } + } + """), + Example(""" + open class Bar { + public var foo: Int? { + return 42 + } + } + open class Foo: Bar { + public override var foo: Int? { + return 43 + } + } + """), + Example(""" + protocol Foo: class {} + class Bar { + private(set) public weak var foo: Foo? + } + """), + Example(""" + open class Bar { + open class func foo() -> Int { + return 42 + } + } + class Foo: Bar { + class open override func foo() -> Int { + return 43 + } + } + """), + Example(""" + open class Bar { + open class func foo() -> Int { + return 42 + } + } + class Foo: Bar { + open override class func foo() -> Int { + return 43 + } + } + """), + Example(""" + @objc + final public class Foo: NSObject {} + """), + Example(""" + @objcMembers + final public class Foo: NSObject {} + """), + Example(""" + @objc + final open class Foo: NSObject { + weak open var weakBar: NSString? = nil + } + """), + Example(""" + final public class Foo {} + """), + Example(""" + internal class Foo: Bar { + internal override func bar() {} + } + """), + Example(""" + public struct Foo { + weak internal var weakBar: NSObjetc? = nil + } + """), + Example(""" + class Foo { + lazy internal var bar: String = "foo" + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift index 981db34809..084566af55 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift @@ -12,66 +12,66 @@ public struct MultilineArgumentsBracketsRule: ASTRule, OptInRule, ConfigurationP description: "Multiline arguments should have their surrounding brackets in a new line.", kind: .style, nonTriggeringExamples: [ - """ + Example(""" foo(param1: "Param1", param2: "Param2", param3: "Param3") - """, - """ + """), + Example(""" foo( param1: "Param1", param2: "Param2", param3: "Param3" ) - """, - """ + """), + Example(""" func foo( param1: "Param1", param2: "Param2", param3: "Param3" ) - """, - """ + """), + Example(""" foo { param1, param2 in print("hello world") } - """, - """ + """), + Example(""" foo( bar( x: 5, y: 7 ) ) - """, - """ + """), + Example(""" AlertViewModel.AlertAction(title: "some title", style: .default) { AlertManager.shared.presentNextDebugAlert() } - """ + """) ], triggeringExamples: [ - """ + Example(""" foo(↓param1: "Param1", param2: "Param2", param3: "Param3" ) - """, - """ + """), + Example(""" foo( param1: "Param1", param2: "Param2", param3: "Param3"↓) - """, - """ + """), + Example(""" foo(↓bar( x: 5, y: 7 ) ) - """, - """ + """), + Example(""" foo( bar( x: 5, y: 7 )↓) - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsRuleExamples.swift index cf2c915d78..1d8fbf7eb1 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsRuleExamples.swift @@ -1,48 +1,63 @@ internal struct MultilineArgumentsRuleExamples { static let nonTriggeringExamples = [ - "foo()", - "foo(\n" + + Example("foo()"), + Example("foo(\n" + + ")"), + Example("foo { }"), + Example("foo {\n" + " \n" + - ")", - "foo { }", - "foo {\n" + - " \n" + - "}", - "foo(0)", - "foo(0, 1)", - "foo(0, 1) { }", - "foo(0, param1: 1)", - "foo(0, param1: 1) { }", - "foo(param1: 1)", - "foo(param1: 1) { }", - "foo(param1: 1, param2: true) { }", - "foo(param1: 1, param2: true, param3: [3]) { }", - "foo(param1: 1, param2: true, param3: [3]) {\n" + - " bar()\n" + - "}", - "foo(param1: 1,\n" + - " param2: true,\n" + - " param3: [3])", - "foo(\n" + - " param1: 1, param2: true, param3: [3]\n" + - ")", - "foo(\n" + - " param1: 1,\n" + - " param2: true,\n" + - " param3: [3]\n" + - ")" + "}"), + Example("foo(0)"), + Example("foo(0, 1)"), + Example("foo(0, 1) { }"), + Example("foo(0, param1: 1)"), + Example("foo(0, param1: 1) { }"), + Example("foo(param1: 1)"), + Example("foo(param1: 1) { }"), + Example("foo(param1: 1, param2: true) { }"), + Example("foo(param1: 1, param2: true, param3: [3]) { }"), + Example(""" + foo(param1: 1, param2: true, param3: [3]) { + bar() + } + """), + Example(""" + foo(param1: 1, + param2: true, + param3: [3]) + """), + Example(""" + foo( + param1: 1, param2: true, param3: [3] + ) + """), + Example(""" + foo( + param1: 1, + param2: true, + param3: [3] + ) + """) ] static let triggeringExamples = [ - "foo(0,\n" + - " param1: 1, ↓param2: true, ↓param3: [3])", - "foo(0, ↓param1: 1,\n" + - " param2: true, ↓param3: [3])", - "foo(0, ↓param1: 1, ↓param2: true,\n" + - " param3: [3])", - "foo(\n" + - " 0, ↓param1: 1,\n" + - " param2: true, ↓param3: [3]\n" + - ")" + Example(""" + foo(0, + param1: 1, ↓param2: true, ↓param3: [3]) + """), + Example(""" + foo(0, ↓param1: 1, + param2: true, ↓param3: [3]) + """), + Example(""" + foo(0, ↓param1: 1, ↓param2: true, + param3: [3]) + """), + Example(""" + foo( + 0, ↓param1: 1, + param2: true, ↓param3: [3] + ) + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineFunctionChainsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineFunctionChainsRule.swift index 7ec947c758..63e1ef1c31 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineFunctionChainsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineFunctionChainsRule.swift @@ -12,40 +12,40 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv description: "Chained function calls should be either on the same line, or one per line.", kind: .style, nonTriggeringExamples: [ - "let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)", - """ + Example("let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)"), + Example(""" let evenSquaresSum = [20, 17, 35, 4] .filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)", - """, - """ + """), + Example(""" let chain = a .b(1, 2, 3) .c { blah in print(blah) } .d() - """, - """ + """), + Example(""" let chain = a.b(1, 2, 3) .c { blah in print(blah) } .d() - """, - """ + """), + Example(""" let chain = a.b(1, 2, 3) .c { blah in print(blah) } .d() - """, - """ + """), + Example(""" let chain = a.b(1, 2, 3) .c(.init( a: 1, b, 2, c, 3)) .d() - """, - """ + """), + Example(""" self.viewModel.outputs.postContextualNotification .observeForUI() .observeValues { @@ -57,40 +57,40 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv ) ) } - """, - "let remainingIDs = Array(Set(self.currentIDs).subtracting(Set(response.ids)))", - """ + """), + Example("let remainingIDs = Array(Set(self.currentIDs).subtracting(Set(response.ids)))"), + Example(""" self.happeningNewsletterOn = self.updateCurrentUser .map { $0.newsletters.happening }.skipNil().skipRepeats() - """ + """) ], triggeringExamples: [ - """ + Example(""" let evenSquaresSum = [20, 17, 35, 4] .filter { $0 % 2 == 0 }↓.map { $0 * $0 } .reduce(0, +) - """, - """ + """), + Example(""" let evenSquaresSum = a.b(1, 2, 3) .c { blah in print(blah) }↓.d() - """, - """ + """), + Example(""" let evenSquaresSum = a.b(1, 2, 3) .c(2, 3, 4)↓.d() - """, - """ + """), + Example(""" let evenSquaresSum = a.b(1, 2, 3)↓.c { blah in print(blah) } .d() - """, - """ + """), + Example(""" a.b { // ““ }↓.e() - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift index 2292438cd3..dbb5a583f5 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift @@ -12,11 +12,11 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro description: "Multiline literals should have their surrounding brackets in a new line.", kind: .style, nonTriggeringExamples: [ - """ + Example(""" let trio = ["harry", "ronald", "hermione"] let houseCup = ["gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450] - """, - """ + """), + Example(""" let trio = [ "harry", "ronald", @@ -28,8 +28,8 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro "ravenclaw": 410, "slytherin": 450 ] - """, - """ + """), + Example(""" let trio = [ "harry", "ronald", "hermione" ] @@ -37,8 +37,8 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro "gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450 ] - """, - """ + """), + Example(""" _ = [ 1, 2, @@ -47,39 +47,39 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro 5, 6, 7, 8, 9 ] - """ + """) ], triggeringExamples: [ - """ + Example(""" let trio = [↓"harry", "ronald", "hermione" ] - """, - """ + """), + Example(""" let houseCup = [↓"gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450 ] - """, - """ + """), + Example(""" let trio = [ "harry", "ronald", "hermione"↓] - """, - """ + """), + Example(""" let houseCup = [ "gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450↓] - """, - """ + """), + Example(""" class Hogwarts { let houseCup = [ "gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450↓] } - """, - """ + """), + Example(""" _ = [ 1, 2, @@ -87,13 +87,13 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro 4, 5, 6, 7, 8, 9↓] - """, - """ + """), + Example(""" _ = [↓1, 2, 3, 4, 5, 6, 7, 8, 9 ] - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift index 625f39db01..a2f2f57fa6 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift @@ -12,34 +12,34 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR description: "Multiline parameters should have their surrounding brackets in a new line.", kind: .style, nonTriggeringExamples: [ - """ + Example(""" func foo(param1: String, param2: String, param3: String) - """, - """ + """), + Example(""" func foo( param1: String, param2: String, param3: String ) - """, - """ + """), + Example(""" func foo( param1: String, param2: String, param3: String ) - """, - """ + """), + Example(""" class SomeType { func foo(param1: String, param2: String, param3: String) } - """, - """ + """), + Example(""" class SomeType { func foo( param1: String, param2: String, param3: String ) } - """, - """ + """), + Example(""" class SomeType { func foo( param1: String, @@ -47,43 +47,43 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR param3: String ) } - """, - """ + """), + Example(""" func foo(param1: T, param2: String, param3: String) -> T { /* some code */ } - """ + """) ], triggeringExamples: [ - """ + Example(""" func foo(↓param1: String, param2: String, param3: String ) - """, - """ + """), + Example(""" func foo( param1: String, param2: String, param3: String↓) - """, - """ + """), + Example(""" class SomeType { func foo(↓param1: String, param2: String, param3: String ) } - """, - """ + """), + Example(""" class SomeType { func foo( param1: String, param2: String, param3: String↓) } - """, - """ + """), + Example(""" func foo(↓param1: T, param2: String, param3: String ) -> T - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineParametersRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/MultilineParametersRuleExamples.swift index 47bb434876..07f6c4b0ff 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultilineParametersRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultilineParametersRuleExamples.swift @@ -1,216 +1,298 @@ // swiftlint:disable type_body_length internal struct MultilineParametersRuleExamples { - static let nonTriggeringExamples = [ - "func foo() { }", - "func foo(param1: Int) { }", - "func foo(param1: Int, param2: Bool) { }", - "func foo(param1: Int, param2: Bool, param3: [String]) { }", - "func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }", - "func foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int {\n" + - " return { x in x + param1 + param2 + param3 }\n" + - "}", - "static func foo() { }", - "static func foo(param1: Int) { }", - "static func foo(param1: Int, param2: Bool) { }", - "static func foo(param1: Int, param2: Bool, param3: [String]) { }", - "static func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }", - "protocol Foo {\n\tfunc foo() { }\n}", - "protocol Foo {\n\tfunc foo(param1: Int) { }\n}", - "protocol Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}", - "protocol Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "protocol Foo {\n" + - " func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "protocol Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "protocol Foo {\n" + - " static func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "protocol Foo {\n\tclass func foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "protocol Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "enum Foo {\n\tfunc foo() { }\n}", - "enum Foo {\n\tfunc foo(param1: Int) { }\n}", - "enum Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}", - "enum Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "enum Foo {\n" + - " func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "enum Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "enum Foo {\n" + - " static func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "struct Foo {\n\tfunc foo() { }\n}", - "struct Foo {\n\tfunc foo(param1: Int) { }\n}", - "struct Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}", - "struct Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "struct Foo {\n" + - " func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "struct Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "struct Foo {\n" + - " static func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n\tfunc foo() { }\n}", - "class Foo {\n\tfunc foo(param1: Int) { }\n}", - "class Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}", - "class Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n\t}", - "class Foo {\n" + - " func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n\tclass func foo(param1: Int, param2: Bool, param3: [String]) { }\n}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping (Int, Int) -> Void = { _, _ in }) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping (Int) -> Void = { _ in }) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping ((Int) -> Void)? = nil) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping ((Int) -> Void)? = { _ in }) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: @escaping ((Int) -> Void)? = { _ in },\n" + - " param3: Bool) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: @escaping ((Int) -> Void)? = { _ in },\n" + - " param3: @escaping (Int, Int) -> Void = { _, _ in }) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping (Int) -> Void = { (x: Int) in }) { }\n" + - "}", - "class Foo {\n" + - " class func foo(param1: Int,\n" + - " param2: Bool,\n" + - " param3: @escaping (Int, (Int) -> Void) -> Void = { (x: Int, f: (Int) -> Void) in }) { }\n" + - "}" + static let nonTriggeringExamples: [Example] = [ + Example("func foo() { }"), + Example("func foo(param1: Int) { }"), + Example("func foo(param1: Int, param2: Bool) { }"), + Example("func foo(param1: Int, param2: Bool, param3: [String]) { }"), + Example(""" + func foo(param1: Int, + param2: Bool, + param3: [String]) { } + """), + Example(""" + func foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int { + return { x in x + param1 + param2 + param3 } + } + """), + Example("static func foo() { }"), + Example("static func foo(param1: Int) { }"), + Example("static func foo(param1: Int, param2: Bool) { }"), + Example("static func foo(param1: Int, param2: Bool, param3: [String]) { }"), + Example(""" + static func foo(param1: Int, + param2: Bool, + param3: [String]) { } + """), + Example("protocol Foo {\n\tfunc foo() { }\n}"), + Example("protocol Foo {\n\tfunc foo(param1: Int) { }\n}"), + Example("protocol Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}"), + Example("protocol Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + protocol Foo { + func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("protocol Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + protocol Foo { + static func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("protocol Foo {\n\tclass func foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + protocol Foo { + class func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("enum Foo {\n\tfunc foo() { }\n}"), + Example("enum Foo {\n\tfunc foo(param1: Int) { }\n}"), + Example("enum Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}"), + Example("enum Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + enum Foo { + func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("enum Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + enum Foo { + static func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("struct Foo {\n\tfunc foo() { }\n}"), + Example("struct Foo {\n\tfunc foo(param1: Int) { }\n}"), + Example("struct Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}"), + Example("struct Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + struct Foo { + func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("struct Foo {\n\tstatic func foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + struct Foo { + static func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("class Foo {\n\tfunc foo() { }\n}"), + Example("class Foo {\n\tfunc foo(param1: Int) { }\n}"), + Example("class Foo {\n\tfunc foo(param1: Int, param2: Bool) { }\n}"), + Example("class Foo {\n\tfunc foo(param1: Int, param2: Bool, param3: [String]) { }\n\t}"), + Example(""" + class Foo { + func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example("class Foo {\n\tclass func foo(param1: Int, param2: Bool, param3: [String]) { }\n}"), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: [String]) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping (Int, Int) -> Void = { _, _ in }) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping (Int) -> Void = { _ in }) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping ((Int) -> Void)? = nil) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping ((Int) -> Void)? = { _ in }) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: @escaping ((Int) -> Void)? = { _ in }, + param3: Bool) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: @escaping ((Int) -> Void)? = { _ in }, + param3: @escaping (Int, Int) -> Void = { _, _ in }) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping (Int) -> Void = { (x: Int) in }) { } + } + """), + Example(""" + class Foo { + class func foo(param1: Int, + param2: Bool, + param3: @escaping (Int, (Int) -> Void) -> Void = { (x: Int, f: (Int) -> Void) in }) { } + } + """) ] - static let triggeringExamples = [ - "func ↓foo(_ param1: Int,\n" + - " param2: Int, param3: Int) -> (Int) -> Int {\n" + - " return { x in x + param1 + param2 + param3 }\n" + - "}", - "protocol Foo {\n" + - " func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "protocol Foo {\n" + - " func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "protocol Foo {\n" + - " static func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "protocol Foo {\n" + - " static func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "protocol Foo {\n" + - " class func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "protocol Foo {\n" + - " class func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "enum Foo {\n" + - " func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "enum Foo {\n" + - " func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "enum Foo {\n" + - " static func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "enum Foo {\n" + - " static func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "struct Foo {\n" + - " func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "struct Foo {\n" + - " func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "struct Foo {\n" + - " static func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "struct Foo {\n" + - " static func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " class func ↓foo(param1: Int,\n" + - " param2: Bool, param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " class func ↓foo(param1: Int, param2: Bool,\n" + - " param3: [String]) { }\n" + - "}", - "class Foo {\n" + - " class func ↓foo(param1: Int,\n" + - " param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }\n" + - "}", - "class Foo {\n" + - " class func ↓foo(param1: Int,\n" + - " param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { }\n" + - "}" + static let triggeringExamples: [Example] = [ + Example(""" + func ↓foo(_ param1: Int, + param2: Int, param3: Int) -> (Int) -> Int { + return { x in x + param1 + param2 + param3 } + } + """), + Example(""" + protocol Foo { + func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + protocol Foo { + func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + protocol Foo { + static func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + protocol Foo { + static func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + protocol Foo { + class func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + protocol Foo { + class func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + enum Foo { + func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + enum Foo { + func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + enum Foo { + static func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + enum Foo { + static func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + struct Foo { + func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + struct Foo { + func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + struct Foo { + static func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + struct Foo { + static func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + class Foo { + func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + class Foo { + func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + class Foo { + class func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + } + """), + Example(""" + class Foo { + class func ↓foo(param1: Int, param2: Bool, + param3: [String]) { } + } + """), + Example(""" + class Foo { + class func ↓foo(param1: Int, + param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { } + } + """), + Example(""" + class Foo { + class func ↓foo(param1: Int, + param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { } + } + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Style/MultipleClosuresWithTrailingClosureRule.swift b/Source/SwiftLintFramework/Rules/Style/MultipleClosuresWithTrailingClosureRule.swift index 6f224206c5..197fc19712 100644 --- a/Source/SwiftLintFramework/Rules/Style/MultipleClosuresWithTrailingClosureRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/MultipleClosuresWithTrailingClosureRule.swift @@ -12,21 +12,25 @@ public struct MultipleClosuresWithTrailingClosureRule: ASTRule, ConfigurationPro description: "Trailing closure syntax should not be used when passing more than one closure argument.", kind: .style, nonTriggeringExamples: [ - "foo.map { $0 + 1 }\n", - "foo.reduce(0) { $0 + $1 }\n", - "if let foo = bar.map({ $0 + 1 }) {\n\n}\n", - "foo.something(param1: { $0 }, param2: { $0 + 1 })\n", - "UIView.animate(withDuration: 1.0) {\n" + - " someView.alpha = 0.0\n" + - "}" + Example("foo.map { $0 + 1 }\n"), + Example("foo.reduce(0) { $0 + $1 }\n"), + Example("if let foo = bar.map({ $0 + 1 }) {\n\n}\n"), + Example("foo.something(param1: { $0 }, param2: { $0 + 1 })\n"), + Example(""" + UIView.animate(withDuration: 1.0) { + someView.alpha = 0.0 + } + """) ], triggeringExamples: [ - "foo.something(param1: { $0 }) ↓{ $0 + 1 }", - "UIView.animate(withDuration: 1.0, animations: {\n" + - " someView.alpha = 0.0\n" + - "}) ↓{ _ in\n" + - " someView.removeFromSuperview()\n" + - "}" + Example("foo.something(param1: { $0 }) ↓{ $0 + 1 }"), + Example(""" + UIView.animate(withDuration: 1.0, animations: { + someView.alpha = 0.0 + }) ↓{ _ in + someView.removeFromSuperview() + } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/NoSpaceInMethodCallRule.swift b/Source/SwiftLintFramework/Rules/Style/NoSpaceInMethodCallRule.swift index 879d320679..6b533728d0 100644 --- a/Source/SwiftLintFramework/Rules/Style/NoSpaceInMethodCallRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/NoSpaceInMethodCallRule.swift @@ -14,29 +14,29 @@ public struct NoSpaceInMethodCallRule: SubstitutionCorrectableASTRule, Configura kind: .style, minSwiftVersion: .fourDotTwo, nonTriggeringExamples: [ - "foo()", - "object.foo()", - "object.foo(1)", - "object.foo(value: 1)", - "object.foo { print($0 }", - "list.sorted { $0.0 < $1.0 }.map { $0.value }", - "self.init(rgb: (Int) (colorInt))" + Example("foo()"), + Example("object.foo()"), + Example("object.foo(1)"), + Example("object.foo(value: 1)"), + Example("object.foo { print($0 }"), + Example("list.sorted { $0.0 < $1.0 }.map { $0.value }"), + Example("self.init(rgb: (Int) (colorInt))") ], triggeringExamples: [ - "foo↓ ()", - "object.foo↓ ()", - "object.foo↓ (1)", - "object.foo↓ (value: 1)", - "object.foo↓ () {}", - "object.foo↓ ()" + Example("foo↓ ()"), + Example("object.foo↓ ()"), + Example("object.foo↓ (1)"), + Example("object.foo↓ (value: 1)"), + Example("object.foo↓ () {}"), + Example("object.foo↓ ()") ], corrections: [ - "foo↓ ()": "foo()", - "object.foo↓ ()": "object.foo()", - "object.foo↓ (1)": "object.foo(1)", - "object.foo↓ (value: 1)": "object.foo(value: 1)", - "object.foo↓ () {}": "object.foo() {}", - "object.foo↓ ()": "object.foo()" + Example("foo↓ ()"): Example("foo()"), + Example("object.foo↓ ()"): Example("object.foo()"), + Example("object.foo↓ (1)"): Example("object.foo(1)"), + Example("object.foo↓ (value: 1)"): Example("object.foo(value: 1)"), + Example("object.foo↓ () {}"): Example("object.foo() {}"), + Example("object.foo↓ ()"): Example("object.foo()") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/NumberSeparatorRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/NumberSeparatorRuleExamples.swift index 156a0165e4..0ed1eef7e8 100644 --- a/Source/SwiftLintFramework/Rules/Style/NumberSeparatorRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/NumberSeparatorRuleExamples.swift @@ -1,21 +1,21 @@ internal struct NumberSeparatorRuleExamples { - static let nonTriggeringExamples: [String] = { - return ["-", "+", ""].flatMap { (sign: String) -> [String] in + static let nonTriggeringExamples: [Example] = { + return ["-", "+", ""].flatMap { (sign: String) -> [Example] in [ - "let foo = \(sign)100", - "let foo = \(sign)1_000", - "let foo = \(sign)1_000_000", - "let foo = \(sign)1.000_1", - "let foo = \(sign)1_000_000.000_000_1", - "let binary = \(sign)0b10000", - "let binary = \(sign)0b1000_0001", - "let hex = \(sign)0xA", - "let hex = \(sign)0xAA_BB", - "let octal = \(sign)0o21", - "let octal = \(sign)0o21_1", - "let exp = \(sign)1_000_000.000_000e2", - "let foo: Double = \(sign)(200)", - "let foo: Double = \(sign)(200 / 447.214)" + Example("let foo = \(sign)100"), + Example("let foo = \(sign)1_000"), + Example("let foo = \(sign)1_000_000"), + Example("let foo = \(sign)1.000_1"), + Example("let foo = \(sign)1_000_000.000_000_1"), + Example("let binary = \(sign)0b10000"), + Example("let binary = \(sign)0b1000_0001"), + Example("let hex = \(sign)0xA"), + Example("let hex = \(sign)0xAA_BB"), + Example("let octal = \(sign)0o21"), + Example("let octal = \(sign)0o21_1"), + Example("let exp = \(sign)1_000_000.000_000e2"), + Example("let foo: Double = \(sign)(200)"), + Example("let foo: Double = \(sign)(200 / 447.214)") ] } }() @@ -25,44 +25,45 @@ internal struct NumberSeparatorRuleExamples { static let corrections = makeCorrections(signs: [("↓-", "-"), ("+↓", "+"), ("↓", "")]) - private static func makeTriggeringExamples(signs: [String]) -> [String] { - return signs.flatMap { (sign: String) -> [String] in + private static func makeTriggeringExamples(signs: [String]) -> [Example] { + return signs.flatMap { (sign: String) -> [Example] in [ - "let foo = \(sign)10_0", - "let foo = \(sign)1000", - "let foo = \(sign)1000e2", - "let foo = \(sign)1000E2", - "let foo = \(sign)1__000", - "let foo = \(sign)1.0001", - "let foo = \(sign)1_000_000.000000_1", - "let foo = \(sign)1000000.000000_1" + Example("let foo = \(sign)10_0"), + Example("let foo = \(sign)1000"), + Example("let foo = \(sign)1000e2"), + Example("let foo = \(sign)1000E2"), + Example("let foo = \(sign)1__000"), + Example("let foo = \(sign)1.0001"), + Example("let foo = \(sign)1_000_000.000000_1"), + Example("let foo = \(sign)1000000.000000_1") ] } } - private static func makeTriggeringExamplesWithParentheses() -> [String] { + private static func makeTriggeringExamplesWithParentheses() -> [Example] { let signsWithParenthesisAndViolation = ["↓-(", "+(↓", "(↓"] - return signsWithParenthesisAndViolation.flatMap { (sign: String) -> [String] in + return signsWithParenthesisAndViolation.flatMap { (sign: String) -> [Example] in [ - "let foo: Double = \(sign)100000)", - "let foo: Double = \(sign)10.000000_1)", - "let foo: Double = \(sign)123456 / ↓447.214214)" + Example("let foo: Double = \(sign)100000)"), + Example("let foo: Double = \(sign)10.000000_1)"), + Example("let foo: Double = \(sign)123456 / ↓447.214214)") ] } } - private static func makeCorrections(signs: [(String, String)]) -> [String: String] { - var result = [String: String]() + private static func makeCorrections(signs: [(String, String)]) -> [Example: Example] { + var result = [Example: Example]() for (violation, sign) in signs { - result["let foo = \(violation)10_0"] = "let foo = \(sign)100" - result["let foo = \(violation)1000"] = "let foo = \(sign)1_000" - result["let foo = \(violation)1000e2"] = "let foo = \(sign)1_000e2" - result["let foo = \(violation)1000E2"] = "let foo = \(sign)1_000E2" - result["let foo = \(violation)1__000"] = "let foo = \(sign)1_000" - result["let foo = \(violation)1.0001"] = "let foo = \(sign)1.000_1" - result["let foo = \(violation)1_000_000.000000_1"] = "let foo = \(sign)1_000_000.000_000_1" - result["let foo = \(violation)1000000.000000_1"] = "let foo = \(sign)1_000_000.000_000_1" + result[Example("let foo = \(violation)10_0")] = Example("let foo = \(sign)100") + result[Example("let foo = \(violation)1000")] = Example("let foo = \(sign)1_000") + result[Example("let foo = \(violation)1000e2")] = Example("let foo = \(sign)1_000e2") + result[Example("let foo = \(violation)1000E2")] = Example("let foo = \(sign)1_000E2") + result[Example("let foo = \(violation)1__000")] = Example("let foo = \(sign)1_000") + result[Example("let foo = \(violation)1.0001")] = Example("let foo = \(sign)1.000_1") + // swiftlint:disable:next line_length + result[Example("let foo = \(violation)1_000_000.000000_1")] = Example("let foo = \(sign)1_000_000.000_000_1") + result[Example("let foo = \(violation)1000000.000000_1")] = Example("let foo = \(sign)1_000_000.000_000_1") } return result diff --git a/Source/SwiftLintFramework/Rules/Style/OpeningBraceRule.swift b/Source/SwiftLintFramework/Rules/Style/OpeningBraceRule.swift index 64db23859b..166e68e53d 100644 --- a/Source/SwiftLintFramework/Rules/Style/OpeningBraceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/OpeningBraceRule.swift @@ -67,42 +67,42 @@ public struct OpeningBraceRule: CorrectableRule, ConfigurationProviderRule, Auto "as the declaration.", kind: .style, nonTriggeringExamples: [ - "func abc() {\n}", - "[].map() { $0 }", - "[].map({ })", - "if let a = b { }", - "while a == b { }", - "guard let a = b else { }", - "if\n\tlet a = b,\n\tlet c = d\n\twhere a == c\n{ }", - "while\n\tlet a = b,\n\tlet c = d\n\twhere a == c\n{ }", - "guard\n\tlet a = b,\n\tlet c = d\n\twhere a == c else\n{ }", - "struct Rule {}\n", - "struct Parent {\n\tstruct Child {\n\t\tlet foo: Int\n\t}\n}\n", - """ + Example("func abc() {\n}"), + Example("[].map() { $0 }"), + Example("[].map({ })"), + Example("if let a = b { }"), + Example("while a == b { }"), + Example("guard let a = b else { }"), + Example("if\n\tlet a = b,\n\tlet c = d\n\twhere a == c\n{ }"), + Example("while\n\tlet a = b,\n\tlet c = d\n\twhere a == c\n{ }"), + Example("guard\n\tlet a = b,\n\tlet c = d\n\twhere a == c else\n{ }"), + Example("struct Rule {}\n"), + Example("struct Parent {\n\tstruct Child {\n\t\tlet foo: Int\n\t}\n}\n"), + Example(""" func f(rect: CGRect) { { let centre = CGPoint(x: rect.midX, y: rect.midY) print(centre) }() } - """ + """) ], triggeringExamples: [ - "func abc()↓{\n}", - "func abc()\n\t↓{ }", - "[].map()↓{ $0 }", - "[].map( ↓{ } )", - "if let a = b↓{ }", - "while a == b↓{ }", - "guard let a = b else↓{ }", - "if\n\tlet a = b,\n\tlet c = d\n\twhere a == c↓{ }", - "while\n\tlet a = b,\n\tlet c = d\n\twhere a == c↓{ }", - "guard\n\tlet a = b,\n\tlet c = d\n\twhere a == c else↓{ }", - "struct Rule↓{}\n", - "struct Rule\n↓{\n}\n", - "struct Rule\n\n\t↓{\n}\n", - "struct Parent {\n\tstruct Child\n\t↓{\n\t\tlet foo: Int\n\t}\n}\n", - """ + Example("func abc()↓{\n}"), + Example("func abc()\n\t↓{ }"), + Example("[].map()↓{ $0 }"), + Example("[].map( ↓{ } )"), + Example("if let a = b↓{ }"), + Example("while a == b↓{ }"), + Example("guard let a = b else↓{ }"), + Example("if\n\tlet a = b,\n\tlet c = d\n\twhere a == c↓{ }"), + Example("while\n\tlet a = b,\n\tlet c = d\n\twhere a == c↓{ }"), + Example("guard\n\tlet a = b,\n\tlet c = d\n\twhere a == c else↓{ }"), + Example("struct Rule↓{}\n"), + Example("struct Rule\n↓{\n}\n"), + Example("struct Rule\n\n\t↓{\n}\n"), + Example("struct Parent {\n\tstruct Child\n\t↓{\n\t\tlet foo: Int\n\t}\n}\n"), + Example(""" // Get the current thread's TLS pointer. On first call for a given thread, // creates and initializes a new one. internal static func getPointer() @@ -111,8 +111,8 @@ public struct OpeningBraceRule: CorrectableRule, ConfigurationProviderRule, Auto return _swift_stdlib_threadLocalStorageGet().assumingMemoryBound( to: _ThreadLocalStorage.self) } - """, - """ + """), + Example(""" func run_Array_method1x(_ N: Int) { let existentialArray = array! for _ in 0 ..< N * 100 { @@ -127,18 +127,18 @@ public struct OpeningBraceRule: CorrectableRule, ConfigurationProviderRule, Auto func run_Array_method2x(_ N: Int) { } - """ + """) ], corrections: [ - "struct Rule↓{}\n": "struct Rule {}\n", - "struct Rule\n↓{\n}\n": "struct Rule {\n}\n", - "struct Rule\n\n\t↓{\n}\n": "struct Rule {\n}\n", - "struct Parent {\n\tstruct Child\n\t↓{\n\t\tlet foo: Int\n\t}\n}\n": - "struct Parent {\n\tstruct Child {\n\t\tlet foo: Int\n\t}\n}\n", - "[].map()↓{ $0 }\n": "[].map() { $0 }\n", - "[].map( ↓{ })\n": "[].map({ })\n", - "if a == b↓{ }\n": "if a == b { }\n", - "if\n\tlet a = b,\n\tlet c = d↓{ }\n": "if\n\tlet a = b,\n\tlet c = d { }\n" + Example("struct Rule↓{}\n"): Example("struct Rule {}\n"), + Example("struct Rule\n↓{\n}\n"): Example("struct Rule {\n}\n"), + Example("struct Rule\n\n\t↓{\n}\n"): Example("struct Rule {\n}\n"), + Example("struct Parent {\n\tstruct Child\n\t↓{\n\t\tlet foo: Int\n\t}\n}\n"): + Example("struct Parent {\n\tstruct Child {\n\t\tlet foo: Int\n\t}\n}\n"), + Example("[].map()↓{ $0 }\n"): Example("[].map() { $0 }\n"), + Example("[].map( ↓{ })\n"): Example("[].map({ })\n"), + Example("if a == b↓{ }\n"): Example("if a == b { }\n"), + Example("if\n\tlet a = b,\n\tlet c = d↓{ }\n"): Example("if\n\tlet a = b,\n\tlet c = d { }\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/OperatorFunctionWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/OperatorFunctionWhitespaceRule.swift index 4986429a17..3e843cf419 100644 --- a/Source/SwiftLintFramework/Rules/Style/OperatorFunctionWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/OperatorFunctionWhitespaceRule.swift @@ -11,17 +11,17 @@ public struct OperatorFunctionWhitespaceRule: ConfigurationProviderRule, Automat description: "Operators should be surrounded by a single whitespace when defining them.", kind: .style, nonTriggeringExamples: [ - "func <| (lhs: Int, rhs: Int) -> Int {}\n", - "func <|< (lhs: A, rhs: A) -> A {}\n", - "func abc(lhs: Int, rhs: Int) -> Int {}\n" + Example("func <| (lhs: Int, rhs: Int) -> Int {}\n"), + Example("func <|< (lhs: A, rhs: A) -> A {}\n"), + Example("func abc(lhs: Int, rhs: Int) -> Int {}\n") ], triggeringExamples: [ - "↓func <|(lhs: Int, rhs: Int) -> Int {}\n", // no spaces after - "↓func <|<(lhs: A, rhs: A) -> A {}\n", // no spaces after - "↓func <| (lhs: Int, rhs: Int) -> Int {}\n", // 2 spaces after - "↓func <|< (lhs: A, rhs: A) -> A {}\n", // 2 spaces after - "↓func <| (lhs: Int, rhs: Int) -> Int {}\n", // 2 spaces before - "↓func <|< (lhs: A, rhs: A) -> A {}\n" // 2 spaces before + Example("↓func <|(lhs: Int, rhs: Int) -> Int {}\n"), // no spaces after + Example("↓func <|<(lhs: A, rhs: A) -> A {}\n"), // no spaces after + Example("↓func <| (lhs: Int, rhs: Int) -> Int {}\n"), // 2 spaces after + Example("↓func <|< (lhs: A, rhs: A) -> A {}\n"), // 2 spaces after + Example("↓func <| (lhs: Int, rhs: Int) -> Int {}\n"), // 2 spaces before + Example("↓func <|< (lhs: A, rhs: A) -> A {}\n") // 2 spaces before ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/OperatorUsageWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/OperatorUsageWhitespaceRule.swift index 0f6daf94e9..d414bbb535 100644 --- a/Source/SwiftLintFramework/Rules/Style/OperatorUsageWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/OperatorUsageWhitespaceRule.swift @@ -14,59 +14,59 @@ public struct OperatorUsageWhitespaceRule: OptInRule, CorrectableRule, Configura "when they are being used.", kind: .style, nonTriggeringExamples: [ - "let foo = 1 + 2\n", - "let foo = 1 > 2\n", - "let foo = !false\n", - "let foo: Int?\n", - "let foo: Array\n", - "let model = CustomView, NSAttributedString>()\n", - "let foo: [String]\n", - "let foo = 1 + \n 2\n", - "let range = 1...3\n", - "let range = 1 ... 3\n", - "let range = 1..<3\n", - "#if swift(>=3.0)\n foo()\n#endif\n", - "array.removeAtIndex(-200)\n", - "let name = \"image-1\"\n", - "button.setImage(#imageLiteral(resourceName: \"image-1\"), for: .normal)\n", - "let doubleValue = -9e-11\n", - "let foo = GenericType<(UIViewController) -> Void>()\n", - "let foo = Foo, Baz>()\n", - "let foo = SignalProducer, Error>([ self.signal, next ]).flatten(.concat)\n" + Example("let foo = 1 + 2\n"), + Example("let foo = 1 > 2\n"), + Example("let foo = !false\n"), + Example("let foo: Int?\n"), + Example("let foo: Array\n"), + Example("let model = CustomView, NSAttributedString>()\n"), + Example("let foo: [String]\n"), + Example("let foo = 1 + \n 2\n"), + Example("let range = 1...3\n"), + Example("let range = 1 ... 3\n"), + Example("let range = 1..<3\n"), + Example("#if swift(>=3.0)\n foo()\n#endif\n"), + Example("array.removeAtIndex(-200)\n"), + Example("let name = \"image-1\"\n"), + Example("button.setImage(#imageLiteral(resourceName: \"image-1\"), for: .normal)\n"), + Example("let doubleValue = -9e-11\n"), + Example("let foo = GenericType<(UIViewController) -> Void>()\n"), + Example("let foo = Foo, Baz>()\n"), + Example("let foo = SignalProducer, Error>([ self.signal, next ]).flatten(.concat)\n") ], triggeringExamples: [ - "let foo = 1↓+2\n", - "let foo = 1↓ + 2\n", - "let foo = 1↓ + 2\n", - "let foo = 1↓ + 2\n", - "let foo↓=1↓+2\n", - "let foo↓=1 + 2\n", - "let foo↓=bar\n", - "let range = 1↓ ..< 3\n", - "let foo = bar↓ ?? 0\n", - "let foo = bar↓??0\n", - "let foo = bar↓ != 0\n", - "let foo = bar↓ !== bar2\n", - "let v8 = Int8(1)↓ << 6\n", - "let v8 = 1↓ << (6)\n", - "let v8 = 1↓ << (6)\n let foo = 1 > 2\n" + Example("let foo = 1↓+2\n"), + Example("let foo = 1↓ + 2\n"), + Example("let foo = 1↓ + 2\n"), + Example("let foo = 1↓ + 2\n"), + Example("let foo↓=1↓+2\n"), + Example("let foo↓=1 + 2\n"), + Example("let foo↓=bar\n"), + Example("let range = 1↓ ..< 3\n"), + Example("let foo = bar↓ ?? 0\n"), + Example("let foo = bar↓??0\n"), + Example("let foo = bar↓ != 0\n"), + Example("let foo = bar↓ !== bar2\n"), + Example("let v8 = Int8(1)↓ << 6\n"), + Example("let v8 = 1↓ << (6)\n"), + Example("let v8 = 1↓ << (6)\n let foo = 1 > 2\n") ], corrections: [ - "let foo = 1↓+2\n": "let foo = 1 + 2\n", - "let foo = 1↓ + 2\n": "let foo = 1 + 2\n", - "let foo = 1↓ + 2\n": "let foo = 1 + 2\n", - "let foo = 1↓ + 2\n": "let foo = 1 + 2\n", - "let foo↓=1↓+2\n": "let foo = 1 + 2\n", - "let foo↓=1 + 2\n": "let foo = 1 + 2\n", - "let foo↓=bar\n": "let foo = bar\n", - "let range = 1↓ ..< 3\n": "let range = 1..<3\n", - "let foo = bar↓ ?? 0\n": "let foo = bar ?? 0\n", - "let foo = bar↓??0\n": "let foo = bar ?? 0\n", - "let foo = bar↓ != 0\n": "let foo = bar != 0\n", - "let foo = bar↓ !== bar2\n": "let foo = bar !== bar2\n", - "let v8 = Int8(1)↓ << 6\n": "let v8 = Int8(1) << 6\n", - "let v8 = 1↓ << (6)\n": "let v8 = 1 << (6)\n", - "let v8 = 1↓ << (6)\n let foo = 1 > 2\n": "let v8 = 1 << (6)\n let foo = 1 > 2\n" + Example("let foo = 1↓+2\n"): Example("let foo = 1 + 2\n"), + Example("let foo = 1↓ + 2\n"): Example("let foo = 1 + 2\n"), + Example("let foo = 1↓ + 2\n"): Example("let foo = 1 + 2\n"), + Example("let foo = 1↓ + 2\n"): Example("let foo = 1 + 2\n"), + Example("let foo↓=1↓+2\n"): Example("let foo = 1 + 2\n"), + Example("let foo↓=1 + 2\n"): Example("let foo = 1 + 2\n"), + Example("let foo↓=bar\n"): Example("let foo = bar\n"), + Example("let range = 1↓ ..< 3\n"): Example("let range = 1..<3\n"), + Example("let foo = bar↓ ?? 0\n"): Example("let foo = bar ?? 0\n"), + Example("let foo = bar↓??0\n"): Example("let foo = bar ?? 0\n"), + Example("let foo = bar↓ != 0\n"): Example("let foo = bar != 0\n"), + Example("let foo = bar↓ !== bar2\n"): Example("let foo = bar !== bar2\n"), + Example("let v8 = Int8(1)↓ << 6\n"): Example("let v8 = Int8(1) << 6\n"), + Example("let v8 = 1↓ << (6)\n"): Example("let v8 = 1 << (6)\n"), + Example("let v8 = 1↓ << (6)\n let foo = 1 > 2\n"): Example("let v8 = 1 << (6)\n let foo = 1 > 2\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/OptionalEnumCaseMatchingRule.swift b/Source/SwiftLintFramework/Rules/Style/OptionalEnumCaseMatchingRule.swift index 7fe906a262..a4b7c2b42f 100644 --- a/Source/SwiftLintFramework/Rules/Style/OptionalEnumCaseMatchingRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/OptionalEnumCaseMatchingRule.swift @@ -14,125 +14,125 @@ public struct OptionalEnumCaseMatchingRule: SubstitutionCorrectableASTRule, Conf kind: .style, minSwiftVersion: .fiveDotOne, nonTriggeringExamples: [ - """ + Example(""" switch foo { case .bar: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case (.bar, .baz): break case (.bar, _): break case (_, .baz): break default: break } - """ + """) ], triggeringExamples: [ - """ + Example(""" switch foo { case .bar↓?: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case Foo.bar↓?: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case .bar↓?, .baz↓?: break default: break } - """, - """ + """), + Example(""" switch foo { case .bar↓? where x > 1: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case (.bar↓?, .baz↓?): break case (.bar↓?, _): break case (_, .bar↓?): break default: break } - """ + """) ], corrections: [ - """ + Example(""" switch foo { case .bar↓?: break case .baz: break default: break } - """: """ + """): Example(""" switch foo { case .bar: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case Foo.bar↓?: break case .baz: break default: break } - """: """ + """): Example(""" switch foo { case Foo.bar: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case .bar↓?, .baz↓?: break default: break } - """: """ + """): Example(""" switch foo { case .bar, .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case .bar↓? where x > 1: break case .baz: break default: break } - """: """ + """): Example(""" switch foo { case .bar where x > 1: break case .baz: break default: break } - """, - """ + """), + Example(""" switch foo { case (.bar↓?, .baz↓?): break case (.bar↓?, _): break case (_, .bar↓?): break default: break } - """: """ + """): Example(""" switch foo { case (.bar, .baz): break case (.bar, _): break case (_, .bar): break default: break } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/PreferSelfTypeOverTypeOfSelfRule.swift b/Source/SwiftLintFramework/Rules/Style/PreferSelfTypeOverTypeOfSelfRule.swift index 503252a23c..31ce9d17f9 100644 --- a/Source/SwiftLintFramework/Rules/Style/PreferSelfTypeOverTypeOfSelfRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/PreferSelfTypeOverTypeOfSelfRule.swift @@ -12,98 +12,98 @@ public struct PreferSelfTypeOverTypeOfSelfRule: OptInRule, ConfigurationProvider kind: .style, minSwiftVersion: .fiveDotOne, nonTriggeringExamples: [ - """ + Example(""" class Foo { func bar() { Self.baz() } } - """, - """ + """), + Example(""" class Foo { func bar() { print(Self.baz) } } - """, - """ + """), + Example(""" class A { func foo(param: B) { type(of: param).bar() } } - """, - """ + """), + Example(""" class A { func foo() { print(type(of: self)) } } - """ + """) ], triggeringExamples: [ - """ + Example(""" class Foo { func bar() { ↓type(of: self).baz() } } - """, - """ + """), + Example(""" class Foo { func bar() { print(↓type(of: self).baz) } } - """, - """ + """), + Example(""" class Foo { func bar() { print(↓Swift.type(of: self).baz) } } - """ + """) ], corrections: [ - """ + Example(""" class Foo { func bar() { ↓type(of: self).baz() } } - """: """ + """): Example(""" class Foo { func bar() { Self.baz() } } - """, - """ + """), + Example(""" class Foo { func bar() { print(↓type(of: self).baz) } } - """: """ + """): Example(""" class Foo { func bar() { print(Self.baz) } } - """, - """ + """), + Example(""" class Foo { func bar() { print(↓Swift.type(of: self).baz) } } - """: """ + """): Example(""" class Foo { func bar() { print(Self.baz) } } - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/PrefixedTopLevelConstantRule.swift b/Source/SwiftLintFramework/Rules/Style/PrefixedTopLevelConstantRule.swift index 29f523e530..8d87fde996 100644 --- a/Source/SwiftLintFramework/Rules/Style/PrefixedTopLevelConstantRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/PrefixedTopLevelConstantRule.swift @@ -13,40 +13,40 @@ public struct PrefixedTopLevelConstantRule: ASTRule, OptInRule, ConfigurationPro description: "Top-level constants should be prefixed by `k`.", kind: .style, nonTriggeringExamples: [ - "private let kFoo = 20.0", - "public let kFoo = false", - "internal let kFoo = \"Foo\"", - "let kFoo = true", - "struct Foo {\n" + + Example("private let kFoo = 20.0"), + Example("public let kFoo = false"), + Example("internal let kFoo = \"Foo\""), + Example("let kFoo = true"), + Example("struct Foo {\n" + " let bar = 20.0\n" + - "}", - "private var foo = 20.0", - "public var foo = false", - "internal var foo = \"Foo\"", - "var foo = true", - "var foo = true, bar = true", - "var foo = true, let kFoo = true", - "let\n" + - " kFoo = true", - "var foo: Int {\n" + + "}"), + Example("private var foo = 20.0"), + Example("public var foo = false"), + Example("internal var foo = \"Foo\""), + Example("var foo = true"), + Example("var foo = true, bar = true"), + Example("var foo = true, let kFoo = true"), + Example("let\n" + + " kFoo = true"), + Example("var foo: Int {\n" + " return a + b\n" + - "}", - "let kFoo = {\n" + + "}"), + Example("let kFoo = {\n" + " return a + b\n" + - "}()" + "}()") ], triggeringExamples: [ - "private let ↓Foo = 20.0", - "public let ↓Foo = false", - "internal let ↓Foo = \"Foo\"", - "let ↓Foo = true", - "let ↓foo = 2, ↓bar = true", - "var foo = true, let ↓Foo = true", - "let\n" + - " ↓foo = true", - "let ↓foo = {\n" + + Example("private let ↓Foo = 20.0"), + Example("public let ↓Foo = false"), + Example("internal let ↓Foo = \"Foo\""), + Example("let ↓Foo = true"), + Example("let ↓foo = 2, ↓bar = true"), + Example("var foo = true, let ↓Foo = true"), + Example("let\n" + + " ↓foo = true"), + Example("let ↓foo = {\n" + " return a + b\n" + - "}()" + "}()") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ProtocolPropertyAccessorsOrderRule.swift b/Source/SwiftLintFramework/Rules/Style/ProtocolPropertyAccessorsOrderRule.swift index c83eff69e3..a5d7e4e287 100644 --- a/Source/SwiftLintFramework/Rules/Style/ProtocolPropertyAccessorsOrderRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ProtocolPropertyAccessorsOrderRule.swift @@ -13,16 +13,16 @@ public struct ProtocolPropertyAccessorsOrderRule: ConfigurationProviderRule, Sub description: "When declaring properties in protocols, the order of accessors should be `get set`.", kind: .style, nonTriggeringExamples: [ - "protocol Foo {\n var bar: String { get set }\n }", - "protocol Foo {\n var bar: String { get }\n }", - "protocol Foo {\n var bar: String { set }\n }" + Example("protocol Foo {\n var bar: String { get set }\n }"), + Example("protocol Foo {\n var bar: String { get }\n }"), + Example("protocol Foo {\n var bar: String { set }\n }") ], triggeringExamples: [ - "protocol Foo {\n var bar: String { ↓set get }\n }" + Example("protocol Foo {\n var bar: String { ↓set get }\n }") ], corrections: [ - "protocol Foo {\n var bar: String { ↓set get }\n }": - "protocol Foo {\n var bar: String { get set }\n }" + Example("protocol Foo {\n var bar: String { ↓set get }\n }"): + Example("protocol Foo {\n var bar: String { get set }\n }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/RedundantDiscardableLetRule.swift b/Source/SwiftLintFramework/Rules/Style/RedundantDiscardableLetRule.swift index 972213b240..cbbbda134c 100644 --- a/Source/SwiftLintFramework/Rules/Style/RedundantDiscardableLetRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/RedundantDiscardableLetRule.swift @@ -13,19 +13,19 @@ public struct RedundantDiscardableLetRule: SubstitutionCorrectableRule, Configur description: "Prefer `_ = foo()` over `let _ = foo()` when discarding a result from a function.", kind: .style, nonTriggeringExamples: [ - "_ = foo()\n", - "if let _ = foo() { }\n", - "guard let _ = foo() else { return }\n", - "let _: ExplicitType = foo()", - "while let _ = SplashStyle(rawValue: maxValue) { maxValue += 1 }\n" + Example("_ = foo()\n"), + Example("if let _ = foo() { }\n"), + Example("guard let _ = foo() else { return }\n"), + Example("let _: ExplicitType = foo()"), + Example("while let _ = SplashStyle(rawValue: maxValue) { maxValue += 1 }\n") ], triggeringExamples: [ - "↓let _ = foo()\n", - "if _ = foo() { ↓let _ = bar() }\n" + Example("↓let _ = foo()\n"), + Example("if _ = foo() { ↓let _ = bar() }\n") ], corrections: [ - "↓let _ = foo()\n": "_ = foo()\n", - "if _ = foo() { ↓let _ = bar() }\n": "if _ = foo() { _ = bar() }\n" + Example("↓let _ = foo()\n"): Example("_ = foo()\n"), + Example("if _ = foo() { ↓let _ = bar() }\n"): Example("if _ = foo() { _ = bar() }\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ReturnArrowWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/ReturnArrowWhitespaceRule.swift index e1f1c9c00f..71e203f9e2 100644 --- a/Source/SwiftLintFramework/Rules/Style/ReturnArrowWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ReturnArrowWhitespaceRule.swift @@ -13,32 +13,32 @@ public struct ReturnArrowWhitespaceRule: CorrectableRule, ConfigurationProviderR "separate line.", kind: .style, nonTriggeringExamples: [ - "func abc() -> Int {}\n", - "func abc() -> [Int] {}\n", - "func abc() -> (Int, Int) {}\n", - "var abc = {(param: Int) -> Void in }\n", - "func abc() ->\n Int {}\n", - "func abc()\n -> Int {}\n" + Example("func abc() -> Int {}\n"), + Example("func abc() -> [Int] {}\n"), + Example("func abc() -> (Int, Int) {}\n"), + Example("var abc = {(param: Int) -> Void in }\n"), + Example("func abc() ->\n Int {}\n"), + Example("func abc()\n -> Int {}\n") ], triggeringExamples: [ - "func abc()↓->Int {}\n", - "func abc()↓->[Int] {}\n", - "func abc()↓->(Int, Int) {}\n", - "func abc()↓-> Int {}\n", - "func abc()↓ ->Int {}\n", - "func abc()↓ -> Int {}\n", - "var abc = {(param: Int)↓ ->Bool in }\n", - "var abc = {(param: Int)↓->Bool in }\n" + Example("func abc()↓->Int {}\n"), + Example("func abc()↓->[Int] {}\n"), + Example("func abc()↓->(Int, Int) {}\n"), + Example("func abc()↓-> Int {}\n"), + Example("func abc()↓ ->Int {}\n"), + Example("func abc()↓ -> Int {}\n"), + Example("var abc = {(param: Int)↓ ->Bool in }\n"), + Example("var abc = {(param: Int)↓->Bool in }\n") ], corrections: [ - "func abc()↓->Int {}\n": "func abc() -> Int {}\n", - "func abc()↓-> Int {}\n": "func abc() -> Int {}\n", - "func abc()↓ ->Int {}\n": "func abc() -> Int {}\n", - "func abc()↓ -> Int {}\n": "func abc() -> Int {}\n", - "func abc()↓\n -> Int {}\n": "func abc()\n -> Int {}\n", - "func abc()↓\n-> Int {}\n": "func abc()\n-> Int {}\n", - "func abc()↓ ->\n Int {}\n": "func abc() ->\n Int {}\n", - "func abc()↓ ->\nInt {}\n": "func abc() ->\nInt {}\n" + Example("func abc()↓->Int {}\n"): Example("func abc() -> Int {}\n"), + Example("func abc()↓-> Int {}\n"): Example("func abc() -> Int {}\n"), + Example("func abc()↓ ->Int {}\n"): Example("func abc() -> Int {}\n"), + Example("func abc()↓ -> Int {}\n"): Example("func abc() -> Int {}\n"), + Example("func abc()↓\n -> Int {}\n"): Example("func abc()\n -> Int {}\n"), + Example("func abc()↓\n-> Int {}\n"): Example("func abc()\n-> Int {}\n"), + Example("func abc()↓ ->\n Int {}\n"): Example("func abc() ->\n Int {}\n"), + Example("func abc()↓ ->\nInt {}\n"): Example("func abc() ->\nInt {}\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/ShorthandOperatorRule.swift b/Source/SwiftLintFramework/Rules/Style/ShorthandOperatorRule.swift index f1510dcabf..cb453b54d6 100644 --- a/Source/SwiftLintFramework/Rules/Style/ShorthandOperatorRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/ShorthandOperatorRule.swift @@ -13,31 +13,31 @@ public struct ShorthandOperatorRule: ConfigurationProviderRule, AutomaticTestabl kind: .style, nonTriggeringExamples: allOperators.flatMap { operation in [ - "foo \(operation)= 1", - "foo \(operation)= variable", - "foo \(operation)= bar.method()", - "self.foo = foo \(operation) 1", - "foo = self.foo \(operation) 1", - "page = ceilf(currentOffset \(operation) pageWidth)", - "foo = aMethod(foo \(operation) bar)", - "foo = aMethod(bar \(operation) foo)" + Example("foo \(operation)= 1"), + Example("foo \(operation)= variable"), + Example("foo \(operation)= bar.method()"), + Example("self.foo = foo \(operation) 1"), + Example("foo = self.foo \(operation) 1"), + Example("page = ceilf(currentOffset \(operation) pageWidth)"), + Example("foo = aMethod(foo \(operation) bar)"), + Example("foo = aMethod(bar \(operation) foo)") ] } + [ - "var helloWorld = \"world!\"\n helloWorld = \"Hello, \" + helloWorld", - "angle = someCheck ? angle : -angle", - "seconds = seconds * 60 + value" + Example("var helloWorld = \"world!\"\n helloWorld = \"Hello, \" + helloWorld"), + Example("angle = someCheck ? angle : -angle"), + Example("seconds = seconds * 60 + value") ], triggeringExamples: allOperators.flatMap { operation in [ - "↓foo = foo \(operation) 1\n", - "↓foo = foo \(operation) aVariable\n", - "↓foo = foo \(operation) bar.method()\n", - "↓foo.aProperty = foo.aProperty \(operation) 1\n", - "↓self.aProperty = self.aProperty \(operation) 1\n" + Example("↓foo = foo \(operation) 1\n"), + Example("↓foo = foo \(operation) aVariable\n"), + Example("↓foo = foo \(operation) bar.method()\n"), + Example("↓foo.aProperty = foo.aProperty \(operation) 1\n"), + Example("↓self.aProperty = self.aProperty \(operation) 1\n") ] } + [ - "n = n + i / outputLength", - "n = n - i / outputLength" + Example("n = n + i / outputLength"), + Example("n = n - i / outputLength") // "d = d * 60 * 60" ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/SingleTestClassRule.swift b/Source/SwiftLintFramework/Rules/Style/SingleTestClassRule.swift index 826ca91f36..5caa5e987f 100644 --- a/Source/SwiftLintFramework/Rules/Style/SingleTestClassRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/SingleTestClassRule.swift @@ -9,17 +9,38 @@ public struct SingleTestClassRule: Rule, OptInRule, ConfigurationProviderRule, A description: "Test files should contain a single QuickSpec or XCTestCase class.", kind: .style, nonTriggeringExamples: [ - "class FooTests { }\n", - "class FooTests: QuickSpec { }\n", - "class FooTests: XCTestCase { }\n" + Example("class FooTests { }\n"), + Example("class FooTests: QuickSpec { }\n"), + Example("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: 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", - "↓class FooTests: QuickSpec { }\n↓class BarTests: XCTestCase { }\nclass TotoTests { }\n" + Example(""" + ↓class FooTests: QuickSpec { } + ↓class BarTests: QuickSpec { } + """), + Example(""" + ↓class FooTests: QuickSpec { } + ↓class BarTests: QuickSpec { } + ↓class TotoTests: QuickSpec { } + """), + Example(""" + ↓class FooTests: XCTestCase { } + ↓class BarTests: XCTestCase { } + """), + Example(""" + ↓class FooTests: XCTestCase { } + ↓class BarTests: XCTestCase { } + ↓class TotoTests: XCTestCase { } + """), + Example(""" + ↓class FooTests: QuickSpec { } + ↓class BarTests: XCTestCase { } + """), + Example(""" + ↓class FooTests: QuickSpec { } + ↓class BarTests: XCTestCase { } + class TotoTests { } + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/SortedImportsRule.swift b/Source/SwiftLintFramework/Rules/Style/SortedImportsRule.swift index 49108204e6..51946e05d7 100644 --- a/Source/SwiftLintFramework/Rules/Style/SortedImportsRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/SortedImportsRule.swift @@ -57,13 +57,13 @@ public struct SortedImportsRule: CorrectableRule, ConfigurationProviderRule, Opt description: "Imports should be sorted.", kind: .style, nonTriggeringExamples: [ - "import AAA\nimport BBB\nimport CCC\nimport DDD", - "import Alamofire\nimport API", - "import labc\nimport Ldef", - "import BBB\n// comment\nimport AAA\nimport CCC", - "@testable import AAA\nimport CCC", - "import AAA\n@testable import CCC", - """ + Example("import AAA\nimport BBB\nimport CCC\nimport DDD"), + Example("import Alamofire\nimport API"), + Example("import labc\nimport Ldef"), + Example("import BBB\n// comment\nimport AAA\nimport CCC"), + Example("@testable import AAA\nimport CCC"), + Example("import AAA\n@testable import CCC"), + Example(""" import EEE.A import FFF.B #if os(Linux) @@ -75,14 +75,14 @@ public struct SortedImportsRule: CorrectableRule, ConfigurationProviderRule, Opt #endif import AAA import BBB - """ + """) ], triggeringExamples: [ - "import AAA\nimport ZZZ\nimport ↓BBB\nimport CCC", - "import DDD\n// comment\nimport CCC\nimport ↓AAA", - "@testable import CCC\nimport ↓AAA", - "import CCC\n@testable import ↓AAA", - """ + Example("import AAA\nimport ZZZ\nimport ↓BBB\nimport CCC"), + Example("import DDD\n// comment\nimport CCC\nimport ↓AAA"), + Example("@testable import CCC\nimport ↓AAA"), + Example("import CCC\n@testable import ↓AAA"), + Example(""" import FFF.B import ↓EEE.A #if os(Linux) @@ -94,15 +94,17 @@ public struct SortedImportsRule: CorrectableRule, ConfigurationProviderRule, Opt #endif import AAA import BBB - """ + """) ], corrections: [ - "import AAA\nimport ZZZ\nimport ↓BBB\nimport CCC": "import AAA\nimport BBB\nimport CCC\nimport ZZZ", - "import BBB // comment\nimport ↓AAA": "import AAA\nimport BBB // comment", - "import BBB\n// comment\nimport CCC\nimport ↓AAA": "import BBB\n// comment\nimport AAA\nimport CCC", - "@testable import CCC\nimport ↓AAA": "import AAA\n@testable import CCC", - "import CCC\n@testable import ↓AAA": "@testable import AAA\nimport CCC", - """ + Example("import AAA\nimport ZZZ\nimport ↓BBB\nimport CCC"): + Example("import AAA\nimport BBB\nimport CCC\nimport ZZZ"), + Example("import BBB // comment\nimport ↓AAA"): Example("import AAA\nimport BBB // comment"), + Example("import BBB\n// comment\nimport CCC\nimport ↓AAA"): + Example("import BBB\n// comment\nimport AAA\nimport CCC"), + Example("@testable import CCC\nimport ↓AAA"): Example("import AAA\n@testable import CCC"), + Example("import CCC\n@testable import ↓AAA"): Example("@testable import AAA\nimport CCC"), + Example(""" import FFF.B import ↓EEE.A #if os(Linux) @@ -114,8 +116,8 @@ public struct SortedImportsRule: CorrectableRule, ConfigurationProviderRule, Opt #endif import AAA import BBB - """: - """ + """): + Example(""" import EEE.A import FFF.B #if os(Linux) @@ -127,7 +129,7 @@ public struct SortedImportsRule: CorrectableRule, ConfigurationProviderRule, Opt #endif import AAA import BBB - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/StatementPositionRule.swift b/Source/SwiftLintFramework/Rules/Style/StatementPositionRule.swift index 6715ffb97b..6b31ff9ccf 100644 --- a/Source/SwiftLintFramework/Rules/Style/StatementPositionRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/StatementPositionRule.swift @@ -14,23 +14,23 @@ public struct StatementPositionRule: CorrectableRule, ConfigurationProviderRule "declaration.", kind: .style, nonTriggeringExamples: [ - "} else if {", - "} else {", - "} catch {", - "\"}else{\"", - "struct A { let catchphrase: Int }\nlet a = A(\n catchphrase: 0\n)", - "struct A { let `catch`: Int }\nlet a = A(\n `catch`: 0\n)" + Example("} else if {"), + Example("} else {"), + Example("} catch {"), + Example("\"}else{\""), + Example("struct A { let catchphrase: Int }\nlet a = A(\n catchphrase: 0\n)"), + Example("struct A { let `catch`: Int }\nlet a = A(\n `catch`: 0\n)") ], triggeringExamples: [ - "↓}else if {", - "↓} else {", - "↓}\ncatch {", - "↓}\n\t catch {" + Example("↓}else if {"), + Example("↓} else {"), + Example("↓}\ncatch {"), + Example("↓}\n\t catch {") ], corrections: [ - "↓}\n else {\n": "} else {\n", - "↓}\n else if {\n": "} else if {\n", - "↓}\n catch {\n": "} catch {\n" + Example("↓}\n else {\n"): Example("} else {\n"), + Example("↓}\n else if {\n"): Example("} else if {\n"), + Example("↓}\n catch {\n"): Example("} catch {\n") ] ) @@ -41,26 +41,26 @@ public struct StatementPositionRule: CorrectableRule, ConfigurationProviderRule "previous declaration.", kind: .style, nonTriggeringExamples: [ - " }\n else if {", - " }\n else {", - " }\n catch {", - " }\n\n catch {", - "\n\n }\n catch {", - "\"}\nelse{\"", - "struct A { let catchphrase: Int }\nlet a = A(\n catchphrase: 0\n)", - "struct A { let `catch`: Int }\nlet a = A(\n `catch`: 0\n)" + Example(" }\n else if {"), + Example(" }\n else {"), + Example(" }\n catch {"), + Example(" }\n\n catch {"), + Example("\n\n }\n catch {"), + Example("\"}\nelse{\""), + Example("struct A { let catchphrase: Int }\nlet a = A(\n catchphrase: 0\n)"), + Example("struct A { let `catch`: Int }\nlet a = A(\n `catch`: 0\n)") ], triggeringExamples: [ - "↓ }else if {", - "↓}\n else {", - "↓ }\ncatch {", - "↓}\n\t catch {" + Example("↓ }else if {"), + Example("↓}\n else {"), + Example("↓ }\ncatch {"), + Example("↓}\n\t catch {") ], corrections: [ - " }else if {": " }\n else if {", - "}\n else {": "}\nelse {", - " }\ncatch {": " }\n catch {", - "}\n\t catch {": "}\ncatch {" + Example(" }else if {"): Example(" }\n else if {"), + Example("}\n else {"): Example("}\nelse {"), + Example(" }\ncatch {"): Example(" }\n catch {"), + Example("}\n\t catch {"): Example("}\ncatch {") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/SwitchCaseAlignmentRule.swift b/Source/SwiftLintFramework/Rules/Style/SwitchCaseAlignmentRule.swift index 25f0817420..eed930662a 100644 --- a/Source/SwiftLintFramework/Rules/Style/SwitchCaseAlignmentRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/SwitchCaseAlignmentRule.swift @@ -82,27 +82,27 @@ extension SwitchCaseAlignmentRule { self.indentedCasesOption = indentedCases } - var triggeringExamples: [String] { + var triggeringExamples: [Example] { return (indentedCasesOption ? nonIndentedCases : indentedCases) + invalidCases } - var nonTriggeringExamples: [String] { + var nonTriggeringExamples: [Example] { return indentedCasesOption ? indentedCases : nonIndentedCases } - private var indentedCases: [String] { + private var indentedCases: [Example] { let violationMarker = indentedCasesOption ? "" : self.violationMarker return [ - """ + Example(""" switch someBool { \(violationMarker)case true: print("red") \(violationMarker)case false: print("blue") } - """, - """ + """), + Example(""" if aBool { switch someBool { \(violationMarker)case true: @@ -111,8 +111,8 @@ extension SwitchCaseAlignmentRule { print('blue') } } - """, - """ + """), + Example(""" switch someInt { \(violationMarker)case 0: print('Zero') @@ -121,15 +121,15 @@ extension SwitchCaseAlignmentRule { \(violationMarker)default: print('Some other number') } - """ + """) ] } - private var nonIndentedCases: [String] { + private var nonIndentedCases: [Example] { let violationMarker = indentedCasesOption ? self.violationMarker : "" return [ - """ + Example(""" switch someBool { \(violationMarker)case true: // case 1 print('red') @@ -144,8 +144,8 @@ extension SwitchCaseAlignmentRule { enum SomeEnum { case innocent } - """, - """ + """), + Example(""" if aBool { switch someBool { \(violationMarker)case true: @@ -154,8 +154,8 @@ extension SwitchCaseAlignmentRule { print('blue') } } - """, - """ + """), + Example(""" switch someInt { // comments ignored \(violationMarker)case 0: @@ -166,23 +166,23 @@ extension SwitchCaseAlignmentRule { \(violationMarker)default: print('Some other number') } - """ + """) ] } - private var invalidCases: [String] { + private var invalidCases: [Example] { let indentation = indentedCasesOption ? " " : "" return [ - """ + Example(""" switch someBool { \(indentation)case true: \(indentation)print('red') \(indentation)\(violationMarker)case false: \(indentation)print('blue') } - """, - """ + """), + Example(""" if aBool { switch someBool { \(indentation)\(indentedCasesOption ? "" : violationMarker)case true: @@ -191,7 +191,7 @@ extension SwitchCaseAlignmentRule { \(indentation)print('blue') } } - """ + """) ] } } diff --git a/Source/SwiftLintFramework/Rules/Style/SwitchCaseOnNewlineRule.swift b/Source/SwiftLintFramework/Rules/Style/SwitchCaseOnNewlineRule.swift index e0e479eafc..7c5bed6a46 100644 --- a/Source/SwiftLintFramework/Rules/Style/SwitchCaseOnNewlineRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/SwitchCaseOnNewlineRule.swift @@ -1,7 +1,11 @@ import SourceKittenFramework -private func wrapInSwitch(_ str: String) -> String { - return "switch foo {\n \(str)\n}\n" +private func wrapInSwitch(_ str: String, file: StaticString = #file, line: UInt = #line) -> Example { + return Example(""" + switch foo { + \(str) + } + """, file: file, line: line) } public struct SwitchCaseOnNewlineRule: ASTRule, ConfigurationProviderRule, OptInRule, AutomaticTestableRule { @@ -15,37 +19,41 @@ public struct SwitchCaseOnNewlineRule: ASTRule, ConfigurationProviderRule, OptIn description: "Cases inside a switch should always be on a newline", kind: .style, nonTriggeringExamples: [ - "/*case 1: */return true", - "//case 1:\n return true", - "let x = [caseKey: value]", - "let x = [key: .default]", - "if case let .someEnum(value) = aFunction([key: 2]) { }", - "guard case let .someEnum(value) = aFunction([key: 2]) { }", - "for case let .someEnum(value) = aFunction([key: 2]) { }", - "enum Environment {\n case development\n}", - "enum Environment {\n case development(url: URL)\n}", - "enum Environment {\n case development(url: URL) // staging\n}" - ] + [ - "case 1:\n return true", - "default:\n return true", - "case let value:\n return true", - "case .myCase: // error from network\n return true", - "case let .myCase(value) where value > 10:\n return false", - "case let .myCase(value)\n where value > 10:\n return false", - "case let .myCase(code: lhsErrorCode, description: _)\n where lhsErrorCode > 10:\n return false", - "case #selector(aFunction(_:)):\n return false\n" - ].map(wrapInSwitch), + Example("/*case 1: */return true"), + Example("//case 1:\n return true"), + Example("let x = [caseKey: value]"), + Example("let x = [key: .default]"), + Example("if case let .someEnum(value) = aFunction([key: 2]) { }"), + Example("guard case let .someEnum(value) = aFunction([key: 2]) { }"), + Example("for case let .someEnum(value) = aFunction([key: 2]) { }"), + Example("enum Environment {\n case development\n}"), + Example("enum Environment {\n case development(url: URL)\n}"), + Example("enum Environment {\n case development(url: URL) // staging\n}"), + + wrapInSwitch("case 1:\n return true"), + wrapInSwitch("default:\n return true"), + wrapInSwitch("case let value:\n return true"), + wrapInSwitch("case .myCase: // error from network\n return true"), + wrapInSwitch("case let .myCase(value) where value > 10:\n return false"), + wrapInSwitch("case let .myCase(value)\n where value > 10:\n return false"), + wrapInSwitch(""" + case let .myCase(code: lhsErrorCode, description: _) + where lhsErrorCode > 10: + return false + """), + wrapInSwitch("case #selector(aFunction(_:)):\n return false\n") + ], triggeringExamples: [ - "↓case 1: return true", - "↓case let value: return true", - "↓default: return true", - "↓case \"a string\": return false", - "↓case .myCase: return false // error from network", - "↓case let .myCase(value) where value > 10: return false", - "↓case #selector(aFunction(_:)): return false\n", - "↓case let .myCase(value)\n where value > 10: return false", - "↓case .first,\n .second: return false" - ].map(wrapInSwitch) + wrapInSwitch("↓case 1: return true"), + wrapInSwitch("↓case let value: return true"), + wrapInSwitch("↓default: return true"), + wrapInSwitch("↓case \"a string\": return false"), + wrapInSwitch("↓case .myCase: return false // error from network"), + wrapInSwitch("↓case let .myCase(value) where value > 10: return false"), + wrapInSwitch("↓case #selector(aFunction(_:)): return false\n"), + wrapInSwitch("↓case let .myCase(value)\n where value > 10: return false"), + wrapInSwitch("↓case .first,\n .second: return false") + ] ) public func validate(file: SwiftLintFile, kind: StatementKind, diff --git a/Source/SwiftLintFramework/Rules/Style/TrailingClosureRule.swift b/Source/SwiftLintFramework/Rules/Style/TrailingClosureRule.swift index 72a471bb8b..64cf41cd41 100644 --- a/Source/SwiftLintFramework/Rules/Style/TrailingClosureRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/TrailingClosureRule.swift @@ -12,21 +12,21 @@ public struct TrailingClosureRule: OptInRule, ConfigurationProviderRule { description: "Trailing closure syntax should be used whenever possible.", kind: .style, nonTriggeringExamples: [ - "foo.map { $0 + 1 }\n", - "foo.bar()\n", - "foo.reduce(0) { $0 + 1 }\n", - "if let foo = bar.map({ $0 + 1 }) { }\n", - "foo.something(param1: { $0 }, param2: { $0 + 1 })\n", - "offsets.sorted { $0.offset < $1.offset }\n", - "foo.something({ return 1 }())", - "foo.something({ return $0 }(1))", - "foo.something(0, { return 1 }())" + Example("foo.map { $0 + 1 }\n"), + Example("foo.bar()\n"), + Example("foo.reduce(0) { $0 + 1 }\n"), + Example("if let foo = bar.map({ $0 + 1 }) { }\n"), + Example("foo.something(param1: { $0 }, param2: { $0 + 1 })\n"), + Example("offsets.sorted { $0.offset < $1.offset }\n"), + Example("foo.something({ return 1 }())"), + Example("foo.something({ return $0 }(1))"), + Example("foo.something(0, { return 1 }())") ], triggeringExamples: [ - "↓foo.map({ $0 + 1 })\n", - "↓foo.reduce(0, combine: { $0 + 1 })\n", - "↓offsets.sorted(by: { $0.offset < $1.offset })\n", - "↓foo.something(0, { $0 + 1 })\n" + Example("↓foo.map({ $0 + 1 })\n"), + Example("↓foo.reduce(0, combine: { $0 + 1 })\n"), + Example("↓offsets.sorted(by: { $0.offset < $1.offset })\n"), + Example("↓foo.something(0, { $0 + 1 })\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/TrailingCommaRule.swift b/Source/SwiftLintFramework/Rules/Style/TrailingCommaRule.swift index 915fa7d687..ffc46bca45 100644 --- a/Source/SwiftLintFramework/Rules/Style/TrailingCommaRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/TrailingCommaRule.swift @@ -13,22 +13,25 @@ public struct TrailingCommaRule: SubstitutionCorrectableASTRule, ConfigurationPr public init() {} - private static let triggeringExamples = [ - "let foo = [1, 2, 3↓,]\n", - "let foo = [1, 2, 3↓, ]\n", - "let foo = [1, 2, 3 ↓,]\n", - "let foo = [1: 2, 2: 3↓, ]\n", - "struct Bar {\n let foo = [1: 2, 2: 3↓, ]\n}\n", - "let foo = [1, 2, 3↓,] + [4, 5, 6↓,]\n", - "let example = [ 1,\n2↓,\n // 3,\n]", - "let foo = [\"אבג\", \"αβγ\", \"🇺🇸\"↓,]\n", - "class C {\n #if true\n func f() {\n let foo = [1, 2, 3↓,]\n }\n #endif\n}", - "foo([1: \"\\(error)\"↓,])\n" + private static let triggeringExamples: [Example] = [ + Example("let foo = [1, 2, 3↓,]\n"), + Example("let foo = [1, 2, 3↓, ]\n"), + Example("let foo = [1, 2, 3 ↓,]\n"), + Example("let foo = [1: 2, 2: 3↓, ]\n"), + Example("struct Bar {\n let foo = [1: 2, 2: 3↓, ]\n}\n"), + Example("let foo = [1, 2, 3↓,] + [4, 5, 6↓,]\n"), + Example("let example = [ 1,\n2↓,\n // 3,\n]"), + Example("let foo = [\"אבג\", \"αβγ\", \"🇺🇸\"↓,]\n"), + Example("class C {\n #if true\n func f() {\n let foo = [1, 2, 3↓,]\n }\n #endif\n}"), + Example("foo([1: \"\\(error)\"↓,])\n") ] - private static let corrections: [String: String] = { - let fixed = triggeringExamples.map { $0.replacingOccurrences(of: "↓,", with: "") } - var result: [String: String] = [:] + private static let corrections: [Example: Example] = { + let fixed = triggeringExamples.map { example -> Example in + let fixedString = example.code.replacingOccurrences(of: "↓,", with: "") + return example.with(code: fixedString) + } + var result: [Example: Example] = [:] for (triggering, correction) in zip(triggeringExamples, fixed) { result[triggering] = correction } @@ -41,13 +44,13 @@ public struct TrailingCommaRule: SubstitutionCorrectableASTRule, ConfigurationPr description: "Trailing commas in arrays and dictionaries should be avoided/enforced.", kind: .style, nonTriggeringExamples: [ - "let foo = [1, 2, 3]\n", - "let foo = []\n", - "let foo = [:]\n", - "let foo = [1: 2, 2: 3]\n", - "let foo = [Void]()\n", - "let example = [ 1,\n 2\n // 3,\n]", - "foo([1: \"\\(error)\"])\n" + Example("let foo = [1, 2, 3]\n"), + Example("let foo = []\n"), + Example("let foo = [:]\n"), + Example("let foo = [1: 2, 2: 3]\n"), + Example("let foo = [Void]()\n"), + Example("let example = [ 1,\n 2\n // 3,\n]"), + Example("foo([1: \"\\(error)\"])\n") ], triggeringExamples: TrailingCommaRule.triggeringExamples, corrections: TrailingCommaRule.corrections diff --git a/Source/SwiftLintFramework/Rules/Style/TrailingNewlineRule.swift b/Source/SwiftLintFramework/Rules/Style/TrailingNewlineRule.swift index 3dee64def0..86e89712f7 100644 --- a/Source/SwiftLintFramework/Rules/Style/TrailingNewlineRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/TrailingNewlineRule.swift @@ -29,16 +29,16 @@ public struct TrailingNewlineRule: CorrectableRule, ConfigurationProviderRule, S description: "Files should have a single trailing newline.", kind: .style, nonTriggeringExamples: [ - "let a = 0\n" + Example("let a = 0\n") ], triggeringExamples: [ - "let a = 0", - "let a = 0\n\n" + Example("let a = 0"), + Example("let a = 0\n\n") ], corrections: [ - "let a = 0": "let a = 0\n", - "let b = 0\n\n": "let b = 0\n", - "let c = 0\n\n\n\n": "let c = 0\n" + Example("let a = 0"): Example("let a = 0\n"), + Example("let b = 0\n\n"): Example("let b = 0\n"), + Example("let c = 0\n\n\n\n"): Example("let c = 0\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/TrailingWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/TrailingWhitespaceRule.swift index bddec2523c..f8bc4e03f6 100644 --- a/Source/SwiftLintFramework/Rules/Style/TrailingWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/TrailingWhitespaceRule.swift @@ -13,15 +13,15 @@ public struct TrailingWhitespaceRule: CorrectableRule, ConfigurationProviderRule description: "Lines should not have trailing whitespace.", kind: .style, nonTriggeringExamples: [ - "let name: String\n", "//\n", "// \n", - "let name: String //\n", "let name: String // \n" + Example("let name: String\n"), Example("//\n"), Example("// \n"), + Example("let name: String //\n"), Example("let name: String // \n") ], triggeringExamples: [ - "let name: String \n", "/* */ let name: String \n" + Example("let name: String \n"), Example("/* */ let name: String \n") ], corrections: [ - "let name: String \n": "let name: String\n", - "/* */ let name: String \n": "/* */ let name: String\n" + Example("let name: String \n"): Example("let name: String\n"), + Example("/* */ let name: String \n"): Example("/* */ let name: String\n") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/TypeContentsOrderRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/TypeContentsOrderRuleExamples.swift index 1778ceb3ab..1bd90ed706 100644 --- a/Source/SwiftLintFramework/Rules/Style/TypeContentsOrderRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/TypeContentsOrderRuleExamples.swift @@ -113,15 +113,15 @@ internal struct TypeContentsOrderRuleExamples { ] static let nonTriggeringExamples = [ - [ - "class TestViewController: UIViewController {", - TypeContentsOrderRuleExamples.defaultOrderParts.joined(separator: "\n\n"), - "}" - ].joined(separator: "\n") + Example(""" + class TestViewController: UIViewController { + \(TypeContentsOrderRuleExamples.defaultOrderParts.joined(separator: "\n\n")), + } + """) ] static let triggeringExamples = [ - """ + Example(""" class TestViewController: UIViewController { // Subtypes ↓class TestClass { @@ -131,8 +131,8 @@ internal struct TypeContentsOrderRuleExamples { // Type Aliases typealias CompletionHandler = ((TestEnum) -> Void) } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Stored Type Properties ↓static let cellIdentifier: String = "AmazingCell" @@ -142,8 +142,8 @@ internal struct TypeContentsOrderRuleExamples { // 10 lines } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Stored Instance Properties ↓var shouldLayoutView1: Bool! @@ -151,8 +151,8 @@ internal struct TypeContentsOrderRuleExamples { // Stored Type Properties static let cellIdentifier: String = "AmazingCell" } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // IBOutlets @IBOutlet private ↓var view1: UIView! @@ -162,8 +162,8 @@ internal struct TypeContentsOrderRuleExamples { return hasLayoutedView1 || hasLayoutedView2 } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // deinitializer @@ -180,8 +180,8 @@ internal struct TypeContentsOrderRuleExamples { @IBOutlet private var view1: UIView! @IBOutlet private var view2: UIView! } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // View Life-Cycle Methods override ↓func viewDidLoad() { @@ -197,8 +197,8 @@ internal struct TypeContentsOrderRuleExamples { // some code } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // IBActions @IBAction ↓func goNextButtonPressed() { @@ -215,8 +215,8 @@ internal struct TypeContentsOrderRuleExamples { hasLayoutedView1 = true } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Other Methods ↓func goToNextVc() { /* TODO */ } @@ -227,8 +227,8 @@ internal struct TypeContentsOrderRuleExamples { delegate?.didPressTrackedButton() } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Subscripts ↓subscript(_ someIndexThatIsNotEvenUsed: Int) -> String { @@ -244,6 +244,6 @@ internal struct TypeContentsOrderRuleExamples { // MARK: Other Methods func goToNextVc() { /* TODO */ } } - """ + """) ] } diff --git a/Source/SwiftLintFramework/Rules/Style/UnneededParenthesesInClosureArgumentRule.swift b/Source/SwiftLintFramework/Rules/Style/UnneededParenthesesInClosureArgumentRule.swift index 0cdbf541df..2db80c3d97 100644 --- a/Source/SwiftLintFramework/Rules/Style/UnneededParenthesesInClosureArgumentRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/UnneededParenthesesInClosureArgumentRule.swift @@ -13,18 +13,18 @@ public struct UnneededParenthesesInClosureArgumentRule: ConfigurationProviderRul description: "Parentheses are not needed when declaring closure arguments.", kind: .style, nonTriggeringExamples: [ - "let foo = { (bar: Int) in }\n", - "let foo = { bar, _ in }\n", - "let foo = { bar in }\n", - "let foo = { bar -> Bool in return true }\n" + Example("let foo = { (bar: Int) in }\n"), + Example("let foo = { bar, _ in }\n"), + Example("let foo = { bar in }\n"), + Example("let foo = { bar -> Bool in return true }\n") ], triggeringExamples: [ - "call(arg: { ↓(bar) in })\n", - "call(arg: { ↓(bar, _) in })\n", - "let foo = { ↓(bar) -> Bool in return true }\n", - "foo.map { ($0, $0) }.forEach { ↓(x, y) in }", - "foo.bar { [weak self] ↓(x, y) in }", - """ + Example("call(arg: { ↓(bar) in })\n"), + Example("call(arg: { ↓(bar, _) in })\n"), + Example("let foo = { ↓(bar) -> Bool in return true }\n"), + Example("foo.map { ($0, $0) }.forEach { ↓(x, y) in }"), + Example("foo.bar { [weak self] ↓(x, y) in }"), + Example(""" [].first { ↓(temp) in [].first { ↓(temp) in [].first { ↓(temp) in @@ -35,8 +35,8 @@ public struct UnneededParenthesesInClosureArgumentRule: ConfigurationProviderRul } return false } - """, - """ + """), + Example(""" [].first { temp in [].first { ↓(temp) in [].first { ↓(temp) in @@ -47,15 +47,16 @@ public struct UnneededParenthesesInClosureArgumentRule: ConfigurationProviderRul } return false } - """ + """) ], corrections: [ - "call(arg: { ↓(bar) in })\n": "call(arg: { bar in })\n", - "call(arg: { ↓(bar, _) in })\n": "call(arg: { bar, _ in })\n", - "let foo = { ↓(bar) -> Bool in return true }\n": "let foo = { bar -> Bool in return true }\n", - "method { ↓(foo, bar) in }\n": "method { foo, bar in }\n", - "foo.map { ($0, $0) }.forEach { ↓(x, y) in }": "foo.map { ($0, $0) }.forEach { x, y in }", - "foo.bar { [weak self] ↓(x, y) in }": "foo.bar { [weak self] x, y in }" + Example("call(arg: { ↓(bar) in })\n"): Example("call(arg: { bar in })\n"), + Example("call(arg: { ↓(bar, _) in })\n"): Example("call(arg: { bar, _ in })\n"), + Example("let foo = { ↓(bar) -> Bool in return true }\n"): + Example("let foo = { bar -> Bool in return true }\n"), + Example("method { ↓(foo, bar) in }\n"): Example("method { foo, bar in }\n"), + Example("foo.map { ($0, $0) }.forEach { ↓(x, y) in }"): Example("foo.map { ($0, $0) }.forEach { x, y in }"), + Example("foo.bar { [weak self] ↓(x, y) in }"): Example("foo.bar { [weak self] x, y in }") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/UnusedOptionalBindingRule.swift b/Source/SwiftLintFramework/Rules/Style/UnusedOptionalBindingRule.swift index 454c1d2bfc..9e43e3f102 100644 --- a/Source/SwiftLintFramework/Rules/Style/UnusedOptionalBindingRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/UnusedOptionalBindingRule.swift @@ -12,34 +12,34 @@ public struct UnusedOptionalBindingRule: ASTRule, ConfigurationProviderRule { description: "Prefer `!= nil` over `let _ =`", kind: .style, nonTriggeringExamples: [ - "if let bar = Foo.optionalValue {\n" + - "}\n", - "if let (_, second) = getOptionalTuple() {\n" + - "}\n", - "if let (_, asd, _) = getOptionalTuple(), let bar = Foo.optionalValue {\n" + - "}\n", - "if foo() { let _ = bar() }\n", - "if foo() { _ = bar() }\n", - "if case .some(_) = self {}", - "if let point = state.find({ _ in true }) {}" + Example("if let bar = Foo.optionalValue {\n" + + "}\n"), + Example("if let (_, second) = getOptionalTuple() {\n" + + "}\n"), + Example("if let (_, asd, _) = getOptionalTuple(), let bar = Foo.optionalValue {\n" + + "}\n"), + Example("if foo() { let _ = bar() }\n"), + Example("if foo() { _ = bar() }\n"), + Example("if case .some(_) = self {}"), + Example("if let point = state.find({ _ in true }) {}") ], triggeringExamples: [ - "if let ↓_ = Foo.optionalValue {\n" + - "}\n", - "if let a = Foo.optionalValue, let ↓_ = Foo.optionalValue2 {\n" + - "}\n", - "guard let a = Foo.optionalValue, let ↓_ = Foo.optionalValue2 {\n" + - "}\n", - "if let (first, second) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + - "}\n", - "if let (first, _) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + - "}\n", - "if let (_, second) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + - "}\n", - "if let ↓(_, _, _) = getOptionalTuple(), let bar = Foo.optionalValue {\n" + - "}\n", - "func foo() {\nif let ↓_ = bar {\n}\n", - "if case .some(let ↓_) = self {}" + Example("if let ↓_ = Foo.optionalValue {\n" + + "}\n"), + Example("if let a = Foo.optionalValue, let ↓_ = Foo.optionalValue2 {\n" + + "}\n"), + Example("guard let a = Foo.optionalValue, let ↓_ = Foo.optionalValue2 {\n" + + "}\n"), + Example("if let (first, second) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + + "}\n"), + Example("if let (first, _) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + + "}\n"), + Example("if let (_, second) = getOptionalTuple(), let ↓_ = Foo.optionalValue {\n" + + "}\n"), + Example("if let ↓(_, _, _) = getOptionalTuple(), let bar = Foo.optionalValue {\n" + + "}\n"), + Example("func foo() {\nif let ↓_ = bar {\n}\n"), + Example("if case .some(let ↓_) = self {}") ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentOnCallRule.swift b/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentOnCallRule.swift index 63940c0fea..87f3cd0287 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentOnCallRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentOnCallRule.swift @@ -12,64 +12,94 @@ public struct VerticalParameterAlignmentOnCallRule: ASTRule, ConfigurationProvid description: "Function parameters should be aligned vertically if they're in multiple lines in a method call.", kind: .style, nonTriggeringExamples: [ - "foo(param1: 1, param2: bar\n" + - " param3: false, param4: true)", - "foo(param1: 1, param2: bar)", - "foo(param1: 1, param2: bar\n" + - " param3: false,\n" + - " param4: true)", - "foo(\n" + - " param1: 1\n" + - ") { _ in }", - "UIView.animate(withDuration: 0.4, animations: {\n" + - " blurredImageView.alpha = 1\n" + - "}, completion: { _ in\n" + - " self.hideLoading()\n" + - "})", - "UIView.animate(withDuration: 0.4, animations: {\n" + - " blurredImageView.alpha = 1\n" + - "},\n" + - "completion: { _ in\n" + - " self.hideLoading()\n" + - "})", - "foo(param1: 1, param2: { _ in },\n" + - " param3: false, param4: true)", - "foo({ _ in\n" + - " bar()\n" + - " },\n" + - " completion: { _ in\n" + - " baz()\n" + - " }\n" + - ")", - "foo(param1: 1, param2: [\n" + - " 0,\n" + - " 1\n" + - "], param3: 0)", - """ + Example(""" + foo(param1: 1, param2: bar + param3: false, param4: true) + """), + Example(""" + foo(param1: 1, param2: bar) + """), + Example(""" + foo(param1: 1, param2: bar + param3: false, + param4: true) + """), + Example(""" + foo( + param1: 1 + ) { _ in } + """), + Example(""" + UIView.animate(withDuration: 0.4, animations: { + blurredImageView.alpha = 1 + }, completion: { _ in + self.hideLoading() + }) + """), + Example(""" + UIView.animate(withDuration: 0.4, animations: { + blurredImageView.alpha = 1 + }, + completion: { _ in + self.hideLoading() + }) + """), + Example(""" + foo(param1: 1, param2: { _ in }, + param3: false, param4: true) + """), + Example(""" + foo({ _ in + bar() + }, + completion: { _ in + baz() + } + ) + """), + Example(""" + foo(param1: 1, param2: [ + 0, + 1 + ], param3: 0) + """), + Example(""" myFunc(foo: 0, bar: baz == 0) - """ + """) ], triggeringExamples: [ - "foo(param1: 1, param2: bar\n" + - " ↓param3: false, param4: true)", - "foo(param1: 1, param2: bar\n" + - " ↓param3: false, param4: true)", - "foo(param1: 1, param2: bar\n" + - " ↓param3: false,\n" + - " ↓param4: true)", - "foo(param1: 1,\n" + - " ↓param2: { _ in })", - "foo(param1: 1,\n" + - " param2: { _ in\n" + - "}, param3: 2,\n" + - " ↓param4: 0)", - "foo(param1: 1, param2: { _ in },\n" + - " ↓param3: false, param4: true)", - """ + Example(""" + foo(param1: 1, param2: bar + ↓param3: false, param4: true) + """), + Example(""" + foo(param1: 1, param2: bar + ↓param3: false, param4: true) + """), + Example(""" + foo(param1: 1, param2: bar + ↓param3: false, + ↓param4: true) + """), + Example(""" + foo(param1: 1, + ↓param2: { _ in }) + """), + Example(""" + foo(param1: 1, + param2: { _ in + }, param3: 2, + ↓param4: 0) + """), + Example(""" + foo(param1: 1, param2: { _ in }, + ↓param3: false, param4: true) + """), + Example(""" myFunc(foo: 0, ↓bar: baz == 0) - """ + """) ] ) diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentRuleExamples.swift index d7248866cc..90221cf973 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentRuleExamples.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalParameterAlignmentRuleExamples.swift @@ -1,28 +1,51 @@ internal struct VerticalParameterAlignmentRuleExamples { - static let nonTriggeringExamples: [String] = { + static let nonTriggeringExamples: [Example] = { let commonExamples = [ - "func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " dictionary: SourceKittenDictionary) { }\n", - "func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " dictionary: SourceKittenDictionary) -> [StyleViolation]\n", - "func foo(bar: Int)\n", - "func foo(bar: Int) -> String \n", - "func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " dictionary: SourceKittenDictionary)\n" + - " -> [StyleViolation]\n", - "func validateFunction(\n" + - " _ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " dictionary: SourceKittenDictionary) -> [StyleViolation]\n", - "func validateFunction(\n" + - " _ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " dictionary: SourceKittenDictionary\n" + - ") -> [StyleViolation]\n", - "func regex(_ pattern: String,\n" + - " options: NSRegularExpression.Options = [.anchorsMatchLines,\n" + - " .dotMatchesLineSeparators]) -> NSRegularExpression\n", - "func foo(a: Void,\n b: [String: String] =\n [:]) {\n}\n", - "func foo(data: (size: CGSize,\n" + - " identifier: String)) {}" + Example(""" + func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind, + dictionary: SourceKittenDictionary) { } + """), + Example(""" + func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind, + dictionary: SourceKittenDictionary) -> [StyleViolation] + """), + Example(""" + func foo(bar: Int) + """), + Example(""" + func foo(bar: Int) -> String + """), + Example(""" + func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind, + dictionary: SourceKittenDictionary) + -> [StyleViolation] + """), + Example(""" + func validateFunction( + _ file: SwiftLintFile, kind: SwiftDeclarationKind, + dictionary: SourceKittenDictionary) -> [StyleViolation] + """), + Example(""" + func validateFunction( + _ file: SwiftLintFile, kind: SwiftDeclarationKind, + dictionary: SourceKittenDictionary + ) -> [StyleViolation] + """), + Example(""" + func regex(_ pattern: String, + options: NSRegularExpression.Options = [.anchorsMatchLines, + .dotMatchesLineSeparators]) -> NSRegularExpression + """), + Example(""" + func foo(a: Void, + b: [String: String] = + [:]) { + } + """), + Example(""" + func foo(data: (size: CGSize, + identifier: String)) {} + """) ] guard SwiftVersion.current >= .fiveDotOne else { @@ -30,22 +53,28 @@ internal struct VerticalParameterAlignmentRuleExamples { } return commonExamples + [ - """ + Example(""" func foo(data: Data, @ViewBuilder content: @escaping (Data.Element.IdentifiedValue) -> Content) {} - """ + """) ] }() - static let triggeringExamples: [String] = { + static let triggeringExamples: [Example] = { let commonExamples = [ - "func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " ↓dictionary: SourceKittenDictionary) { }\n", - "func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind,\n" + - " ↓dictionary: SourceKittenDictionary) { }\n", - "func validateFunction(_ file: SwiftLintFile,\n" + - " ↓kind: SwiftDeclarationKind,\n" + - " ↓dictionary: SourceKittenDictionary) { }\n" + Example(""" + func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind, + ↓dictionary: SourceKittenDictionary) { } + """), + Example(""" + func validateFunction(_ file: SwiftLintFile, kind: SwiftDeclarationKind, + ↓dictionary: SourceKittenDictionary) { } + """), + Example(""" + func validateFunction(_ file: SwiftLintFile, + ↓kind: SwiftDeclarationKind, + ↓dictionary: SourceKittenDictionary) { } + """) ] guard SwiftVersion.current >= .fiveDotOne else { @@ -53,10 +82,10 @@ internal struct VerticalParameterAlignmentRuleExamples { } return commonExamples + [ - """ + Example(""" func foo(data: Data, ↓@ViewBuilder content: @escaping (Data.Element.IdentifiedValue) -> Content) {} - """ + """) ] }() } diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceBetweenCasesRule.swift b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceBetweenCasesRule.swift index 0fc0519006..ffab684e17 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceBetweenCasesRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceBetweenCasesRule.swift @@ -12,8 +12,8 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { public init() {} - private static let nonTriggeringExamples = [ - """ + private static let nonTriggeringExamples: [Example] = [ + Example(""" switch x { case 0..<5: @@ -26,8 +26,8 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { print("x is invalid") } - """, - """ + """), + Example(""" switch x { case 0..<5: print("x is low") @@ -38,34 +38,35 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { default: print("x is invalid") } - """, - """ + """), + Example(""" switch x { case 0..<5: print("x is low") case 5..<10: print("x is high") default: print("x is invalid") } - """ - , + """), // Testing handling of trailing spaces: do not convert to """ style - "switch x { \n" + - "case 1: \n" + - " print(\"one\") \n" + - " \n" + - "default: \n" + - " print(\"not one\") \n" + - "} " + Example([ + "switch x { \n", + "case 1: \n", + " print(\"one\") \n", + " \n", + "default: \n", + " print(\"not one\") \n", + "} " + ].joined()) ] - private static let violatingToValidExamples: [String: String] = [ - """ + private static let violatingToValidExamples: [Example: Example] = [ + Example(""" switch x { case 0..<5: print("x is valid") ↓ default: print("x is invalid") } - """: """ + """): Example(""" switch x { case 0..<5: print("x is valid") @@ -73,15 +74,15 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { default: print("x is invalid") } - """, - """ + """), + Example(""" switch x { case .valid: print("x is valid") ↓ case .invalid: print("x is invalid") } - """: """ + """): Example(""" switch x { case .valid: print("x is valid") @@ -89,8 +90,8 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { case .invalid: print("x is invalid") } - """, - """ + """), + Example(""" switch x { case .valid: print("multiple ...") @@ -99,7 +100,7 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { print("multiple ...") print("... lines") } - """: """ + """): Example(""" switch x { case .valid: print("multiple ...") @@ -109,7 +110,7 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule { print("multiple ...") print("... lines") } - """ + """) ] private let pattern = "([^\\n{][ \\t]*\\n)([ \\t]*(?:case[^\\n]+|default):[ \\t]*\\n)" diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceClosingBracesRule.swift b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceClosingBracesRule.swift index 33923e3774..fbc4d1276e 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceClosingBracesRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceClosingBracesRule.swift @@ -12,10 +12,10 @@ public struct VerticalWhitespaceClosingBracesRule: ConfigurationProviderRule { public init() {} - private static let nonTriggeringExamples = [ - "[1, 2].map { $0 }.filter {", - "[1, 2].map { $0 }.filter { num in", - """ + private static let nonTriggeringExamples: [Example] = [ + Example("[1, 2].map { $0 }.filter {"), + Example("[1, 2].map { $0 }.filter { num in"), + Example(""" /* class X { @@ -23,17 +23,18 @@ public struct VerticalWhitespaceClosingBracesRule: ConfigurationProviderRule { } */ - """ + """) ] - private static let violatingToValidExamples: [String: String] = [ - " print(\"x is 5\")\n↓\n}": " print(\"x is 5\")\n}", - " print(\"x is 5\")\n↓\n\n}": " print(\"x is 5\")\n}", - " print(\"x is 5\")\n↓ \n}": " print(\"x is 5\")\n}", - " )\n}\n↓\n }\n}": " )\n}\n }\n}", - "[\n1,\n2,\n3\n↓\n]": "[\n1,\n2,\n3\n]", - "foo(\nx: 5,\ny:6\n↓\n)": "foo(\nx: 5,\ny:6\n)", - "class Name {\n run(5) { x in print(x) }\n↓\n}": "class Name {\n run(5) { x in print(x) }\n}" + private static let violatingToValidExamples: [Example: Example] = [ + Example(" print(\"x is 5\")\n↓\n}"): Example(" print(\"x is 5\")\n}"), + Example(" print(\"x is 5\")\n↓\n\n}"): Example(" print(\"x is 5\")\n}"), + Example(" print(\"x is 5\")\n↓ \n}"): Example(" print(\"x is 5\")\n}"), + Example(" )\n}\n↓\n }\n}"): Example(" )\n}\n }\n}"), + Example("[\n1,\n2,\n3\n↓\n]"): Example("[\n1,\n2,\n3\n]"), + Example("foo(\nx: 5,\ny:6\n↓\n)"): Example("foo(\nx: 5,\ny:6\n)"), + Example("class Name {\n run(5) { x in print(x) }\n↓\n}"): + Example("class Name {\n run(5) { x in print(x) }\n}") ] private let pattern = "((?:\\n[ \\t]*)+)(\\n[ \\t]*[)}\\]])" diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceOpeningBracesRule.swift b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceOpeningBracesRule.swift index fbb5284f08..13b986b9aa 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceOpeningBracesRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceOpeningBracesRule.swift @@ -13,10 +13,10 @@ public struct VerticalWhitespaceOpeningBracesRule: ConfigurationProviderRule { public init() {} private static let nonTriggeringExamples = [ - "[1, 2].map { $0 }.foo()", - "[1, 2].map { $0 }.filter { num in", - "// [1, 2].map { $0 }.filter { num in", - """ + Example("[1, 2].map { $0 }.foo()"), + Example("[1, 2].map { $0 }.filter { num in"), + Example("// [1, 2].map { $0 }.filter { num in"), + Example(""" /* class X { @@ -24,37 +24,38 @@ public struct VerticalWhitespaceOpeningBracesRule: ConfigurationProviderRule { } */ - """ + """) ] - private static let violatingToValidExamples: [String: String] = [ - "if x == 5 {\n↓\n print(\"x is 5\")": "if x == 5 {\n print(\"x is 5\")", - "if x == 5 {\n↓\n\n print(\"x is 5\")": "if x == 5 {\n print(\"x is 5\")", - "if x == 5 {\n↓\n print(\"x is 5\")": "if x == 5 {\n print(\"x is 5\")", - "if x == 5 {\n↓\n\tprint(\"x is 5\")": "if x == 5 {\n\tprint(\"x is 5\")", - "struct MyStruct {\n↓\n let x = 5": "struct MyStruct {\n let x = 5", - "struct MyStruct {\n↓\n let x = 5": "struct MyStruct {\n let x = 5", - "struct MyStruct {\n↓\n\tlet x = 5": "struct MyStruct {\n\tlet x = 5", - "class X {\n struct Y {\n↓\n class Z {\n": "class X {\n struct Y {\n class Z {\n", - "[\n↓\n1,\n2,\n3\n]": "[\n1,\n2,\n3\n]", - "foo(\n↓\nx: 5,\ny:6\n)": "foo(\nx: 5,\ny:6\n)", - "class Name {\n↓\n run(5) { x in print(x) }\n}": "class Name {\n run(5) { x in print(x) }\n}", - """ + private static let violatingToValidExamples: [Example: Example] = [ + Example("if x == 5 {\n↓\n print(\"x is 5\")"): Example("if x == 5 {\n print(\"x is 5\")"), + Example("if x == 5 {\n↓\n\n print(\"x is 5\")"): Example("if x == 5 {\n print(\"x is 5\")"), + Example("if x == 5 {\n↓\n print(\"x is 5\")"): Example("if x == 5 {\n print(\"x is 5\")"), + Example("if x == 5 {\n↓\n\tprint(\"x is 5\")"): Example("if x == 5 {\n\tprint(\"x is 5\")"), + Example("struct MyStruct {\n↓\n let x = 5"): Example("struct MyStruct {\n let x = 5"), + Example("struct MyStruct {\n↓\n let x = 5"): Example("struct MyStruct {\n let x = 5"), + Example("struct MyStruct {\n↓\n\tlet x = 5"): Example("struct MyStruct {\n\tlet x = 5"), + Example("class X {\n struct Y {\n↓\n class Z {\n"): Example("class X {\n struct Y {\n class Z {\n"), + Example("[\n↓\n1,\n2,\n3\n]"): Example("[\n1,\n2,\n3\n]"), + Example("foo(\n↓\nx: 5,\ny:6\n)"): Example("foo(\nx: 5,\ny:6\n)"), + Example("class Name {\n↓\n run(5) { x in print(x) }\n}"): + Example("class Name {\n run(5) { x in print(x) }\n}"), + Example(""" KingfisherManager.shared.retrieveImage(with: url, options: nil, progressBlock: nil) { image, _, _, _ in ↓ guard let img = image else { return } - """: """ + """): Example(""" KingfisherManager.shared.retrieveImage(with: url, options: nil, progressBlock: nil) { image, _, _, _ in guard let img = image else { return } - """, - """ + """), + Example(""" }) { _ in ↓ self.dismiss(animated: false, completion: { - """: """ + """): Example(""" }) { _ in self.dismiss(animated: false, completion: { - """ + """) ] private let pattern = "([{(\\[][ \\t]*(?:[^\\n{]+ in[ \\t]*$)?)((?:\\n[ \\t]*)+)(\\n)" diff --git a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceRule.swift index 6ce7db0801..ed6b5494b2 100644 --- a/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VerticalWhitespaceRule.swift @@ -14,20 +14,20 @@ public struct VerticalWhitespaceRule: CorrectableRule, ConfigurationProviderRule description: defaultDescriptionReason, kind: .style, nonTriggeringExamples: [ - "let abc = 0\n", - "let abc = 0\n\n", - "/* bcs \n\n\n\n*/", - "// bca \n\n" + Example("let abc = 0\n"), + Example("let abc = 0\n\n"), + Example("/* bcs \n\n\n\n*/"), + Example("// bca \n\n") ], triggeringExamples: [ - "let aaaa = 0\n\n\n", - "struct AAAA {}\n\n\n\n", - "class BBBB {}\n\n\n" + Example("let aaaa = 0\n\n\n"), + Example("struct AAAA {}\n\n\n\n"), + Example("class BBBB {}\n\n\n") ], corrections: [ - "let b = 0\n\n\nclass AAA {}\n": "let b = 0\n\nclass AAA {}\n", - "let c = 0\n\n\nlet num = 1\n": "let c = 0\n\nlet num = 1\n", - "// bca \n\n\n": "// bca \n\n" + Example("let b = 0\n\n\nclass AAA {}\n"): Example("let b = 0\n\nclass AAA {}\n"), + Example("let c = 0\n\n\nlet num = 1\n"): Example("let c = 0\n\nlet num = 1\n"), + Example("// bca \n\n\n"): Example("// bca \n\n") ] // End of line autocorrections are handled by Trailing Newline Rule. ) diff --git a/Source/SwiftLintFramework/Rules/Style/VoidReturnRule.swift b/Source/SwiftLintFramework/Rules/Style/VoidReturnRule.swift index 49ed61d18d..93dbef331b 100644 --- a/Source/SwiftLintFramework/Rules/Style/VoidReturnRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/VoidReturnRule.swift @@ -12,32 +12,32 @@ public struct VoidReturnRule: ConfigurationProviderRule, SubstitutionCorrectable description: "Prefer `-> Void` over `-> ()`.", kind: .style, nonTriggeringExamples: [ - "let abc: () -> Void = {}\n", - "let abc: () -> (VoidVoid) = {}\n", - "func foo(completion: () -> Void)\n", - "let foo: (ConfigurationTests) -> () throws -> Void)\n", - "let foo: (ConfigurationTests) -> () throws -> Void)\n", - "let foo: (ConfigurationTests) ->() throws -> Void)\n", - "let foo: (ConfigurationTests) -> () -> Void)\n" + Example("let abc: () -> Void = {}\n"), + Example("let abc: () -> (VoidVoid) = {}\n"), + Example("func foo(completion: () -> Void)\n"), + Example("let foo: (ConfigurationTests) -> () throws -> Void)\n"), + Example("let foo: (ConfigurationTests) -> () throws -> Void)\n"), + Example("let foo: (ConfigurationTests) ->() throws -> Void)\n"), + Example("let foo: (ConfigurationTests) -> () -> Void)\n") ], triggeringExamples: [ - "let abc: () -> ↓() = {}\n", - "let abc: () -> ↓(Void) = {}\n", - "let abc: () -> ↓( Void ) = {}\n", - "func foo(completion: () -> ↓())\n", - "func foo(completion: () -> ↓( ))\n", - "func foo(completion: () -> ↓(Void))\n", - "let foo: (ConfigurationTests) -> () throws -> ↓())\n" + Example("let abc: () -> ↓() = {}\n"), + Example("let abc: () -> ↓(Void) = {}\n"), + Example("let abc: () -> ↓( Void ) = {}\n"), + Example("func foo(completion: () -> ↓())\n"), + Example("func foo(completion: () -> ↓( ))\n"), + Example("func foo(completion: () -> ↓(Void))\n"), + Example("let foo: (ConfigurationTests) -> () throws -> ↓())\n") ], corrections: [ - "let abc: () -> ↓() = {}\n": "let abc: () -> Void = {}\n", - "let abc: () -> ↓(Void) = {}\n": "let abc: () -> Void = {}\n", - "let abc: () -> ↓( Void ) = {}\n": "let abc: () -> Void = {}\n", - "func foo(completion: () -> ↓())\n": "func foo(completion: () -> Void)\n", - "func foo(completion: () -> ↓( ))\n": "func foo(completion: () -> Void)\n", - "func foo(completion: () -> ↓(Void))\n": "func foo(completion: () -> Void)\n", - "let foo: (ConfigurationTests) -> () throws -> ↓())\n": - "let foo: (ConfigurationTests) -> () throws -> Void)\n" + Example("let abc: () -> ↓() = {}\n"): Example("let abc: () -> Void = {}\n"), + Example("let abc: () -> ↓(Void) = {}\n"): Example("let abc: () -> Void = {}\n"), + Example("let abc: () -> ↓( Void ) = {}\n"): Example("let abc: () -> Void = {}\n"), + Example("func foo(completion: () -> ↓())\n"): Example("func foo(completion: () -> Void)\n"), + Example("func foo(completion: () -> ↓( ))\n"): Example("func foo(completion: () -> Void)\n"), + Example("func foo(completion: () -> ↓(Void))\n"): Example("func foo(completion: () -> Void)\n"), + Example("let foo: (ConfigurationTests) -> () throws -> ↓())\n"): + Example("let foo: (ConfigurationTests) -> () throws -> Void)\n") ] ) diff --git a/Source/swiftlint/Commands/RulesCommand.swift b/Source/swiftlint/Commands/RulesCommand.swift index e57d874d63..1afe849a66 100644 --- a/Source/swiftlint/Commands/RulesCommand.swift +++ b/Source/swiftlint/Commands/RulesCommand.swift @@ -20,7 +20,7 @@ private func print(ruleDescription desc: RuleDescription) { } print("\nTriggering Examples (violation is marked with '↓'):") for (index, example) in desc.triggeringExamples.enumerated() { - print("\nExample #\(index + 1)\n\n\(indent(example))") + print("\nExample #\(index + 1)\n\n\(indent(example.code))") } } } diff --git a/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift b/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift index a6cbf6af09..4e487d6549 100644 --- a/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift +++ b/Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift @@ -114,10 +114,7 @@ struct LintOrAnalyzeCommand { } return violations.map { if $0.severity == .error { - return StyleViolation(ruleDescription: $0.ruleDescription, - severity: .warning, - location: $0.location, - reason: $0.reason) + return $0.with(severity: .warning) } else { return $0 } diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index f901dad462..db866badde 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -103,6 +103,9 @@ 57ED827B1CF656E3002B3513 /* JUnitReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57ED82791CF65183002B3513 /* JUnitReporter.swift */; }; 584B0D3A2112BA78002F7E25 /* SonarQubeReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584B0D392112BA78002F7E25 /* SonarQubeReporter.swift */; }; 584B0D3C2112E8FB002F7E25 /* CannedSonarQubeReporterOutput.json in Resources */ = {isa = PBXBuildFile; fileRef = 584B0D3B2112E8FB002F7E25 /* CannedSonarQubeReporterOutput.json */; }; + 5B1701BA23CEB00000CC7079 /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B1701B823CEAF8C00CC7079 /* ExampleTests.swift */; }; + 5B3BEC3A23CCCC5D00DE5BEE /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3BEC3923CCCC5D00DE5BEE /* Example.swift */; }; + 5BD08DCC23D254BF000B9CE6 /* ImplicitGetterRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD08DCA23D2549F000B9CE6 /* ImplicitGetterRuleExamples.swift */; }; 621061BF1ED57E640082D51E /* MultilineParametersRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621061BE1ED57E640082D51E /* MultilineParametersRuleExamples.swift */; }; 621C8EA420CBC7A10007DA74 /* RedundantTypeAnnotationRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6208ED4E20C297AC004E78D1 /* RedundantTypeAnnotationRule.swift */; }; 622AD800216ACE6300A002C6 /* XCTSpecificMatcherRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 622AD7FE216ACE6200A002C6 /* XCTSpecificMatcherRuleExamples.swift */; }; @@ -606,6 +609,9 @@ 57ED82791CF65183002B3513 /* JUnitReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JUnitReporter.swift; sourceTree = ""; }; 584B0D392112BA78002F7E25 /* SonarQubeReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SonarQubeReporter.swift; sourceTree = ""; }; 584B0D3B2112E8FB002F7E25 /* CannedSonarQubeReporterOutput.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CannedSonarQubeReporterOutput.json; sourceTree = ""; }; + 5B1701B823CEAF8C00CC7079 /* ExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleTests.swift; sourceTree = ""; }; + 5B3BEC3923CCCC5D00DE5BEE /* Example.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example.swift; sourceTree = ""; }; + 5BD08DCA23D2549F000B9CE6 /* ImplicitGetterRuleExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImplicitGetterRuleExamples.swift; sourceTree = ""; }; 6208ED4E20C297AC004E78D1 /* RedundantTypeAnnotationRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedundantTypeAnnotationRule.swift; sourceTree = ""; }; 621061BE1ED57E640082D51E /* MultilineParametersRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultilineParametersRuleExamples.swift; sourceTree = ""; }; 622AD7FE216ACE6200A002C6 /* XCTSpecificMatcherRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTSpecificMatcherRuleExamples.swift; sourceTree = ""; }; @@ -1238,6 +1244,7 @@ E88DEA931B099C0900A66CB0 /* IdentifierNameRule.swift */, D4130D961E16183F00242361 /* IdentifierNameRuleExamples.swift */, D43DB1071DC573DA00281215 /* ImplicitGetterRule.swift */, + 5BD08DCA23D2549F000B9CE6 /* ImplicitGetterRuleExamples.swift */, D4470D561EB69225008A1B2E /* ImplicitReturnRule.swift */, B1FD3ABE238BC6D400CE121E /* ImplicitReturnRuleExamples.swift */, CC6D28572292EF460052B682 /* IndentationWidthRule.swift */, @@ -1534,6 +1541,7 @@ CCD8B87720559C4A00B75847 /* DisableAllTests.swift */, 62AF35D71F30B183009B11EE /* DiscouragedDirectInitRuleTests.swift */, D414D6AB21D0B77F00960935 /* DiscouragedObjectLiteralRuleTests.swift */, + 5B1701B823CEAF8C00CC7079 /* ExampleTests.swift */, 125CE52E20425EFD001635E5 /* ExplicitTypeInterfaceConfigurationTests.swift */, 12E3D4DB2042729300B3E30E /* ExplicitTypeInterfaceRuleTests.swift */, 02FD8AEE1BFC18D60014BFFB /* ExtendedNSStringTests.swift */, @@ -1686,6 +1694,7 @@ 3B12C9C41C322032000B423F /* MasterRuleList.swift */, E80E018E1B92C1350078EB70 /* Region.swift */, 83D71E261B131EB5000395DE /* RuleDescription.swift */, + 5B3BEC3923CCCC5D00DE5BEE /* Example.swift */, CC26ED05204DE86E0013BBBC /* RuleIdentifier.swift */, E8BDE3FE1EDF91B6002EC12F /* RuleList.swift */, D401D9251ED85EF0005DA5D4 /* RuleKind.swift */, @@ -2109,6 +2118,7 @@ E315B83C1DFA4BC500621B44 /* DynamicInlineRule.swift in Sources */, 125AAC78203AA82D0004BCE0 /* ExplicitTypeInterfaceConfiguration.swift in Sources */, 1E18574B1EADBA51004F89F7 /* NoExtensionAccessModifierRule.swift in Sources */, + 5BD08DCC23D254BF000B9CE6 /* ImplicitGetterRuleExamples.swift in Sources */, D42D2B381E09CC0D00CD7A2E /* FirstWhereRule.swift in Sources */, 550DA0E022DB95AD00B67F03 /* EmptyCollectionLiteralRule.swift in Sources */, D4B0226F1E0C75F9007E5297 /* VerticalParameterAlignmentRule.swift in Sources */, @@ -2273,6 +2283,7 @@ 8FF4288B23C30494003B6CB0 /* RuleDocumentation.swift in Sources */, 094385041D5D4F7C009168CF /* PrivateOutletRule.swift in Sources */, 6264015520155556005B9C4A /* DiscouragedOptionalBooleanRuleExamples.swift in Sources */, + 5B3BEC3A23CCCC5D00DE5BEE /* Example.swift in Sources */, 8F8050821FFE0CBB006F5B93 /* Configuration+IndentationStyle.swift in Sources */, E88DEA6B1B0983FE00A66CB0 /* StyleViolation.swift in Sources */, 62622F6B1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift in Sources */, @@ -2356,6 +2367,7 @@ D45255C81F0932F8003C9B56 /* RuleDescription+Examples.swift in Sources */, CC8C6D2322935F5200A55D1A /* IndentationWidthRuleTests.swift in Sources */, E81ADD721ED5ED9D000CD451 /* RegionTests.swift in Sources */, + 5B1701BA23CEB00000CC7079 /* ExampleTests.swift in Sources */, D4998DE91DF194F20006E05D /* FileHeaderRuleTests.swift in Sources */, 750BBD0B214180AF007EC437 /* CollectionAlignmentRuleTests.swift in Sources */, 8B01E50220A4349100C9233E /* FunctionParameterCountRuleTests.swift in Sources */, diff --git a/Tests/SwiftLintFrameworkTests/AttributesRuleTests.swift b/Tests/SwiftLintFrameworkTests/AttributesRuleTests.swift index 6934b30b54..72fee3d1c0 100644 --- a/Tests/SwiftLintFrameworkTests/AttributesRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/AttributesRuleTests.swift @@ -10,18 +10,20 @@ class AttributesRuleTests: XCTestCase { func testAttributesWithAlwaysOnSameLine() { // Test with custom `always_on_same_line` let nonTriggeringExamples = [ - "@objc var x: String", - "@objc func foo()", - "@nonobjc\n func foo()", - "class Foo {\n" + - "@objc private var object: RLMWeakObjectHandle?\n" + - "@objc private var property: RLMProperty?\n" + - "}" + Example("@objc var x: String"), + Example("@objc func foo()"), + Example("@nonobjc\n func foo()"), + Example(""" + class Foo { + @objc private var object: RLMWeakObjectHandle? + @objc private var property: RLMProperty? + } + """) ] let triggeringExamples = [ - "@objc\n ↓var x: String", - "@objc\n ↓func foo()", - "@nonobjc ↓func foo()" + Example("@objc\n ↓var x: String"), + Example("@objc\n ↓func foo()"), + Example("@nonobjc ↓func foo()") ] let alwaysOnSameLineDescription = AttributesRule.description @@ -35,14 +37,14 @@ class AttributesRuleTests: XCTestCase { func testAttributesWithAlwaysOnLineAbove() { // Test with custom `always_on_line_above` let nonTriggeringExamples = [ - "@objc\n var x: String", - "@objc\n func foo()", - "@nonobjc\n func foo()" + Example("@objc\n var x: String"), + Example("@objc\n func foo()"), + Example("@nonobjc\n func foo()") ] let triggeringExamples = [ - "@objc ↓var x: String", - "@objc ↓func foo()", - "@nonobjc ↓func foo()" + Example("@objc ↓var x: String"), + Example("@objc ↓func foo()"), + Example("@nonobjc ↓func foo()") ] let alwaysOnNewLineDescription = AttributesRule.description @@ -55,37 +57,37 @@ class AttributesRuleTests: XCTestCase { func testAttributesWithAttributesOnLineAboveButOnOtherDeclaration() { let nonTriggeringExamples = [ - """ + Example(""" @IBDesignable open class TagListView: UIView { @IBInspectable open dynamic var textColor: UIColor = UIColor.white { didSet {} } } - """, - """ + """), + Example(""" @objc public protocol TagListViewDelegate { @objc optional func tagDidSelect(_ title: String, sender: TagListView) @objc optional func tagDidDeselect(_ title: String, sender: TagListView) } - """ + """) ] let triggeringExamples = [ - """ + Example(""" @IBDesignable open class TagListView: UIView { @IBInspectable open dynamic ↓var textColor: UIColor = UIColor.white { didSet {} } } - """, - """ + """), + Example(""" @objc public protocol TagListViewDelegate { @objc optional ↓func tagDidSelect(_ title: String, sender: TagListView) @objc optional func tagDidDeselect(_ title: String, sender: TagListView) } - """ + """) ] let alwaysOnNewLineDescription = AttributesRule.description diff --git a/Tests/SwiftLintFrameworkTests/CollectingRuleTests.swift b/Tests/SwiftLintFrameworkTests/CollectingRuleTests.swift index c1fae3d043..7dd72dc27e 100644 --- a/Tests/SwiftLintFrameworkTests/CollectingRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/CollectingRuleTests.swift @@ -16,7 +16,7 @@ class CollectingRuleTests: XCTestCase { } } - XCTAssertFalse(violations("", config: Spec.configuration!).isEmpty) + XCTAssertFalse(violations(Example(""), config: Spec.configuration!).isEmpty) } func testCollectsAllFiles() { @@ -51,7 +51,7 @@ class CollectingRuleTests: XCTestCase { } } - XCTAssertFalse(violations("", config: Spec.configuration!, requiresFileOnDisk: true).isEmpty) + XCTAssertFalse(violations(Example(""), config: Spec.configuration!, requiresFileOnDisk: true).isEmpty) } func testCorrects() { diff --git a/Tests/SwiftLintFrameworkTests/ColonRuleTests.swift b/Tests/SwiftLintFrameworkTests/ColonRuleTests.swift index 227fa5e389..1339c964a2 100644 --- a/Tests/SwiftLintFrameworkTests/ColonRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ColonRuleTests.swift @@ -13,60 +13,60 @@ class ColonRuleTests: XCTestCase { // Verify Colon rule with test values for when flexible_right_spacing // is true. let nonTriggeringExamples = ColonRule.description.nonTriggeringExamples + [ - "let abc: Void\n", - "let abc: (Void, String, Int)\n", - "let abc: ([Void], String, Int)\n", - "let abc: [([Void], String, Int)]\n", - "func abc(def: Void) {}\n", - "let abc = [Void: Void]()\n" + Example("let abc: Void\n"), + Example("let abc: (Void, String, Int)\n"), + Example("let abc: ([Void], String, Int)\n"), + Example("let abc: [([Void], String, Int)]\n"), + Example("func abc(def: Void) {}\n"), + Example("let abc = [Void: Void]()\n") ] - let triggeringExamples = [ - "let ↓abc:Void\n", - "let ↓abc :Void\n", - "let ↓abc : Void\n", - "let ↓abc : [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n", - "let ↓abc :Int=0\n", - "let ↓abc :Int = 0\n", - "let ↓abc:Int=0\n", - "let ↓abc:Int = 0\n", - "let ↓abc:Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n", - "func abc(↓def :Void) {}\n", - "func abc(↓def : Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n", - "let abc = [Void↓:Void]()\n", - "let abc = [Void↓ : Void]()\n", - "let abc = [Void↓ : Void]()\n", - "let abc = [1: [3↓ : 2], 3: 4]\n", - "let abc = [1: [3↓ : 2], 3: 4]\n" + let triggeringExamples: [Example] = [ + Example("let ↓abc:Void\n"), + Example("let ↓abc :Void\n"), + Example("let ↓abc : Void\n"), + Example("let ↓abc : [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"), + Example("let ↓abc :Int=0\n"), + Example("let ↓abc :Int = 0\n"), + Example("let ↓abc:Int=0\n"), + Example("let ↓abc:Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"), + Example("func abc(↓def :Void) {}\n"), + Example("func abc(↓def : Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n"), + Example("let abc = [Void↓:Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n") ] - let corrections = [ - "let ↓abc:Void\n": "let abc: Void\n", - "let ↓abc :Void\n": "let abc: Void\n", - "let ↓abc : Void\n": "let abc: Void\n", - "let ↓abc : [Void: Void]\n": "let abc: [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n": "let abc: (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n": "let abc: ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n": "let abc: [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n": "let abc: String=\"def\"\n", - "let ↓abc :Int=0\n": "let abc: Int=0\n", - "let ↓abc :Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Int=0\n": "let abc: Int=0\n", - "let ↓abc:Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Enum=Enum.Value\n": "let abc: Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def :Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def : Void) {}\n": "func abc(def: Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n": "func abc(def: Void, ghi: Void) {}\n", - "let abc = [Void↓:Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [Void↓ : Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [Void↓ : Void]()\n": "let abc = [Void: Void]()\n", - "let abc = [1: [3↓ : 2], 3: 4]\n": "let abc = [1: [3: 2], 3: 4]\n", - "let abc = [1: [3↓ : 2], 3: 4]\n": "let abc = [1: [3: 2], 3: 4]\n" + let corrections: [Example: Example] = [ + Example("let ↓abc:Void\n"): Example("let abc: Void\n"), + Example("let ↓abc :Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : [Void: Void]\n"): Example("let abc: [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"): Example("let abc: (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"): Example("let abc: ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"): Example("let abc: [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"): Example("let abc: String=\"def\"\n"), + Example("let ↓abc :Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc :Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc:Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"): Example("let abc: Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def :Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def : Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n"): Example("func abc(def: Void, ghi: Void) {}\n"), + Example("let abc = [Void↓:Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void↓ : Void]()\n"): Example("let abc = [Void: Void]()\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n"): Example("let abc = [1: [3: 2], 3: 4]\n"), + Example("let abc = [1: [3↓ : 2], 3: 4]\n"): Example("let abc = [1: [3: 2], 3: 4]\n") ] let description = ColonRule.description.with(triggeringExamples: triggeringExamples) .with(nonTriggeringExamples: nonTriggeringExamples) @@ -78,60 +78,60 @@ class ColonRuleTests: XCTestCase { // swiftlint:disable:next function_body_length func testColonWithoutApplyToDictionaries() { let nonTriggeringExamples = ColonRule.description.nonTriggeringExamples + [ - "let abc = [Void:Void]()\n", - "let abc = [Void : Void]()\n", - "let abc = [Void: Void]()\n", - "let abc = [Void : Void]()\n", - "let abc = [1: [3 : 2], 3: 4]\n", - "let abc = [1: [3 : 2], 3: 4]\n" + Example("let abc = [Void:Void]()\n"), + Example("let abc = [Void : Void]()\n"), + Example("let abc = [Void: Void]()\n"), + Example("let abc = [Void : Void]()\n"), + Example("let abc = [1: [3 : 2], 3: 4]\n"), + Example("let abc = [1: [3 : 2], 3: 4]\n") ] - let triggeringExamples = [ - "let ↓abc:Void\n", - "let ↓abc: Void\n", - "let ↓abc :Void\n", - "let ↓abc : Void\n", - "let ↓abc : [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n", - "let ↓abc: (Void, String, Int)\n", - "let ↓abc: ([Void], String, Int)\n", - "let ↓abc: [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n", - "let ↓abc :Int=0\n", - "let ↓abc :Int = 0\n", - "let ↓abc:Int=0\n", - "let ↓abc:Int = 0\n", - "let ↓abc:Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n", - "func abc(↓def: Void) {}\n", - "func abc(↓def :Void) {}\n", - "func abc(↓def : Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n" + let triggeringExamples: [Example] = [ + Example("let ↓abc:Void\n"), + Example("let ↓abc: Void\n"), + Example("let ↓abc :Void\n"), + Example("let ↓abc : Void\n"), + Example("let ↓abc : [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"), + Example("let ↓abc: (Void, String, Int)\n"), + Example("let ↓abc: ([Void], String, Int)\n"), + Example("let ↓abc: [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"), + Example("let ↓abc :Int=0\n"), + Example("let ↓abc :Int = 0\n"), + Example("let ↓abc:Int=0\n"), + Example("let ↓abc:Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"), + Example("func abc(↓def: Void) {}\n"), + Example("func abc(↓def :Void) {}\n"), + Example("func abc(↓def : Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n") ] - let corrections = [ - "let ↓abc:Void\n": "let abc: Void\n", - "let ↓abc: Void\n": "let abc: Void\n", - "let ↓abc :Void\n": "let abc: Void\n", - "let ↓abc : Void\n": "let abc: Void\n", - "let ↓abc : [Void: Void]\n": "let abc: [Void: Void]\n", - "let ↓abc : (Void, String, Int)\n": "let abc: (Void, String, Int)\n", - "let ↓abc : ([Void], String, Int)\n": "let abc: ([Void], String, Int)\n", - "let ↓abc : [([Void], String, Int)]\n": "let abc: [([Void], String, Int)]\n", - "let ↓abc: (Void, String, Int)\n": "let abc: (Void, String, Int)\n", - "let ↓abc: ([Void], String, Int)\n": "let abc: ([Void], String, Int)\n", - "let ↓abc: [([Void], String, Int)]\n": "let abc: [([Void], String, Int)]\n", - "let ↓abc :String=\"def\"\n": "let abc: String=\"def\"\n", - "let ↓abc :Int=0\n": "let abc: Int=0\n", - "let ↓abc :Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Int=0\n": "let abc: Int=0\n", - "let ↓abc:Int = 0\n": "let abc: Int = 0\n", - "let ↓abc:Enum=Enum.Value\n": "let abc: Enum=Enum.Value\n", - "func abc(↓def:Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def: Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def :Void) {}\n": "func abc(def: Void) {}\n", - "func abc(↓def : Void) {}\n": "func abc(def: Void) {}\n", - "func abc(def: Void, ↓ghi :Void) {}\n": "func abc(def: Void, ghi: Void) {}\n" + let corrections: [Example: Example] = [ + Example("let ↓abc:Void\n"): Example("let abc: Void\n"), + Example("let ↓abc: Void\n"): Example("let abc: Void\n"), + Example("let ↓abc :Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : Void\n"): Example("let abc: Void\n"), + Example("let ↓abc : [Void: Void]\n"): Example("let abc: [Void: Void]\n"), + Example("let ↓abc : (Void, String, Int)\n"): Example("let abc: (Void, String, Int)\n"), + Example("let ↓abc : ([Void], String, Int)\n"): Example("let abc: ([Void], String, Int)\n"), + Example("let ↓abc : [([Void], String, Int)]\n"): Example("let abc: [([Void], String, Int)]\n"), + Example("let ↓abc: (Void, String, Int)\n"): Example("let abc: (Void, String, Int)\n"), + Example("let ↓abc: ([Void], String, Int)\n"): Example("let abc: ([Void], String, Int)\n"), + Example("let ↓abc: [([Void], String, Int)]\n"): Example("let abc: [([Void], String, Int)]\n"), + Example("let ↓abc :String=\"def\"\n"): Example("let abc: String=\"def\"\n"), + Example("let ↓abc :Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc :Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Int=0\n"): Example("let abc: Int=0\n"), + Example("let ↓abc:Int = 0\n"): Example("let abc: Int = 0\n"), + Example("let ↓abc:Enum=Enum.Value\n"): Example("let abc: Enum=Enum.Value\n"), + Example("func abc(↓def:Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def: Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def :Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(↓def : Void) {}\n"): Example("func abc(def: Void) {}\n"), + Example("func abc(def: Void, ↓ghi :Void) {}\n"): Example("func abc(def: Void, ghi: Void) {}\n") ] let description = ColonRule.description.with(triggeringExamples: triggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/CommandTests.swift b/Tests/SwiftLintFrameworkTests/CommandTests.swift index 20dc156b27..af01657a55 100644 --- a/Tests/SwiftLintFrameworkTests/CommandTests.swift +++ b/Tests/SwiftLintFrameworkTests/CommandTests.swift @@ -237,19 +237,19 @@ class CommandTests: XCTestCase { func testSuperfluousDisableCommands() { XCTAssertEqual( - violations("// swiftlint:disable nesting\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable nesting\nprint(123)\n"))[0].ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("// swiftlint:disable:next nesting\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable:next nesting\nprint(123)\n"))[0].ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123) // swiftlint:disable:this nesting\n")[0].ruleDescription.identifier, + violations(Example("print(123) // swiftlint:disable:this nesting\n"))[0].ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting\n")[0].ruleDescription.identifier, + violations(Example("print(123)\n// swiftlint:disable:previous nesting\n"))[0].ruleIdentifier, "superfluous_disable_command" ) } @@ -257,22 +257,22 @@ class CommandTests: XCTestCase { func testDisableAllOverridesSuperfluousDisableCommand() { XCTAssert( violations( - "//swiftlint:disable all\n// swiftlint:disable nesting\nprint(123)\n" + Example("//swiftlint:disable all\n// swiftlint:disable nesting\nprint(123)\n") ).isEmpty ) XCTAssert( violations( - "//swiftlint:disable all\n// swiftlint:disable:next nesting\nprint(123)\n" + Example("//swiftlint:disable all\n// swiftlint:disable:next nesting\nprint(123)\n") ).isEmpty ) XCTAssert( violations( - "//swiftlint:disable all\n// swiftlint:disable:this nesting\nprint(123)\n" + Example("//swiftlint:disable all\n// swiftlint:disable:this nesting\nprint(123)\n") ).isEmpty ) XCTAssert( violations( - "//swiftlint:disable all\n// swiftlint:disable:previous nesting\nprint(123)\n" + Example("//swiftlint:disable all\n// swiftlint:disable:previous nesting\nprint(123)\n") ).isEmpty ) } @@ -280,85 +280,93 @@ class CommandTests: XCTestCase { func testSuperfluousDisableCommandsIgnoreDelimiter() { let longComment = "Comment with a large number of words that shouldn't register as superfluous" XCTAssertEqual( - violations("// swiftlint:disable nesting - \(longComment)\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable nesting - \(longComment)\nprint(123)\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("// swiftlint:disable:next nesting - Comment\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable:next nesting - Comment\nprint(123)\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123) // swiftlint:disable:this nesting - Comment\n")[0].ruleDescription.identifier, + violations(Example("print(123) // swiftlint:disable:this nesting - Comment\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting - Comment\n")[0].ruleDescription.identifier, + violations(Example("print(123)\n// swiftlint:disable:previous nesting - Comment\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) } func testInvalidDisableCommands() { XCTAssertEqual( - violations("// swiftlint:disable nesting_foo\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable nesting_foo\nprint(123)\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("// swiftlint:disable:next nesting_foo\nprint(123)\n")[0].ruleDescription.identifier, + violations(Example("// swiftlint:disable:next nesting_foo\nprint(123)\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123) // swiftlint:disable:this nesting_foo\n")[0].ruleDescription.identifier, + violations(Example("print(123) // swiftlint:disable:this nesting_foo\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting_foo\n")[0].ruleDescription.identifier, + violations(Example("print(123)\n// swiftlint:disable:previous nesting_foo\n"))[0] + .ruleIdentifier, "superfluous_disable_command" ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting_foo \n").count, + violations(Example("print(123)\n// swiftlint:disable:previous nesting_foo \n")).count, 1 ) - let multipleViolations = violations("// swiftlint:disable nesting this is a comment\n") + let multipleViolations = violations(Example("// swiftlint:disable nesting this is a comment\n")) XCTAssertEqual(multipleViolations.count, 5) - XCTAssertTrue(multipleViolations.allSatisfy { $0.ruleDescription.identifier == "superfluous_disable_command" }) + XCTAssertTrue(multipleViolations.allSatisfy { $0.ruleIdentifier == "superfluous_disable_command" }) - let onlyNonExistentRulesViolations = violations("// swiftlint:disable this is a comment\n") + let onlyNonExistentRulesViolations = violations(Example("// swiftlint:disable this is a comment\n")) XCTAssertEqual(onlyNonExistentRulesViolations.count, 4) XCTAssertTrue(onlyNonExistentRulesViolations.allSatisfy { - $0.ruleDescription.identifier == "superfluous_disable_command" + $0.ruleIdentifier == "superfluous_disable_command" }) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting_foo\n")[0].reason, + violations(Example("print(123)\n// swiftlint:disable:previous nesting_foo\n"))[0].reason, "'nesting_foo' is not a valid SwiftLint rule. Please remove it from the disable command." ) - XCTAssertEqual(violations("/* swiftlint:disable nesting */\n").count, 1) + XCTAssertEqual(violations(Example("/* swiftlint:disable nesting */\n")).count, 1) } func testSuperfluousDisableCommandsDisabled() { XCTAssertEqual( - violations("// swiftlint:disable superfluous_disable_command nesting\nprint(123)\n"), + violations(Example("// swiftlint:disable superfluous_disable_command nesting\nprint(123)\n")), [] ) XCTAssertEqual( - violations("// swiftlint:disable superfluous_disable_command\n" + + violations(Example("// swiftlint:disable superfluous_disable_command\n" + "// swiftlint:disable nesting\n" + - "print(123)\n"), + "print(123)\n")), [] ) XCTAssertEqual( - violations("// swiftlint:disable:next superfluous_disable_command nesting\nprint(123)\n"), + violations(Example("// swiftlint:disable:next superfluous_disable_command nesting\nprint(123)\n")), [] ) XCTAssertEqual( - violations("print(123) // swiftlint:disable:this superfluous_disable_command nesting\n"), + violations(Example("print(123) // swiftlint:disable:this superfluous_disable_command nesting\n")), [] ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous superfluous_disable_command nesting\n"), + violations(Example("print(123)\n// swiftlint:disable:previous superfluous_disable_command nesting\n")), [] ) } @@ -371,19 +379,19 @@ class CommandTests: XCTestCase { } XCTAssertEqual( - violations("// swiftlint:disable nesting\nprint(123)\n", config: configuration), + violations(Example("// swiftlint:disable nesting\nprint(123)\n"), config: configuration), [] ) XCTAssertEqual( - violations("// swiftlint:disable:next nesting\nprint(123)\n", config: configuration), + violations(Example("// swiftlint:disable:next nesting\nprint(123)\n"), config: configuration), [] ) XCTAssertEqual( - violations("print(123) // swiftlint:disable:this nesting\n", config: configuration), + violations(Example("print(123) // swiftlint:disable:this nesting\n"), config: configuration), [] ) XCTAssertEqual( - violations("print(123)\n// swiftlint:disable:previous nesting\n", config: configuration), + violations(Example("print(123)\n// swiftlint:disable:previous nesting\n"), config: configuration), [] ) } diff --git a/Tests/SwiftLintFrameworkTests/CompilerProtocolInitRuleTests.swift b/Tests/SwiftLintFrameworkTests/CompilerProtocolInitRuleTests.swift index b03fb35bdd..f9f5227f68 100644 --- a/Tests/SwiftLintFrameworkTests/CompilerProtocolInitRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/CompilerProtocolInitRuleTests.swift @@ -10,9 +10,9 @@ class CompilerProtocolInitRuleTests: XCTestCase { func testViolationMessageForExpressibleByIntegerLiteral() throws { let config = try XCTUnwrap(makeConfig(nil, ruleID)) - let allViolations = violations("let a = NSNumber(integerLiteral: 1)", config: config) + let allViolations = violations(Example("let a = NSNumber(integerLiteral: 1)"), config: config) - let compilerProtocolInitViolation = allViolations.first { $0.ruleDescription.identifier == ruleID } + let compilerProtocolInitViolation = allViolations.first { $0.ruleIdentifier == ruleID } let violation = try XCTUnwrap( compilerProtocolInitViolation, "A compiler protocol init violation should have been triggered!" diff --git a/Tests/SwiftLintFrameworkTests/ConditionalReturnsOnNewlineRuleTests.swift b/Tests/SwiftLintFrameworkTests/ConditionalReturnsOnNewlineRuleTests.swift index f61952605a..46566db232 100644 --- a/Tests/SwiftLintFrameworkTests/ConditionalReturnsOnNewlineRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ConditionalReturnsOnNewlineRuleTests.swift @@ -10,20 +10,20 @@ class ConditionalReturnsOnNewlineRuleTests: XCTestCase { func testConditionalReturnsOnNewlineWithIfOnly() { // Test with `if_only` set to true let nonTriggeringExamples = [ - "guard true else {\n return true\n}", - "guard true,\n let x = true else {\n return true\n}", - "if true else {\n return true\n}", - "if true,\n let x = true else {\n return true\n}", - "if textField.returnKeyType == .Next {", - "if true { // return }", - "/*if true { */ return }", - "guard true else { return }" + Example("guard true else {\n return true\n}"), + Example("guard true,\n let x = true else {\n return true\n}"), + Example("if true else {\n return true\n}"), + Example("if true,\n let x = true else {\n return true\n}"), + Example("if textField.returnKeyType == .Next {"), + Example("if true { // return }"), + Example("/*if true { */ return }"), + Example("guard true else { return }") ] let triggeringExamples = [ - "↓if true { return }", - "↓if true { break } else { return }", - "↓if true { break } else { return }", - "↓if true { return \"YES\" } else { return \"NO\" }" + Example("↓if true { return }"), + Example("↓if true { break } else { return }"), + Example("↓if true { break } else { return }"), + Example("↓if true { return \"YES\" } else { return \"NO\" }") ] let description = ConditionalReturnsOnNewlineRule.description diff --git a/Tests/SwiftLintFrameworkTests/ContainsOverFirstNotNilRuleTests.swift b/Tests/SwiftLintFrameworkTests/ContainsOverFirstNotNilRuleTests.swift index 50e7f03959..3e611b3d0b 100644 --- a/Tests/SwiftLintFrameworkTests/ContainsOverFirstNotNilRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ContainsOverFirstNotNilRuleTests.swift @@ -9,16 +9,16 @@ class ContainsOverFirstNotNilRuleTests: XCTestCase { // MARK: - Reasons func testFirstReason() { - let string = "↓myList.first { $0 % 2 == 0 } != nil" - let violations = self.violations(string) + let example = Example("↓myList.first { $0 % 2 == 0 } != nil") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer `contains` over `first(where:) != nil`") } func testFirstIndexReason() { - let string = "↓myList.firstIndex { $0 % 2 == 0 } != nil" - let violations = self.violations(string) + let example = Example("↓myList.firstIndex { $0 % 2 == 0 } != nil") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer `contains` over `firstIndex(where:) != nil`") @@ -26,11 +26,11 @@ class ContainsOverFirstNotNilRuleTests: XCTestCase { // MARK: - Private - private func violations(_ string: String, config: Any? = nil) -> [StyleViolation] { + private func violations(_ example: Example, config: Any? = nil) -> [StyleViolation] { guard let config = makeConfig(config, ContainsOverFirstNotNilRule.description.identifier) else { return [] } - return SwiftLintFrameworkTests.violations(string, config: config) + return SwiftLintFrameworkTests.violations(example, config: config) } } diff --git a/Tests/SwiftLintFrameworkTests/CyclomaticComplexityRuleTests.swift b/Tests/SwiftLintFrameworkTests/CyclomaticComplexityRuleTests.swift index 5fe9d5e2e4..fa2ff2ae82 100644 --- a/Tests/SwiftLintFrameworkTests/CyclomaticComplexityRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/CyclomaticComplexityRuleTests.swift @@ -2,7 +2,7 @@ import SwiftLintFramework import XCTest class CyclomaticComplexityRuleTests: XCTestCase { - private lazy var complexSwitchExample: String = { + private lazy var complexSwitchExample: Example = { var example = "func switcheroo() {\n" example += " switch foo {\n" for index in (0...30) { @@ -10,10 +10,10 @@ class CyclomaticComplexityRuleTests: XCTestCase { } example += " }\n" example += "}\n" - return example + return Example(example) }() - private lazy var complexIfExample: String = { + private lazy var complexIfExample: Example = { let nest = 22 var example = "func nestThoseIfs() {\n" for index in (0...nest) { @@ -27,7 +27,7 @@ class CyclomaticComplexityRuleTests: XCTestCase { example += indent + "}\n" } example += "}\n" - return example + return Example(example) }() func testCyclomaticComplexity() { diff --git a/Tests/SwiftLintFrameworkTests/DeploymentTargetRuleTests.swift b/Tests/SwiftLintFrameworkTests/DeploymentTargetRuleTests.swift index 3ff0af26ae..7a8daa55b1 100644 --- a/Tests/SwiftLintFrameworkTests/DeploymentTargetRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/DeploymentTargetRuleTests.swift @@ -9,8 +9,8 @@ class DeploymentTargetRuleTests: XCTestCase { // MARK: - Reasons func testMacOSAttributeReason() { - let string = "@availability(macOS 10.11, *)\nclass A {}" - let violations = self.violations(string, config: ["macOS_deployment_target": "10.14.0"]) + let example = Example("@availability(macOS 10.11, *)\nclass A {}") + let violations = self.violations(example, config: ["macOS_deployment_target": "10.14.0"]) let expectedMessage = "Availability attribute is using a version (10.11) that is satisfied by " + "the deployment target (10.14) for platform macOS." @@ -19,8 +19,8 @@ class DeploymentTargetRuleTests: XCTestCase { } func testWatchOSConditionReason() { - let string = "if #available(watchOS 4, *) {}" - let violations = self.violations(string, config: ["watchOS_deployment_target": "5.0.1"]) + let example = Example("if #available(watchOS 4, *) {}") + let violations = self.violations(example, config: ["watchOS_deployment_target": "5.0.1"]) let expectedMessage = "Availability condition is using a version (4) that is satisfied by " + "the deployment target (5.0.1) for platform watchOS." @@ -28,11 +28,11 @@ class DeploymentTargetRuleTests: XCTestCase { XCTAssertEqual(violations.first?.reason, expectedMessage) } - private func violations(_ string: String, config: Any?) -> [StyleViolation] { + private func violations(_ example: Example, config: Any?) -> [StyleViolation] { guard let config = makeConfig(config, DeploymentTargetRule.description.identifier) else { return [] } - return SwiftLintFrameworkTests.violations(string, config: config) + return SwiftLintFrameworkTests.violations(example, config: config) } } diff --git a/Tests/SwiftLintFrameworkTests/DisableAllTests.swift b/Tests/SwiftLintFrameworkTests/DisableAllTests.swift index fc04b79ec7..16e4470bb3 100644 --- a/Tests/SwiftLintFrameworkTests/DisableAllTests.swift +++ b/Tests/SwiftLintFrameworkTests/DisableAllTests.swift @@ -1,19 +1,24 @@ -import Foundation +import SwiftLintFramework import XCTest class DisableAllTests: XCTestCase { /// Example violations. Could be replaced with other single violations. private let violatingPhrases = [ - "let r = 0\n", // Violates identifier_name - "let myString:String = \"\"\n", // Violates colon_whitespace - "// TODO: Some todo\n" // Violates todo + Example("let r = 0"), // Violates identifier_name + Example(#"let myString:String = """#), // Violates colon_whitespace + Example("// TODO: Some todo") // Violates todo ] // MARK: Violating Phrase /// Tests whether example violating phrases trigger when not applying disable rule func testViolatingPhrase() { for violatingPhrase in violatingPhrases { - XCTAssertEqual(violations(violatingPhrase).count, 1) + XCTAssertEqual( + violations(violatingPhrase.with(code: violatingPhrase.code + "\n")).count, + 1, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } @@ -21,20 +26,31 @@ class DisableAllTests: XCTestCase { /// Tests whether swiftlint:disable all protects properly func testDisableAll() { for violatingPhrase in violatingPhrases { - let protectedPhrase = "// swiftlint:disable all\n" + violatingPhrase - XCTAssertEqual(violations(protectedPhrase).count, 0) + let protectedPhrase = violatingPhrase.with(code: "// swiftlint:disable all\n" + violatingPhrase.code) + XCTAssertEqual( + violations(protectedPhrase).count, + 0, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } /// Tests whether swiftlint:enable all unprotects properly func testEnableAll() { for violatingPhrase in violatingPhrases { - let unprotectedPhrase = - "// swiftlint:disable all\n" + - violatingPhrase + - "// swiftlint:enable all\n" + - violatingPhrase - XCTAssertEqual(violations(unprotectedPhrase).count, 1) + let unprotectedPhrase = violatingPhrase.with(code: """ + // swiftlint:disable all + \(violatingPhrase.code) + // swiftlint:enable all + \(violatingPhrase.code)\n + """) + XCTAssertEqual( + violations(unprotectedPhrase).count, + 1, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } @@ -42,20 +58,35 @@ class DisableAllTests: XCTestCase { /// Tests whether swiftlint:disable:previous all protects properly func testDisableAllPrevious() { for violatingPhrase in violatingPhrases { - let protectedPhrase = violatingPhrase + "// swiftlint:disable:previous all\n" - XCTAssertEqual(violations(protectedPhrase).count, 0) + let protectedPhrase = violatingPhrase + .with(code: """ + \(violatingPhrase.code) + // swiftlint:disable:previous all\n + """) + XCTAssertEqual( + violations(protectedPhrase).count, + 0, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } /// Tests whether swiftlint:enable:previous all unprotects properly func testEnableAllPrevious() { for violatingPhrase in violatingPhrases { - let unprotectedPhrase = - "// swiftlint:disable all\n" + - violatingPhrase + - violatingPhrase + - "// swiftlint:enable:previous all\n" - XCTAssertEqual(violations(unprotectedPhrase).count, 1) + let unprotectedPhrase = violatingPhrase.with(code: """ + // swiftlint:disable all + \(violatingPhrase.code) + \(violatingPhrase.code) + // swiftlint:enable:previous all\n + """) + XCTAssertEqual( + violations(unprotectedPhrase).count, + 1, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } @@ -63,20 +94,31 @@ class DisableAllTests: XCTestCase { /// Tests whether swiftlint:disable:next all protects properly func testDisableAllNext() { for violatingPhrase in violatingPhrases { - let protectedPhrase = "// swiftlint:disable:next all\n" + violatingPhrase - XCTAssertEqual(violations(protectedPhrase).count, 0) + let protectedPhrase = violatingPhrase.with(code: "// swiftlint:disable:next all\n" + violatingPhrase.code) + XCTAssertEqual( + violations(protectedPhrase).count, + 0, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } /// Tests whether swiftlint:enable:next all unprotects properly func testEnableAllNext() { for violatingPhrase in violatingPhrases { - let unprotectedPhrase = - "// swiftlint:disable all\n" + - violatingPhrase + - "// swiftlint:enable:next all\n" + - violatingPhrase - XCTAssertEqual(violations(unprotectedPhrase).count, 1) + let unprotectedPhrase = violatingPhrase.with(code: """ + // swiftlint:disable all + \(violatingPhrase.code) + // swiftlint:enable:next all + \(violatingPhrase.code)\n + """) + XCTAssertEqual( + violations(unprotectedPhrase).count, + 1, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } @@ -84,22 +126,32 @@ class DisableAllTests: XCTestCase { /// Tests whether swiftlint:disable:this all protects properly func testDisableAllThis() { for violatingPhrase in violatingPhrases { - let rawViolatingPhrase = violatingPhrase.replacingOccurrences(of: "\n", with: "") - let protectedPhrase = rawViolatingPhrase + "// swiftlint:disable:this all\n" - XCTAssertEqual(violations(protectedPhrase).count, 0) + let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "") + let protectedPhrase = violatingPhrase.with(code: rawViolatingPhrase + "// swiftlint:disable:this all\n") + XCTAssertEqual( + violations(protectedPhrase).count, + 0, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } /// Tests whether swiftlint:enable:next all unprotects properly func testEnableAllThis() { for violatingPhrase in violatingPhrases { - let rawViolatingPhrase = violatingPhrase.replacingOccurrences(of: "\n", with: "") - let unprotectedPhrase = - "// swiftlint:disable all\n" + - violatingPhrase + - rawViolatingPhrase + - "// swiftlint:enable:this all\n" - XCTAssertEqual(violations(unprotectedPhrase).count, 1) + let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "") + let unprotectedPhrase = violatingPhrase.with(code: """ + // swiftlint:disable all + \(violatingPhrase.code) + \(rawViolatingPhrase)// swiftlint:enable:this all\n" + """) + XCTAssertEqual( + violations(unprotectedPhrase).count, + 1, + #function, + file: violatingPhrase.file, + line: violatingPhrase.line) } } } diff --git a/Tests/SwiftLintFrameworkTests/DiscouragedDirectInitRuleTests.swift b/Tests/SwiftLintFrameworkTests/DiscouragedDirectInitRuleTests.swift index 3acca1bf7d..a80d5a0a90 100644 --- a/Tests/SwiftLintFrameworkTests/DiscouragedDirectInitRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/DiscouragedDirectInitRuleTests.swift @@ -14,13 +14,13 @@ class DiscouragedDirectInitRuleTests: XCTestCase { func testDiscouragedDirectInitWithNewIncludedTypes() { let triggeringExamples = [ - "let foo = ↓Foo()", - "let bar = ↓Bar()" + Example("let foo = ↓Foo()"), + Example("let bar = ↓Bar()") ] let nonTriggeringExamples = [ - "let foo = Foo(arg: toto)", - "let bar = Bar(arg: \"toto\")" + Example("let foo = Foo(arg: toto)"), + Example("let bar = Bar(arg: \"toto\")") ] let description = baseDescription @@ -32,11 +32,11 @@ class DiscouragedDirectInitRuleTests: XCTestCase { func testDiscouragedDirectInitWithReplacedTypes() { let triggeringExamples = [ - "let bundle = ↓Bundle()" + Example("let bundle = ↓Bundle()") ] let nonTriggeringExamples = [ - "let device = UIDevice()" + Example("let device = UIDevice()") ] let description = baseDescription diff --git a/Tests/SwiftLintFrameworkTests/DiscouragedObjectLiteralRuleTests.swift b/Tests/SwiftLintFrameworkTests/DiscouragedObjectLiteralRuleTests.swift index 8137633546..1af00c7615 100644 --- a/Tests/SwiftLintFrameworkTests/DiscouragedObjectLiteralRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/DiscouragedObjectLiteralRuleTests.swift @@ -9,10 +9,10 @@ class DiscouragedObjectLiteralRuleTests: XCTestCase { func testWithImageLiteral() { let baseDescription = DiscouragedObjectLiteralRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)" + Example("let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)") ] let triggeringExamples = [ - "let image = ↓#imageLiteral(resourceName: \"image.jpg\")" + Example("let image = ↓#imageLiteral(resourceName: \"image.jpg\")") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples, @@ -24,10 +24,10 @@ class DiscouragedObjectLiteralRuleTests: XCTestCase { func testWithColorLiteral() { let baseDescription = DiscouragedObjectLiteralRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "let image = #imageLiteral(resourceName: \"image.jpg\")" + Example("let image = #imageLiteral(resourceName: \"image.jpg\")") ] let triggeringExamples = [ - "let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)" + Example("let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples, diff --git a/Tests/SwiftLintFrameworkTests/ExampleTests.swift b/Tests/SwiftLintFrameworkTests/ExampleTests.swift new file mode 100644 index 0000000000..4de3862287 --- /dev/null +++ b/Tests/SwiftLintFrameworkTests/ExampleTests.swift @@ -0,0 +1,49 @@ +import SwiftLintFramework +import XCTest + +class ExampleTests: XCTestCase { + func testEquatableDoesNotLookAtFile() { + let first = Example("foo", file: "a", line: 1) + let second = Example("foo", file: "b", line: 1) + XCTAssertEqual(first, second) + } + + func testEquatableDoesNotLookAtLine() { + let first = Example("foo", file: "a", line: 1) + let second = Example("foo", file: "a", line: 2) + XCTAssertEqual(first, second) + } + + func testEquatableLooksAtCode() { + let first = Example("a", file: "a", line: 1) + let second = Example("a", file: "x", line: 2) + let third = Example("c", file: "y", line: 2) + XCTAssertEqual(first, second) + XCTAssertNotEqual(first, third) + } + + func testRemovingViolationMarkers() { + let example = Example("↓T↓E↓S↓T") + XCTAssertEqual(example.removingViolationMarkers(), Example("TEST")) + } + + func testComparable() { + XCTAssertLessThan(Example("a"), Example("b")) + } + + func testWithCode() { + let original = Example("original code") + XCTAssertNotNil(original.file) + XCTAssertNotNil(original.line) + + let new = original.with(code: "new code") + XCTAssertEqual(new.code, "new code") + XCTAssertNotNil(new.file) + XCTAssertNotNil(new.line) + + // When modifying the code, it's important that the file and line + // numbers remain intact + XCTAssertEqual(new.file.description, original.file.description) + XCTAssertEqual(new.line, original.line) + } +} diff --git a/Tests/SwiftLintFrameworkTests/ExpiringTodoRuleTests.swift b/Tests/SwiftLintFrameworkTests/ExpiringTodoRuleTests.swift index 55ac828fc8..781235257d 100644 --- a/Tests/SwiftLintFrameworkTests/ExpiringTodoRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ExpiringTodoRuleTests.swift @@ -15,29 +15,29 @@ class ExpiringTodoRuleTests: XCTestCase { } func testExpiredTodo() { - let string = "fatalError() // TODO: [\(dateString(for: .expired))] Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: [\(dateString(for: .expired))] Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved.") } func testExpiredFixMe() { - let string = "fatalError() // FIXME: [\(dateString(for: .expired))] Implement" - let violations = self.violations(string) + let example = Example("fatalError() // FIXME: [\(dateString(for: .expired))] Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved.") } func testApproachingExpiryTodo() { - let string = "fatalError() // TODO: [\(dateString(for: .approachingExpiry))] Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: [\(dateString(for: .approachingExpiry))] Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME is approaching its expiry and should be resolved soon.") } func testNonExpiredTodo() { - let string = "fatalError() // TODO: [\(dateString(for: nil))] Implement" - XCTAssertEqual(violations(string).count, 0) + let example = Example("fatalError() // TODO: [\(dateString(for: nil))] Implement") + XCTAssertEqual(violations(example).count, 0) } func testExpiredCustomDelimiters() { @@ -46,8 +46,8 @@ class ExpiringTodoRuleTests: XCTestCase { ) config = makeConfiguration(with: ruleConfig) - let string = "fatalError() // TODO: <\(dateString(for: .expired))> Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: <\(dateString(for: .expired))> Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved.") } @@ -59,8 +59,8 @@ class ExpiringTodoRuleTests: XCTestCase { ) config = makeConfiguration(with: ruleConfig) - let string = "fatalError() // TODO: [\(dateString(for: .expired))] Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: [\(dateString(for: .expired))] Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved.") } @@ -71,14 +71,14 @@ class ExpiringTodoRuleTests: XCTestCase { ) config = makeConfiguration(with: ruleConfig) - let string = "fatalError() // TODO: [\(dateString(for: .expired))] Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: [\(dateString(for: .expired))] Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved.") } - private func violations(_ string: String) -> [StyleViolation] { - return SwiftLintFrameworkTests.violations(string, config: config) + private func violations(_ example: Example) -> [StyleViolation] { + return SwiftLintFrameworkTests.violations(example, config: config) } private func dateString(for status: ExpiringTodoRule.ExpiryViolationLevel?) -> String { diff --git a/Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift b/Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift index d2072063cb..e872117c28 100644 --- a/Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift @@ -8,7 +8,7 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { func testExcludeLocalVars() { let nonTriggeringExamples = ExplicitTypeInterfaceRule.description.nonTriggeringExamples + [ - "func foo() {\nlet intVal = 1\n}" + Example("func foo() {\nlet intVal = 1\n}") ] let triggeringExamples = ExplicitTypeInterfaceRule.description.triggeringExamples let description = ExplicitTypeInterfaceRule.description @@ -20,13 +20,13 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { func testExcludeClassVars() { let nonTriggeringExamples = ExplicitTypeInterfaceRule.description.nonTriggeringExamples + [ - "class Foo {\n static var myStaticVar = 0\n}\n", - "class Foo {\n static let myStaticLet = 0\n}\n" + Example("class Foo {\n static var myStaticVar = 0\n}\n"), + Example("class Foo {\n static let myStaticLet = 0\n}\n") ] - let triggeringExamples = [ - "class Foo {\n ↓var myVar = 0\n\n}\n", - "class Foo {\n ↓let mylet = 0\n\n}\n", - "class Foo {\n ↓class var myClassVar = 0\n}\n" + let triggeringExamples: [Example] = [ + Example("class Foo {\n ↓var myVar = 0\n\n}\n"), + Example("class Foo {\n ↓let mylet = 0\n\n}\n"), + Example("class Foo {\n ↓class var myClassVar = 0\n}\n") ] let description = ExplicitTypeInterfaceRule.description .with(triggeringExamples: triggeringExamples) @@ -36,28 +36,28 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { } func testAllowRedundancy() { - let nonTriggeringExamples = [ - "class Foo {\n var myVar: Int? = 0\n}\n", - "class Foo {\n let myVar: Int? = 0\n}\n", - "class Foo {\n static var myVar: Int? = 0\n}\n", - "class Foo {\n class var myVar: Int? = 0\n}\n", - "class Foo {\n static let shared = Foo()\n}\n", - "class Foo {\n let myVar = Int(0)\n}\n", - "class Foo {\n let myVar = Set(0)\n}\n", - "class Foo {\n let regex = try! NSRegularExpression(pattern: \".*\")\n}\n", - "class Foo {\n let regex = try? NSRegularExpression(pattern: \".*\")\n}\n", - "class Foo {\n let array = [String]()\n}\n", - "class Foo {\n let dict = [String: String]()\n}\n", - "class Foo {\n let dict = [String: [String: Array]]()\n}\n", - "class Foo {\n let l10n = L10n.Communication.self\n}\n" + let nonTriggeringExamples: [Example] = [ + Example("class Foo {\n var myVar: Int? = 0\n}\n"), + Example("class Foo {\n let myVar: Int? = 0\n}\n"), + Example("class Foo {\n static var myVar: Int? = 0\n}\n"), + Example("class Foo {\n class var myVar: Int? = 0\n}\n"), + Example("class Foo {\n static let shared = Foo()\n}\n"), + Example("class Foo {\n let myVar = Int(0)\n}\n"), + Example("class Foo {\n let myVar = Set(0)\n}\n"), + Example("class Foo {\n let regex = try! NSRegularExpression(pattern: \".*\")\n}\n"), + Example("class Foo {\n let regex = try? NSRegularExpression(pattern: \".*\")\n}\n"), + Example("class Foo {\n let array = [String]()\n}\n"), + Example("class Foo {\n let dict = [String: String]()\n}\n"), + Example("class Foo {\n let dict = [String: [String: Array]]()\n}\n"), + Example("class Foo {\n let l10n = L10n.Communication.self\n}\n") ] - let triggeringExamples = [ - "class Foo {\n ↓var myVar = 0\n\n}\n", - "class Foo {\n ↓let mylet = 0\n\n}\n", - "class Foo {\n ↓static var myStaticVar = 0\n}\n", - "class Foo {\n ↓class var myClassVar = 0\n}\n", - "class Foo {\n ↓let array = [\"foo\", \"bar\"]\n}\n", - "class Foo {\n ↓let dict = [\"foo\": \"bar\"]\n}\n" + let triggeringExamples: [Example] = [ + Example("class Foo {\n ↓var myVar = 0\n\n}\n"), + Example("class Foo {\n ↓let mylet = 0\n\n}\n"), + Example("class Foo {\n ↓static var myStaticVar = 0\n}\n"), + Example("class Foo {\n ↓class var myClassVar = 0\n}\n"), + Example("class Foo {\n ↓let array = [\"foo\", \"bar\"]\n}\n"), + Example("class Foo {\n ↓let dict = [\"foo\": \"bar\"]\n}\n") ] let description = ExplicitTypeInterfaceRule.description .with(triggeringExamples: triggeringExamples) @@ -68,22 +68,22 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { func testEmbededInStatements() { let nonTriggeringExamples = [ - """ + Example(""" func foo() { var bar: String? guard let strongBar = bar else { return } } - """, - """ + """), + Example(""" struct SomeError: Error {} var error: Error? switch error { case let error as SomeError: break default: break } - """ + """) ] let triggeringExamples = ExplicitTypeInterfaceRule.description.triggeringExamples let description = ExplicitTypeInterfaceRule.description @@ -95,19 +95,19 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { func testCaptureGroup() { let nonTriggeringExamples = [ - """ + Example(""" var k: Int = 0 _ = { [weak k] in print(k) } - """, - """ + """), + Example(""" var k: Int = 0 _ = { [unowned k] in print(k) } - """, - """ + """), + Example(""" class Foo { func bar() { var k: Int = 0 @@ -116,7 +116,7 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { } } } - """ + """) ] let triggeringExamples = ExplicitTypeInterfaceRule.description.triggeringExamples let description = ExplicitTypeInterfaceRule.description @@ -128,18 +128,18 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { func testFastEnumerationDeclaration() { let nonTriggeringExaples = [ - """ + Example(""" func foo() { let elements: [Int] = [1, 2] for element in elements {} } - """, - """ + """), + Example(""" func foo() { let elements: [Int] = [1, 2] for (index, element) in elements.enumerated() {} } - """ + """) ] let triggeringExamples = ExplicitTypeInterfaceRule.description.triggeringExamples @@ -156,7 +156,7 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { } let nonTriggeringExamples = [ - """ + Example(""" enum Foo { case failure(Any) case success(Any) @@ -168,8 +168,8 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { case .success(let result): let bar: Int = 2 } } - """, - """ + """), + Example(""" enum Foo { case failure(Any, Any) } @@ -178,11 +178,11 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { case var (x, y): break } } - """ + """) ] let triggeringExamples = [ - """ + Example(""" enum Foo { case failure(Any) case success(Any) @@ -194,8 +194,8 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { case .success(let result): ↓let fooBar = 1 } } - """, - """ + """), + Example(""" enum Foo { case failure(Any, Any) } @@ -206,7 +206,7 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase { default: ↓let fooBar = 1 } } - """ + """) ] let description = ExplicitTypeInterfaceRule.description diff --git a/Tests/SwiftLintFrameworkTests/FileHeaderRuleTests.swift b/Tests/SwiftLintFrameworkTests/FileHeaderRuleTests.swift index 174d6bd3b7..ed35c5fec0 100644 --- a/Tests/SwiftLintFrameworkTests/FileHeaderRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/FileHeaderRuleTests.swift @@ -19,15 +19,15 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithRequiredString() { let nonTriggeringExamples = [ - "// **Header", - "//\n// **Header" + Example("// **Header"), + Example("//\n// **Header") ] let triggeringExamples = [ - "↓// Copyright\n", - "let foo = \"**Header\"", - "let foo = 2 // **Header", - "let foo = 2\n// **Header", - "let foo = 2 // **Header" + Example("↓// Copyright\n"), + Example("let foo = \"**Header\""), + Example("let foo = 2 // **Header"), + Example("let foo = 2\n// **Header"), + Example("let foo = 2 // **Header") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) @@ -40,13 +40,13 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithRequiredPattern() { let nonTriggeringExamples = [ - "// Copyright © 2016 Realm", - "//\n// Copyright © 2016 Realm" + Example("// Copyright © 2016 Realm"), + Example("//\n// Copyright © 2016 Realm)") ] let triggeringExamples = [ - "↓// Copyright\n", - "↓// Copyright © foo Realm", - "↓// Copyright © 2016 MyCompany" + Example("↓// Copyright\n"), + Example("↓// Copyright © foo Realm"), + Example("↓// Copyright © 2016 MyCompany") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) @@ -59,10 +59,10 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithRequiredStringAndURLComment() { let nonTriggeringExamples = [ - "/* Check this url: https://github.com/realm/SwiftLint */" + Example("/* Check this url: https://github.com/realm/SwiftLint */") ] let triggeringExamples = [ - "/* Check this url: https://github.com/apple/swift */" + Example("/* Check this url: https://github.com/apple/swift */") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) @@ -76,15 +76,15 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithForbiddenString() { let nonTriggeringExamples = [ - "// Copyright\n", - "let foo = \"**All rights reserved.\"", - "let foo = 2 // **All rights reserved.", - "let foo = 2\n// **All rights reserved.", - "let foo = 2 // **All rights reserved." + Example("// Copyright\n"), + Example("let foo = \"**All rights reserved.\""), + Example("let foo = 2 // **All rights reserved."), + Example("let foo = 2\n// **All rights reserved."), + Example("let foo = 2 // **All rights reserved.") ] let triggeringExamples = [ - "// ↓**All rights reserved.", - "//\n// ↓**All rights reserved." + Example("// ↓**All rights reserved."), + Example("//\n// ↓**All rights reserved.") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) @@ -96,15 +96,15 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithForbiddenPattern() { let nonTriggeringExamples = [ - "// Copyright\n", - "// FileHeaderRuleTests.m\n", - "let foo = \"FileHeaderRuleTests.swift\"", - "let foo = 2 // FileHeaderRuleTests.swift.", - "let foo = 2\n // FileHeaderRuleTests.swift." + Example("// Copyright\n"), + Example("// FileHeaderRuleTests.m\n"), + Example("let foo = \"FileHeaderRuleTests.swift\""), + Example("let foo = 2 // FileHeaderRuleTests.swift."), + Example("let foo = 2\n // FileHeaderRuleTests.swift.") ] let triggeringExamples = [ - "//↓ FileHeaderRuleTests.swift", - "//\n//↓ FileHeaderRuleTests.swift" + Example("//↓ FileHeaderRuleTests.swift"), + Example("//\n//↓ FileHeaderRuleTests.swift") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) @@ -116,12 +116,12 @@ class FileHeaderRuleTests: XCTestCase { func testFileHeaderWithForbiddenPatternAndDocComment() { let nonTriggeringExamples = [ - "/// This is great tool with tests.\nclass GreatTool {}", - "class GreatTool {}" + Example("/// This is great tool with tests.\nclass GreatTool {}"), + Example("class GreatTool {}") ] let triggeringExamples = [ - "// FileHeaderRule↓Tests.swift", - "//\n// FileHeaderRule↓Tests.swift" + Example("// FileHeaderRule↓Tests.swift"), + Example("//\n// FileHeaderRule↓Tests.swift") ] let description = FileHeaderRule.description .with(nonTriggeringExamples: nonTriggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/FileLengthRuleTests.swift b/Tests/SwiftLintFrameworkTests/FileLengthRuleTests.swift index 89677d0a37..2321199bd5 100644 --- a/Tests/SwiftLintFrameworkTests/FileLengthRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/FileLengthRuleTests.swift @@ -9,11 +9,11 @@ class FileLengthRuleTests: XCTestCase { func testFileLengthIgnoringLinesWithOnlyComments() { let triggeringExamples = [ - repeatElement("print(\"swiftlint\")\n", count: 401).joined() + Example(repeatElement("print(\"swiftlint\")\n", count: 401).joined()) ] let nonTriggeringExamples = [ - (repeatElement("print(\"swiftlint\")\n", count: 400) + ["//\n"]).joined(), - repeatElement("print(\"swiftlint\")\n", count: 400).joined() + Example((repeatElement("print(\"swiftlint\")\n", count: 400) + ["//\n"]).joined()), + Example(repeatElement("print(\"swiftlint\")\n", count: 400).joined()) ] let description = FileLengthRule.description diff --git a/Tests/SwiftLintFrameworkTests/FileTypesOrderRuleTests.swift b/Tests/SwiftLintFrameworkTests/FileTypesOrderRuleTests.swift index 1d2c49bb9d..65c5e43f9a 100644 --- a/Tests/SwiftLintFrameworkTests/FileTypesOrderRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/FileTypesOrderRuleTests.swift @@ -12,18 +12,18 @@ class FileTypesOrderRuleTests: XCTestCase { func testFileTypesOrderReversedOrder() { // Test with reversed `order` entries let nonTriggeringExamples = [ - FileTypesOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n") + Example(FileTypesOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n")) ] let triggeringExamples = [ - """ + Example(""" // Supporting Types ↓protocol TestViewControllerDelegate { func didPressTrackedButton() } class TestViewController: UIViewController {} - """, - """ + """), + Example(""" ↓class TestViewController: UIViewController {} // Extensions @@ -36,8 +36,8 @@ class FileTypesOrderRuleTests: XCTestCase { return UITableViewCell() } } - """, - """ + """), + Example(""" // Supporting Types ↓protocol TestViewControllerDelegate { func didPressTrackedButton() @@ -49,7 +49,7 @@ class FileTypesOrderRuleTests: XCTestCase { protocol TestViewControllerDelegate { func didPressTrackedButton() } - """ + """) ] let reversedOrderDescription = FileTypesOrderRule.description @@ -67,7 +67,7 @@ class FileTypesOrderRuleTests: XCTestCase { func testFileTypesOrderGroupedOrder() { // Test with grouped `order` entries let nonTriggeringExamples = [ - """ + Example(""" class TestViewController: UIViewController {} // Supporting Type @@ -91,18 +91,18 @@ class FileTypesOrderRuleTests: XCTestCase { extension TestViewController: UITableViewDelegate { func someMethod() {} } - """ + """) ] let triggeringExamples = [ - """ + Example(""" // Supporting Types ↓protocol TestViewControllerDelegate { func didPressTrackedButton() } class TestViewController: UIViewController {} - """, - """ + """), + Example(""" // Extensions ↓extension TestViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -115,7 +115,7 @@ class FileTypesOrderRuleTests: XCTestCase { } class TestViewController: UIViewController {} - """ + """) ] let groupedOrderDescription = FileTypesOrderRule.description diff --git a/Tests/SwiftLintFrameworkTests/FunctionBodyLengthRuleTests.swift b/Tests/SwiftLintFrameworkTests/FunctionBodyLengthRuleTests.swift index f16ed7dee8..c0f9e5edff 100644 --- a/Tests/SwiftLintFrameworkTests/FunctionBodyLengthRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/FunctionBodyLengthRuleTests.swift @@ -1,13 +1,16 @@ import SwiftLintFramework import XCTest -private func funcWithBody(_ body: String, violates: Bool = false) -> String { +private func funcWithBody(_ body: String, + violates: Bool = false, + file: StaticString = #file, + line: UInt = #line) -> Example { let marker = violates ? "↓" : "" - return "func \(marker)abc() {\nvar x = 0\n\(body)}\n" + return Example("func \(marker)abc() {\nvar x = 0\n\(body)}\n", file: file, line: line) } -private func violatingFuncWithBody(_ body: String) -> String { - return funcWithBody(body, violates: true) +private func violatingFuncWithBody(_ body: String, file: StaticString = #file, line: UInt = #line) -> Example { + return funcWithBody(body, violates: true, file: file, line: line) } class FunctionBodyLengthRuleTests: XCTestCase { @@ -17,10 +20,10 @@ class FunctionBodyLengthRuleTests: XCTestCase { func testFunctionBodyLengths() { let longFunctionBody = funcWithBody(repeatElement("x = 0\n", count: 39).joined()) - XCTAssertEqual(violations(longFunctionBody), []) + XCTAssertEqual(self.violations(longFunctionBody), []) let longerFunctionBody = violatingFuncWithBody(repeatElement("x = 0\n", count: 40).joined()) - XCTAssertEqual(violations(longerFunctionBody), [StyleViolation( + XCTAssertEqual(self.violations(longerFunctionBody), [StyleViolation( ruleDescription: FunctionBodyLengthRule.description, location: Location(file: nil, line: 1, character: 1), reason: "Function body should span 40 lines or less excluding comments and " + @@ -29,7 +32,7 @@ class FunctionBodyLengthRuleTests: XCTestCase { let longerFunctionBodyWithEmptyLines = funcWithBody( repeatElement("\n", count: 100).joined() ) - XCTAssertEqual(violations(longerFunctionBodyWithEmptyLines), []) + XCTAssertEqual(self.violations(longerFunctionBodyWithEmptyLines), []) } func testFunctionBodyLengthsWithComments() { @@ -43,7 +46,7 @@ class FunctionBodyLengthRuleTests: XCTestCase { repeatElement("x = 0\n", count: 40).joined() + "// comment only line should be ignored.\n" ) - XCTAssertEqual(violations(longerFunctionBodyWithComments), [StyleViolation( + XCTAssertEqual(self.violations(longerFunctionBodyWithComments), [StyleViolation( ruleDescription: FunctionBodyLengthRule.description, location: Location(file: nil, line: 1, character: 1), reason: "Function body should span 40 lines or less excluding comments and " + @@ -55,21 +58,21 @@ class FunctionBodyLengthRuleTests: XCTestCase { repeatElement("x = 0\n", count: 39).joined() + "/* multi line comment only line should be ignored.\n*/\n" ) - XCTAssertEqual(violations(longFunctionBodyWithMultilineComments), []) + XCTAssertEqual(self.violations(longFunctionBodyWithMultilineComments), []) let longerFunctionBodyWithMultilineComments = violatingFuncWithBody( repeatElement("x = 0\n", count: 40).joined() + "/* multi line comment only line should be ignored.\n*/\n" ) - XCTAssertEqual(violations(longerFunctionBodyWithMultilineComments), [StyleViolation( + XCTAssertEqual(self.violations(longerFunctionBodyWithMultilineComments), [StyleViolation( ruleDescription: FunctionBodyLengthRule.description, location: Location(file: nil, line: 1, character: 1), reason: "Function body should span 40 lines or less excluding comments and " + "whitespace: currently spans 41 lines")]) } - private func violations(_ string: String) -> [StyleViolation] { + private func violations(_ example: Example) -> [StyleViolation] { let config = makeConfig(nil, FunctionBodyLengthRule.description.identifier)! - return SwiftLintFrameworkTests.violations(string, config: config) + return SwiftLintFrameworkTests.violations(example, config: config) } } diff --git a/Tests/SwiftLintFrameworkTests/FunctionParameterCountRuleTests.swift b/Tests/SwiftLintFrameworkTests/FunctionParameterCountRuleTests.swift index 0261bd0d55..628f529e66 100644 --- a/Tests/SwiftLintFrameworkTests/FunctionParameterCountRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/FunctionParameterCountRuleTests.swift @@ -1,10 +1,13 @@ import SwiftLintFramework import XCTest -private func funcWithParameters(_ parameters: String, violates: Bool = false) -> String { +private func funcWithParameters(_ parameters: String, + violates: Bool = false, + file: StaticString = #file, + line: UInt = #line) -> Example { let marker = violates ? "↓" : "" - return "func \(marker)abc(\(parameters)) {}\n" + return Example("func \(marker)abc(\(parameters)) {}\n", file: file, line: line) } class FunctionParameterCountRuleTests: XCTestCase { diff --git a/Tests/SwiftLintFrameworkTests/GenericTypeNameRuleTests.swift b/Tests/SwiftLintFrameworkTests/GenericTypeNameRuleTests.swift index 7c8eef8e49..50626891c9 100644 --- a/Tests/SwiftLintFrameworkTests/GenericTypeNameRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/GenericTypeNameRuleTests.swift @@ -9,12 +9,12 @@ class GenericTypeNameRuleTests: XCTestCase { func testGenericTypeNameWithAllowedSymbols() { let baseDescription = GenericTypeNameRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "func foo() {}\n", - "func foo(param: U%) -> T$ {}\n", - "typealias StringDictionary = Dictionary\n", - "class Foo {}\n", - "struct Foo {}\n", - "enum Foo {}\n" + Example("func foo() {}\n"), + Example("func foo(param: U%) -> T$ {}\n"), + Example("typealias StringDictionary = Dictionary\n"), + Example("class Foo {}\n"), + Example("struct Foo {}\n"), + Example("enum Foo {}\n") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) @@ -24,7 +24,7 @@ class GenericTypeNameRuleTests: XCTestCase { func testGenericTypeNameWithAllowedSymbolsAndViolation() { let baseDescription = GenericTypeNameRule.description let triggeringExamples = [ - "func foo<↓T_$>() {}\n" + Example("func foo<↓T_$>() {}\n") ] let description = baseDescription.with(triggeringExamples: triggeringExamples) @@ -34,13 +34,13 @@ class GenericTypeNameRuleTests: XCTestCase { func testGenericTypeNameWithIgnoreStartWithLowercase() { let baseDescription = GenericTypeNameRule.description let triggeringExamplesToRemove = [ - "func foo<↓type>() {}\n", - "class Foo<↓type> {}\n", - "struct Foo<↓type> {}\n", - "enum Foo<↓type> {}\n" + Example("func foo<↓type>() {}\n"), + Example("class Foo<↓type> {}\n"), + Example("struct Foo<↓type> {}\n"), + Example("enum Foo<↓type> {}\n") ] let nonTriggeringExamples = baseDescription.nonTriggeringExamples + - triggeringExamplesToRemove.map { $0.replacingOccurrences(of: "↓", with: "") } + triggeringExamplesToRemove.removingViolationMarkers() let triggeringExamples = baseDescription.triggeringExamples .filter { !triggeringExamplesToRemove.contains($0) } diff --git a/Tests/SwiftLintFrameworkTests/IdentifierNameRuleTests.swift b/Tests/SwiftLintFrameworkTests/IdentifierNameRuleTests.swift index 4f982ad0bd..0c0c0546ee 100644 --- a/Tests/SwiftLintFrameworkTests/IdentifierNameRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/IdentifierNameRuleTests.swift @@ -9,9 +9,9 @@ class IdentifierNameRuleTests: XCTestCase { func testIdentifierNameWithAllowedSymbols() { let baseDescription = IdentifierNameRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "let myLet$ = 0", - "let myLet% = 0", - "let myLet$% = 0" + Example("let myLet$ = 0"), + Example("let myLet% = 0"), + Example("let myLet$% = 0") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) @@ -21,7 +21,7 @@ class IdentifierNameRuleTests: XCTestCase { func testIdentifierNameWithAllowedSymbolsAndViolation() { let baseDescription = IdentifierNameRule.description let triggeringExamples = [ - "↓let my_Let$ = 0" + Example("↓let my_Let$ = 0") ] let description = baseDescription.with(triggeringExamples: triggeringExamples) @@ -31,11 +31,11 @@ class IdentifierNameRuleTests: XCTestCase { func testIdentifierNameWithIgnoreStartWithLowercase() { let baseDescription = IdentifierNameRule.description let triggeringExamplesToRemove = [ - "↓let MyLet = 0", - "enum Foo { case ↓MyEnum }" + Example("↓let MyLet = 0"), + Example("enum Foo { case ↓MyEnum }") ] let nonTriggeringExamples = baseDescription.nonTriggeringExamples + - triggeringExamplesToRemove.map { $0.replacingOccurrences(of: "↓", with: "") } + triggeringExamplesToRemove.removingViolationMarkers() let triggeringExamples = baseDescription.triggeringExamples .filter { !triggeringExamplesToRemove.contains($0) } @@ -48,7 +48,7 @@ class IdentifierNameRuleTests: XCTestCase { func testLinuxCrashOnEmojiNames() { let baseDescription = IdentifierNameRule.description let triggeringExamples = [ - "let 👦🏼 = \"👦🏼\"" + Example("let 👦🏼 = \"👦🏼\"") ] let description = baseDescription.with(triggeringExamples: triggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/ImplicitlyUnwrappedOptionalRuleTests.swift b/Tests/SwiftLintFrameworkTests/ImplicitlyUnwrappedOptionalRuleTests.swift index 18624361cf..042db46710 100644 --- a/Tests/SwiftLintFrameworkTests/ImplicitlyUnwrappedOptionalRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ImplicitlyUnwrappedOptionalRuleTests.swift @@ -15,12 +15,12 @@ class ImplicitlyUnwrappedOptionalRuleTests: XCTestCase { func testImplicitlyUnwrappedOptionalRuleWarnsOnOutletsInAllMode() { let baseDescription = ImplicitlyUnwrappedOptionalRule.description let triggeringExamples = [ - "@IBOutlet private var label: UILabel!", - "@IBOutlet var label: UILabel!", - "let int: Int!" + Example("@IBOutlet private var label: UILabel!"), + Example("@IBOutlet var label: UILabel!"), + Example("let int: Int!") ] - let nonTriggeringExamples = ["if !boolean {}"] + let nonTriggeringExamples = [Example("if !boolean {}")] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/IndentationWidthRuleTests.swift b/Tests/SwiftLintFrameworkTests/IndentationWidthRuleTests.swift index ca92c16573..ef534d9660 100644 --- a/Tests/SwiftLintFrameworkTests/IndentationWidthRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/IndentationWidthRuleTests.swift @@ -164,7 +164,7 @@ class IndentationWidthRuleTests: XCTestCase { // MARK: Helpers private func countViolations( - in string: String, + in example: Example, indentationWidth: Int? = nil, includeComments: Bool? = nil, file: StaticString = #file, @@ -179,7 +179,7 @@ class IndentationWidthRuleTests: XCTestCase { return 0 } - return violations("\(string)\n", config: config).count + return violations(example.with(code: example.code + "\n"), config: config).count } private func assertViolations( @@ -192,7 +192,7 @@ class IndentationWidthRuleTests: XCTestCase { ) { XCTAssertEqual( countViolations( - in: string, + in: Example(string, file: file, line: line), indentationWidth: indentationWidth, includeComments: includeComments, file: file, diff --git a/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift b/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift index c02a78abf1..b736a3aff4 100644 --- a/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift @@ -3,23 +3,23 @@ import XCTest class LineLengthRuleTests: XCTestCase { private let longFunctionDeclarations = [ - "public func superDuperLongFunctionDeclaration(a: String, b: String, " + + Example("public func superDuperLongFunctionDeclaration(a: String, b: String, " + "c: String, d: String, e: String, f: String, g: String, h: String, i: String, " + "j: String, k: String, l: String, m: String, n: String, o: String, p: String, " + "q: String, r: String, s: String, t: String, u: String, v: String, w: String, " + - "x: String, y: String, z: String) {\n", - "func superDuperLongFunctionDeclaration(a: String, b: String, " + + "x: String, y: String, z: String) {\n"), + Example("func superDuperLongFunctionDeclaration(a: String, b: String, " + "c: String, d: String, e: String, f: String, g: String, h: String, i: String, " + "j: String, k: String, l: String, m: String, n: String, o: String, p: String, " + "q: String, r: String, s: String, t: String, u: String, v: String, w: String, " + - "x: String, y: String, z: String) {\n" + "x: String, y: String, z: String) {\n") ] - private let longComment = String(repeating: "/", count: 121) + "\n" - private let longBlockComment = "/*" + String(repeating: " ", count: 121) + "*/\n" - private let declarationWithTrailingLongComment = "let foo = 1 " + String(repeating: "/", count: 121) + "\n" - private let interpolatedString = "print(\"\\(value)" + String(repeating: "A", count: 113) + "\" )\n" - private let plainString = "print(\"" + String(repeating: "A", count: 121) + ")\"\n" + private let longComment = Example(String(repeating: "/", count: 121) + "\n") + private let longBlockComment = Example("/*" + String(repeating: " ", count: 121) + "*/\n") + private let declarationWithTrailingLongComment = Example("let foo = 1 " + String(repeating: "/", count: 121) + "\n") + private let interpolatedString = Example("print(\"\\(value)" + String(repeating: "A", count: 113) + "\" )\n") + private let plainString = Example("print(\"" + String(repeating: "A", count: 121) + ")\"\n") func testLineLength() { verifyRule(LineLengthRule.description, commentDoesntViolate: false, stringDoesntViolate: false) @@ -48,10 +48,10 @@ class LineLengthRuleTests: XCTestCase { func testLineLengthWithIgnoreURLsEnabled() { let url = "https://github.com/realm/SwiftLint" - let triggeringLines = [String(repeating: "/", count: 121) + "\(url)\n"] + let triggeringLines = [Example(String(repeating: "/", count: 121) + "\(url)\n")] let nonTriggeringLines = [ - "\(url) " + String(repeating: "/", count: 118) + " \(url)\n", - "\(url)/" + String(repeating: "a", count: 120) + Example("\(url) " + String(repeating: "/", count: 118) + " \(url)\n"), + Example("\(url)/" + String(repeating: "a", count: 120)) ] let baseDescription = LineLengthRule.description diff --git a/Tests/SwiftLintFrameworkTests/ModifierOrderTests.swift b/Tests/SwiftLintFrameworkTests/ModifierOrderTests.swift index 896bb0c162..79ff500620 100644 --- a/Tests/SwiftLintFrameworkTests/ModifierOrderTests.swift +++ b/Tests/SwiftLintFrameworkTests/ModifierOrderTests.swift @@ -12,20 +12,28 @@ class ModifierOrderTests: XCTestCase { kind: .style, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "public class SomeClass { \n" + - " class public func someFunc() {} \n" + - "}", - "public class SomeClass { \n" + - " static public func someFunc() {} \n" + - "}" + Example(""" + public class SomeClass { + class public func someFunc() {} + } + """), + Example(""" + public class SomeClass { + static public func someFunc() {} + } + """) ], triggeringExamples: [ - "public class SomeClass { \n" + - " public class func someFunc() {} \n" + - "}", - "public class SomeClass { \n" + - " public static func someFunc() {} \n" + - "}" + Example(""" + public class SomeClass { + public class func someFunc() {} + } + """), + Example(""" + public class SomeClass { + public static func someFunc() {} + } + """) ] ) @@ -41,22 +49,22 @@ class ModifierOrderTests: XCTestCase { kind: .style, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "public protocol Foo: class {}\n" + - "public weak internal(set) var bar: Foo? \n", - "open final class Foo {" + + Example("public protocol Foo: class {}\n" + + "public weak internal(set) var bar: Foo? \n"), + Example("open final class Foo {" + " fileprivate static func bar() {} \n" + - " open class func barFoo() {} }", - "public struct Foo {" + - " private mutating func bar() {} }" + " open class func barFoo() {} }"), + Example("public struct Foo {" + + " private mutating func bar() {} }") ], triggeringExamples: [ - "public protocol Foo: class {} \n" + - "public internal(set) weak var bar: Foo? \n", - "final public class Foo {" + + Example("public protocol Foo: class {} \n" + + "public internal(set) weak var bar: Foo? \n"), + Example("final public class Foo {" + " static fileprivate func bar() {} \n" + - " class open func barFoo() {} }", - "public struct Foo {" + - " mutating private func bar() {} }" + " class open func barFoo() {} }"), + Example("public struct Foo {" + + " mutating private func bar() {} }") ] ) @@ -79,7 +87,7 @@ class ModifierOrderTests: XCTestCase { kind: .style, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - "class Foo { \n" + + Example("class Foo { \n" + " @objc \n" + " internal var bar: String {\n" + " return \"foo\"\n" + @@ -90,27 +98,27 @@ class ModifierOrderTests: XCTestCase { " override internal var bar: String { \n" + " return \"bar\"\n" + " }\n" + - "}", - "@objcMembers \n" + - "public final class Bar {} \n", - "class Foo { \n" + + "}"), + Example("@objcMembers \n" + + "public final class Bar {} \n"), + Example("class Foo { \n" + " @IBOutlet internal weak var bar: UIView!\n" + - "}", - "class Foo { \n" + + "}"), + Example("class Foo { \n" + " @IBAction internal func bar() {}\n" + "}\n" + "class Bar: Foo { \n" + " @IBAction override internal func bar() {}\n" + - "}", - "public class Foo {\n" + + "}"), + Example("public class Foo {\n" + " @NSCopying public final var foo:NSString = \"s\"\n" + - "}", - "public class Bar {\n" + + "}"), + Example("public class Bar {\n" + " @NSManaged public final var foo: NSString \n" + - "}\n" + "}\n") ], triggeringExamples: [ - "class Foo { \n" + + Example("class Foo { \n" + " @objc \n" + " internal var bar: String {\n" + " return \"foo\"\n" + @@ -121,24 +129,24 @@ class ModifierOrderTests: XCTestCase { " internal override var bar: String { \n" + " return \"bar\"\n" + " }\n" + - "}", - "@objcMembers \n" + - "final public class Bar {} \n", - "class Foo { \n" + + "}"), + Example("@objcMembers \n" + + "final public class Bar {} \n"), + Example("class Foo { \n" + " @IBOutlet weak internal var bar: UIView!\n" + - "}", - "class Foo { \n" + + "}"), + Example("class Foo { \n" + " @IBAction internal func bar() {}\n" + "}\n" + "class Bar: Foo { \n" + " @IBAction internal override func bar() {}\n" + - "}", - "public class Foo {\n" + + "}"), + Example("public class Foo {\n" + " @NSCopying final public var foo:NSString = \"s\"\n" + - "}", - "public class Bar {\n" + + "}"), + Example("public class Bar {\n" + " @NSManaged final public var foo: NSString \n" + - "}\n" + "}\n") ] ) @@ -154,48 +162,48 @@ class ModifierOrderTests: XCTestCase { kind: .style, minSwiftVersion: .fourDotOne, nonTriggeringExamples: [ - """ + Example(""" class Foo { weak final override private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { final weak override private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { final override weak private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { final override private weak var bar: UIView? } - """ + """) ], triggeringExamples: [ - """ + Example(""" class Foo { weak override final private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { override weak final private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { override final weak private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { override final private weak var bar: UIView? } - """ + """) ] ) @@ -213,37 +221,37 @@ class ModifierOrderTests: XCTestCase { nonTriggeringExamples: [], triggeringExamples: [], corrections: [ - """ + Example(""" class Foo { private final override var bar: UIView? } - """: - """ + """): + Example(""" class Foo { final override private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { private final var bar: UIView? } - """: - """ + """): + Example(""" class Foo { final private var bar: UIView? } - """, - """ + """), + Example(""" class Foo { class private final var bar: UIView? } - """: - """ + """): + Example(""" class Foo { final private class var bar: UIView? } - """, - """ + """), + Example(""" class Foo { @objc private @@ -252,8 +260,8 @@ class ModifierOrderTests: XCTestCase { override var bar: UIView? } - """: - """ + """): + Example(""" class Foo { @objc final @@ -262,13 +270,13 @@ class ModifierOrderTests: XCTestCase { class var bar: UIView? } - """, - """ + """), + Example(""" private final class Foo {} - """: - """ + """): + Example(""" final private class Foo {} - """ + """) ] ) @@ -286,37 +294,37 @@ class ModifierOrderTests: XCTestCase { nonTriggeringExamples: [], triggeringExamples: [], corrections: [ - """ + Example(""" class Foo { weak class final var bar: UIView? } - """: - """ + """): + Example(""" class Foo { weak final class var bar: UIView? } - """, - """ + """), + Example(""" class Foo { static weak final var bar: UIView? } - """: - """ + """): + Example(""" class Foo { final weak static var bar: UIView? } - """, - """ + """), + Example(""" class Foo { class final weak var bar: UIView? } - """: - """ + """): + Example(""" class Foo { final class weak var bar: UIView? } - """, - """ + """), + Example(""" class Foo { @objc private @@ -325,8 +333,8 @@ class ModifierOrderTests: XCTestCase { final var bar: UIView? } - """: - """ + """): + Example(""" class Foo { @objc final @@ -335,17 +343,17 @@ class ModifierOrderTests: XCTestCase { class var bar: UIView? } - """, - """ + """), + Example(""" class Foo { var bar: UIView? } - """: - """ + """): + Example(""" class Foo { var bar: UIView? } - """ + """) ] ) @@ -363,18 +371,18 @@ class ModifierOrderTests: XCTestCase { nonTriggeringExamples: [], triggeringExamples: [], corrections: [ - """ + Example(""" private final class Foo {} - """: - """ + """): + Example(""" final private class Foo {} - """, - """ + """), + Example(""" public protocol Foo: class {}\n - """: - """ + """): + Example(""" public protocol Foo: class {}\n - """ + """) ] ) @@ -393,8 +401,8 @@ class ModifierOrderTests: XCTestCase { return } - let allViolations = violations("final public var foo: String", config: config) - let modifierOrderRuleViolation = allViolations.first { $0.ruleDescription.identifier == ruleID } + let allViolations = violations(Example("final public var foo: String"), config: config) + let modifierOrderRuleViolation = allViolations.first { $0.ruleIdentifier == ruleID } if let violation = modifierOrderRuleViolation { XCTAssertEqual(violation.reason, "public modifier should be before final.") } else { diff --git a/Tests/SwiftLintFrameworkTests/MultilineArgumentsRuleTests.swift b/Tests/SwiftLintFrameworkTests/MultilineArgumentsRuleTests.swift index d40242b13e..00a6110692 100644 --- a/Tests/SwiftLintFrameworkTests/MultilineArgumentsRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/MultilineArgumentsRuleTests.swift @@ -8,20 +8,20 @@ class MultilineArgumentsRuleTests: XCTestCase { func testMultilineArgumentsWithWithNextLine() { let nonTriggeringExamples = [ - "foo()", - "foo(0)", - "foo(1, bar: baz) { }", - "foo(2, bar: baz) {\n}", - "foo(\n" + + Example("foo()"), + Example("foo(0)"), + Example("foo(1, bar: baz) { }"), + Example("foo(2, bar: baz) {\n}"), + Example("foo(\n" + " 3,\n" + - " bar: baz) { }", - "foo(\n" + - " 4, bar: baz) { }" + " bar: baz) { }"), + Example("foo(\n" + + " 4, bar: baz) { }") ] let triggeringExamples = [ - "foo(↓1,\n" + - " bar: baz) { }" + Example("foo(↓1,\n" + + " bar: baz) { }") ] let description = MultilineArgumentsRule.description @@ -33,22 +33,22 @@ class MultilineArgumentsRuleTests: XCTestCase { func testMultilineArgumentsWithWithSameLine() { let nonTriggeringExamples = [ - "foo()", - "foo(0)", - "foo(1, bar: 1) { }", - "foo(2, bar: 2) {\n" + + Example("foo()"), + Example("foo(0)"), + Example("foo(1, bar: 1) { }"), + Example("foo(2, bar: 2) {\n" + " bar()\n" + - "}", - "foo(3,\n" + - " bar: 3) { }" + "}"), + Example("foo(3,\n" + + " bar: 3) { }") ] let triggeringExamples = [ - "foo(\n" + - " ↓1, ↓bar: baz) { }", - "foo(\n" + + Example("foo(\n" + + " ↓1, ↓bar: baz) { }"), + Example("foo(\n" + " ↓2,\n" + - " bar: baz) { }" + " bar: baz) { }") ] let description = MultilineArgumentsRule.description @@ -59,39 +59,39 @@ class MultilineArgumentsRuleTests: XCTestCase { } func testMultilineArgumentsWithOnlyEnforceAfterFirstClosureOnFirstLine() { - let nonTriggeringExamples: [String] = [ - "foo()", - "foo(0)", - "foo(1, bar: 1) { }", - "foo(\n" + - " 4, bar: baz) { }", - "foo(a: a, b: {\n" + + let nonTriggeringExamples: [Example] = [ + Example("foo()"), + Example("foo(0)"), + Example("foo(1, bar: 1) { }"), + Example("foo(\n" + + " 4, bar: baz) { }"), + Example("foo(a: a, b: {\n" + "}, c: {\n" + - "})", - "foo(\n" + + "})"), + Example("foo(\n" + " a: a, b: {\n" + " }, c: {\n" + - "})", - "foo(a: a, b: b, c: {\n" + + "})"), + Example("foo(a: a, b: b, c: {\n" + "}, d: {\n" + - "})", - "foo(\n" + + "})"), + Example("foo(\n" + " a: a, b: b, c: {\n" + " }, d: {\n" + - "})", - "foo(a: a, b: { [weak self] in\n" + + "})"), + Example("foo(a: a, b: { [weak self] in\n" + "}, c: { flag in\n" + - "})" + "})") ] let triggeringExamples = [ - "foo(a: a,\n" + + Example("foo(a: a,\n" + " b: b, c: {\n" + - "})", - "foo(a: a, b: b,\n" + + "})"), + Example("foo(a: a, b: b,\n" + " c: c, d: {\n" + " }, d: {\n" + - "})" + "})") ] let description = MultilineArgumentsRule.description diff --git a/Tests/SwiftLintFrameworkTests/NumberSeparatorRuleTests.swift b/Tests/SwiftLintFrameworkTests/NumberSeparatorRuleTests.swift index c49001c057..488c043b8f 100644 --- a/Tests/SwiftLintFrameworkTests/NumberSeparatorRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/NumberSeparatorRuleTests.swift @@ -8,21 +8,21 @@ class NumberSeparatorRuleTests: XCTestCase { func testNumberSeparatorWithMinimumLength() { let nonTriggeringExamples = [ - "let foo = 10_000", - "let foo = 1000", - "let foo = 1000.0001", - "let foo = 10_000.0001", - "let foo = 1000.000_01" + Example("let foo = 10_000"), + Example("let foo = 1000"), + Example("let foo = 1000.0001"), + Example("let foo = 10_000.0001"), + Example("let foo = 1000.000_01") ] let triggeringExamples = [ - "let foo = ↓1_000", - "let foo = ↓1.000_1", - "let foo = ↓1_000.000_1" + Example("let foo = ↓1_000"), + Example("let foo = ↓1.000_1"), + Example("let foo = ↓1_000.000_1") ] let corrections = [ - "let foo = ↓1_000": "let foo = 1000", - "let foo = ↓1.000_1": "let foo = 1.0001", - "let foo = ↓1_000.000_1": "let foo = 1000.0001" + Example("let foo = ↓1_000"): Example("let foo = 1000"), + Example("let foo = ↓1.000_1"): Example("let foo = 1.0001"), + Example("let foo = ↓1_000.000_1"): Example("let foo = 1000.0001") ] let description = NumberSeparatorRule.description @@ -35,20 +35,20 @@ class NumberSeparatorRuleTests: XCTestCase { func testNumberSeparatorWithMinimumFractionLength() { let nonTriggeringExamples = [ - "let foo = 1_000.000_000_1", - "let foo = 1.000_001", - "let foo = 100.0001", - "let foo = 1_000.000_01" + Example("let foo = 1_000.000_000_1"), + Example("let foo = 1.000_001"), + Example("let foo = 100.0001"), + Example("let foo = 1_000.000_01") ] let triggeringExamples = [ - "let foo = ↓1000", - "let foo = ↓1.000_1", - "let foo = ↓1_000.000_1" + Example("let foo = ↓1000"), + Example("let foo = ↓1.000_1"), + Example("let foo = ↓1_000.000_1") ] let corrections = [ - "let foo = ↓1000": "let foo = 1_000", - "let foo = ↓1.000_1": "let foo = 1.0001", - "let foo = ↓1_000.000_1": "let foo = 1_000.0001" + Example("let foo = ↓1000"): Example("let foo = 1_000"), + Example("let foo = ↓1.000_1"): Example("let foo = 1.0001"), + Example("let foo = ↓1_000.000_1"): Example("let foo = 1_000.0001") ] let description = NumberSeparatorRule.description @@ -61,28 +61,28 @@ class NumberSeparatorRuleTests: XCTestCase { func testNumberSeparatorWithExcludeRanges() { let nonTriggeringExamples = [ - "let foo = 1950", - "let foo = 1_950", - "let foo = 1985", - "let foo = 1_985", - "let foo = 2020", - "let foo = 2_020", - "let foo = 2.10042", - "let foo = 2.100_42", - "let foo = 2.833333", - "let foo = 2.833_333" + Example("let foo = 1950"), + Example("let foo = 1_950"), + Example("let foo = 1985"), + Example("let foo = 1_985"), + Example("let foo = 2020"), + Example("let foo = 2_020"), + Example("let foo = 2.10042"), + Example("let foo = 2.100_42"), + Example("let foo = 2.833333"), + Example("let foo = 2.833_333") ] let triggeringExamples = [ - "let foo = ↓1000", - "let foo = ↓2100", - "let foo = ↓1.920442", - "let foo = ↓3.343434" + Example("let foo = ↓1000"), + Example("let foo = ↓2100"), + Example("let foo = ↓1.920442"), + Example("let foo = ↓3.343434") ] let corrections = [ - "let foo = ↓1000": "let foo = 1_000", - "let foo = ↓2100": "let foo = 2_100", - "let foo = ↓1.920442": "let foo = 1.920_442", - "let foo = ↓3.343434": "let foo = 3.343_434" + Example("let foo = ↓1000"): Example("let foo = 1_000"), + Example("let foo = ↓2100"): Example("let foo = 2_100"), + Example("let foo = ↓1.920442"): Example("let foo = 1.920_442"), + Example("let foo = ↓3.343434"): Example("let foo = 3.343_434") ] let description = NumberSeparatorRule.description diff --git a/Tests/SwiftLintFrameworkTests/ObjectLiteralRuleTests.swift b/Tests/SwiftLintFrameworkTests/ObjectLiteralRuleTests.swift index 7cd316f278..56445862af 100644 --- a/Tests/SwiftLintFrameworkTests/ObjectLiteralRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ObjectLiteralRuleTests.swift @@ -3,25 +3,25 @@ import XCTest class ObjectLiteralRuleTests: XCTestCase { // MARK: - Instance Properties - private let imageLiteralTriggeringExamples = ["", ".init"].flatMap { (method: String) -> [String] in - ["UI", "NS"].flatMap { (prefix: String) -> [String] in + private let imageLiteralTriggeringExamples = ["", ".init"].flatMap { (method: String) -> [Example] in + ["UI", "NS"].flatMap { (prefix: String) -> [Example] in [ - "let image = ↓\(prefix)Image\(method)(named: \"foo\")" + Example("let image = ↓\(prefix)Image\(method)(named: \"foo\")") ] } } - private let colorLiteralTriggeringExamples = ["", ".init"].flatMap { (method: String) -> [String] in - ["UI", "NS"].flatMap { (prefix: String) -> [String] in + private let colorLiteralTriggeringExamples = ["", ".init"].flatMap { (method: String) -> [Example] in + ["UI", "NS"].flatMap { (prefix: String) -> [Example] in [ - "let color = ↓\(prefix)Color\(method)(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)", - "let color = ↓\(prefix)Color\(method)(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)", - "let color = ↓\(prefix)Color\(method)(white: 0.5, alpha: 1)" + Example("let color = ↓\(prefix)Color\(method)(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)"), + Example("let color = ↓\(prefix)Color\(method)(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)"), + Example("let color = ↓\(prefix)Color\(method)(white: 0.5, alpha: 1)") ] } } - private var allTriggeringExamples: [String] { + private var allTriggeringExamples: [Example] { return imageLiteralTriggeringExamples + colorLiteralTriggeringExamples } @@ -33,9 +33,7 @@ class ObjectLiteralRuleTests: XCTestCase { func testObjectLiteralWithImageLiteral() { // Verify ObjectLiteral rule for when image_literal is true. let baseDescription = ObjectLiteralRule.description - let nonTriggeringColorLiteralExamples = colorLiteralTriggeringExamples.map { example in - example.replacingOccurrences(of: "↓", with: "") - } + let nonTriggeringColorLiteralExamples = colorLiteralTriggeringExamples.removingViolationMarkers() let nonTriggeringExamples = baseDescription.nonTriggeringExamples + nonTriggeringColorLiteralExamples let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) @@ -47,9 +45,7 @@ class ObjectLiteralRuleTests: XCTestCase { func testObjectLiteralWithColorLiteral() { // Verify ObjectLiteral rule for when color_literal is true. let baseDescription = ObjectLiteralRule.description - let nonTriggeringImageLiteralExamples = imageLiteralTriggeringExamples.map { example in - example.replacingOccurrences(of: "↓", with: "") - } + let nonTriggeringImageLiteralExamples = imageLiteralTriggeringExamples.removingViolationMarkers() let nonTriggeringExamples = baseDescription.nonTriggeringExamples + nonTriggeringImageLiteralExamples let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/PrefixedTopLevelConstantRuleTests.swift b/Tests/SwiftLintFrameworkTests/PrefixedTopLevelConstantRuleTests.swift index 6ebac2f3f8..de1507f15e 100644 --- a/Tests/SwiftLintFrameworkTests/PrefixedTopLevelConstantRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/PrefixedTopLevelConstantRuleTests.swift @@ -8,13 +8,13 @@ final class PrefixedTopLevelConstantRuleTests: XCTestCase { func testPrivateOnly() { let triggeringExamples = [ - "private let ↓Foo = 20.0", - "fileprivate let ↓foo = 20.0" + Example("private let ↓Foo = 20.0"), + Example("fileprivate let ↓foo = 20.0") ] let nonTriggeringExamples = [ - "let Foo = 20.0", - "internal let Foo = \"Foo\"", - "public let Foo = 20.0" + Example("let Foo = 20.0"), + Example("internal let Foo = \"Foo\""), + Example("public let Foo = 20.0") ] let description = PrefixedTopLevelConstantRule.description diff --git a/Tests/SwiftLintFrameworkTests/PrivateOutletRuleTests.swift b/Tests/SwiftLintFrameworkTests/PrivateOutletRuleTests.swift index db2b5a2043..ab23d4f368 100644 --- a/Tests/SwiftLintFrameworkTests/PrivateOutletRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/PrivateOutletRuleTests.swift @@ -9,10 +9,10 @@ class PrivateOutletRuleTests: XCTestCase { func testWithAllowPrivateSet() { let baseDescription = PrivateOutletRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "class Foo {\n @IBOutlet private(set) var label: UILabel?\n}\n", - "class Foo {\n @IBOutlet private(set) var label: UILabel!\n}\n", - "class Foo {\n @IBOutlet weak private(set) var label: UILabel?\n}\n", - "class Foo {\n @IBOutlet private(set) weak var label: UILabel?\n}\n" + Example("class Foo {\n @IBOutlet private(set) var label: UILabel?\n}\n"), + Example("class Foo {\n @IBOutlet private(set) var label: UILabel!\n}\n"), + Example("class Foo {\n @IBOutlet weak private(set) var label: UILabel?\n}\n"), + Example("class Foo {\n @IBOutlet private(set) weak var label: UILabel?\n}\n") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/PrivateOverFilePrivateRuleTests.swift b/Tests/SwiftLintFrameworkTests/PrivateOverFilePrivateRuleTests.swift index 3c51d6ab8a..0c612be2a5 100644 --- a/Tests/SwiftLintFrameworkTests/PrivateOverFilePrivateRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/PrivateOverFilePrivateRuleTests.swift @@ -9,14 +9,14 @@ class PrivateOverFilePrivateRuleTests: XCTestCase { func testPrivateOverFilePrivateValidatingExtensions() { let baseDescription = PrivateOverFilePrivateRule.description let triggeringExamples = baseDescription.triggeringExamples + [ - "↓fileprivate extension String {}", - "↓fileprivate \n extension String {}", - "↓fileprivate extension \n String {}" + Example("↓fileprivate extension String {}"), + Example("↓fileprivate \n extension String {}"), + Example("↓fileprivate extension \n String {}") ] let corrections = [ - "↓fileprivate extension String {}": "private extension String {}", - "↓fileprivate \n extension String {}": "private \n extension String {}", - "↓fileprivate extension \n String {}": "private extension \n String {}" + Example("↓fileprivate extension String {}"): Example("private extension String {}"), + Example("↓fileprivate \n extension String {}"): Example("private \n extension String {}"), + Example("↓fileprivate extension \n String {}"): Example("private extension \n String {}") ] let description = baseDescription.with(nonTriggeringExamples: []) @@ -27,7 +27,7 @@ class PrivateOverFilePrivateRuleTests: XCTestCase { func testPrivateOverFilePrivateNotValidatingExtensions() { let baseDescription = PrivateOverFilePrivateRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "fileprivate extension String {}" + Example("fileprivate extension String {}") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/RuleDescription+Examples.swift b/Tests/SwiftLintFrameworkTests/RuleDescription+Examples.swift index ca019e569f..c4c8e13a8b 100644 --- a/Tests/SwiftLintFrameworkTests/RuleDescription+Examples.swift +++ b/Tests/SwiftLintFrameworkTests/RuleDescription+Examples.swift @@ -1,8 +1,8 @@ import SwiftLintFramework extension RuleDescription { - func with(nonTriggeringExamples: [String], - triggeringExamples: [String]) -> RuleDescription { + func with(nonTriggeringExamples: [Example], + triggeringExamples: [Example]) -> RuleDescription { return RuleDescription(identifier: identifier, name: name, description: description, @@ -13,17 +13,17 @@ extension RuleDescription { deprecatedAliases: deprecatedAliases) } - func with(nonTriggeringExamples: [String]) -> RuleDescription { + func with(nonTriggeringExamples: [Example]) -> RuleDescription { return with(nonTriggeringExamples: nonTriggeringExamples, triggeringExamples: triggeringExamples) } - func with(triggeringExamples: [String]) -> RuleDescription { + func with(triggeringExamples: [Example]) -> RuleDescription { return with(nonTriggeringExamples: nonTriggeringExamples, triggeringExamples: triggeringExamples) } - func with(corrections: [String: String]) -> RuleDescription { + func with(corrections: [Example: Example]) -> RuleDescription { return RuleDescription(identifier: identifier, name: name, description: description, diff --git a/Tests/SwiftLintFrameworkTests/TestHelpers.swift b/Tests/SwiftLintFrameworkTests/TestHelpers.swift index 7a2f90d56b..c617f0b7b1 100644 --- a/Tests/SwiftLintFrameworkTests/TestHelpers.swift +++ b/Tests/SwiftLintFrameworkTests/TestHelpers.swift @@ -3,6 +3,8 @@ import SourceKittenFramework @testable import SwiftLintFramework import XCTest +// swiftlint:disable file_length + private let violationMarker = "↓" private extension SwiftLintFile { @@ -27,18 +29,18 @@ extension String { let allRuleIdentifiers = Array(masterRuleList.list.keys) -func violations(_ string: String, config: Configuration = Configuration()!, +func violations(_ example: Example, config: Configuration = Configuration()!, requiresFileOnDisk: Bool = false) -> [StyleViolation] { SwiftLintFile.clearCaches() - let stringStrippingMarkers = string.replacingOccurrences(of: violationMarker, with: "") + let stringStrippingMarkers = example.removingViolationMarkers() guard requiresFileOnDisk else { - let file = SwiftLintFile(contents: stringStrippingMarkers) + let file = SwiftLintFile(contents: stringStrippingMarkers.code) let storage = RuleStorage() let linter = Linter(file: file, configuration: config).collect(into: storage) return linter.styleViolations(using: storage) } - let file = SwiftLintFile.temporary(withContents: stringStrippingMarkers) + let file = SwiftLintFile.temporary(withContents: stringStrippingMarkers.code) let storage = RuleStorage() let collecter = Linter(file: file, configuration: config, compilerArguments: file.makeCompilerArguments()) let linter = collecter.collect(into: storage) @@ -92,8 +94,7 @@ private extension Collection where Element == StyleViolation { return map { violation in let locationWithoutFile = Location(file: nil, line: violation.location.line, character: violation.location.character) - return StyleViolation(ruleDescription: violation.ruleDescription, severity: violation.severity, - location: locationWithoutFile, reason: violation.reason) + return violation.with(location: locationWithoutFile) } } } @@ -108,6 +109,15 @@ private extension Collection where Element == Correction { } } +extension Collection where Element == Example { + /// Returns a dictionary with SwiftLint violation markers (↓) removed from keys. + /// + /// - returns: A new `Array`. + func removingViolationMarkers() -> [Element] { + return map { $0.removingViolationMarkers() } + } +} + private func cleanedContentsAndMarkerOffsets(from contents: String) -> (String, [Int]) { var contents = contents.bridge() var markerOffsets = [Int]() @@ -128,9 +138,9 @@ private func render(violations: [StyleViolation], in contents: String) -> String let message = String(repeating: " ", count: character - 1) + "^ " + [ "\(violation.severity.rawValue): ", - "\(violation.ruleDescription.name) Violation: ", + "\(violation.ruleName) Violation: ", violation.reason, - " (\(violation.ruleDescription.identifier))"].joined() + " (\(violation.ruleIdentifier))"].joined() if line >= contents.count { contents.append(message) } else { @@ -152,8 +162,9 @@ private func render(locations: [Location], in contents: String) -> String { } private extension Configuration { - func assertCorrection(_ before: String, expected: String) { - let (cleanedBefore, markerOffsets) = cleanedContentsAndMarkerOffsets(from: before) + // swiftlint:disable:next function_body_length + func assertCorrection(_ before: Example, expected: Example) { + let (cleanedBefore, markerOffsets) = cleanedContentsAndMarkerOffsets(from: before.code) let file = SwiftLintFile.temporary(withContents: cleanedBefore) // expectedLocations are needed to create before call `correct()` let expectedLocations = markerOffsets.map { Location(file: file, characterOffset: $0) } @@ -164,20 +175,40 @@ private extension Configuration { let linter = collecter.collect(into: storage) let corrections = linter.correct(using: storage).sorted { $0.location < $1.location } if expectedLocations.isEmpty { - XCTAssertEqual(corrections.count, before != expected ? 1 : 0) + XCTAssertEqual( + corrections.count, before.code != expected.code ? 1 : 0, #function + ".expectedLocationsEmpty", + file: before.file, line: before.line) } else { - XCTAssertEqual(corrections.count, expectedLocations.count) + XCTAssertEqual( + corrections.count, + expectedLocations.count, + #function + ".expected locations: \(expectedLocations.count)", + file: before.file, line: before.line) for (correction, expectedLocation) in zip(corrections, expectedLocations) { - XCTAssertEqual(correction.location, expectedLocation) + XCTAssertEqual( + correction.location, + expectedLocation, + #function + ".correction location", + file: before.file, line: before.line) } } - XCTAssertEqual(file.contents, expected) + XCTAssertEqual( + file.contents, + expected.code, + #function + ".file contents", + file: before.file, line: before.line) let path = file.path! do { let corrected = try String(contentsOfFile: path, encoding: .utf8) - XCTAssertEqual(corrected, expected) + XCTAssertEqual( + corrected, + expected.code, + #function + ".corrected file equals expected", + file: before.file, line: before.line) } catch { - XCTFail("couldn't read file at path '\(path)': \(error)") + XCTFail( + "couldn't read file at path '\(path)': \(error)", + file: before.file, line: before.line) } } } @@ -203,7 +234,7 @@ internal func makeConfig(_ ruleConfiguration: Any?, _ identifier: String, return Configuration(rulesMode: .whitelisted(identifiers)) } -private func testCorrection(_ correction: (String, String), +private func testCorrection(_ correction: (Example, Example), configuration config: Configuration, testMultiByteOffsets: Bool) { config.assertCorrection(correction.0, expected: correction.1) @@ -212,12 +243,12 @@ private func testCorrection(_ correction: (String, String), } } -private func addEmoji(_ string: String) -> String { - return "/* 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦 */\n\(string)" +private func addEmoji(_ example: Example) -> Example { + return example.with(code: "/* 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦 */\n\(example.code)") } -private func addShebang(_ string: String) -> String { - return "#!/usr/bin/env swift\n\(string)" +private func addShebang(_ example: Example) -> Example { + return example.with(code: "#!/usr/bin/env swift\n\(example.code)") } extension XCTestCase { @@ -229,16 +260,19 @@ extension XCTestCase { skipStringTests: Bool = false, skipDisableCommandTests: Bool = false, testMultiByteOffsets: Bool = true, - testShebang: Bool = true) { + testShebang: Bool = true, + file: StaticString = #file, + line: UInt = #line) { guard ruleDescription.minSwiftVersion <= .current else { return } - guard let config = makeConfig(ruleConfiguration, - ruleDescription.identifier, - skipDisableCommandTests: skipDisableCommandTests) else { - XCTFail("Failed to create configuration") - return + guard let config = makeConfig( + ruleConfiguration, + ruleDescription.identifier, + skipDisableCommandTests: skipDisableCommandTests) else { + XCTFail("Failed to create configuration", file: file, line: line) + return } let disableCommands: [String] @@ -264,10 +298,13 @@ extension XCTestCase { skipStringTests: Bool = false, disableCommands: [String] = [], testMultiByteOffsets: Bool = true, - testShebang: Bool = true) { - func verify(triggers: [String], nonTriggers: [String]) { + testShebang: Bool = true, + file: StaticString = #file, + line: UInt = #line) { + func verify(triggers: [Example], nonTriggers: [Example]) { verifyExamples(triggers: triggers, nonTriggers: nonTriggers, configuration: config, - requiresFileOnDisk: ruleDescription.requiresFileOnDisk) + requiresFileOnDisk: ruleDescription.requiresFileOnDisk, + file: file, line: line) } let triggers = ruleDescription.triggeringExamples @@ -282,29 +319,32 @@ extension XCTestCase { verify(triggers: triggers.map(addShebang), nonTriggers: nonTriggers.map(addShebang)) } - func makeViolations(_ string: String) -> [StyleViolation] { - return violations(string, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk) + func makeViolations(_ example: Example) -> [StyleViolation] { + return violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk) } // Comment doesn't violate if !skipCommentTests { XCTAssertEqual( - triggers.flatMap({ makeViolations("/*\n " + $0 + "\n */") }).count, - commentDoesntViolate ? 0 : triggers.count + triggers.flatMap({ makeViolations($0.with(code: "/*\n " + $0.code + "\n */")) }).count, + commentDoesntViolate ? 0 : triggers.count, + file: file, line: line ) } // String doesn't violate if !skipStringTests { XCTAssertEqual( - triggers.flatMap({ makeViolations($0.toStringLiteral()) }).count, - stringDoesntViolate ? 0 : triggers.count + triggers.flatMap({ makeViolations($0.with(code: $0.code.toStringLiteral())) }).count, + stringDoesntViolate ? 0 : triggers.count, + file: file, line: line ) } // "disable" commands doesn't violate for command in disableCommands { - XCTAssert(triggers.flatMap({ makeViolations(command + $0) }).isEmpty) + XCTAssert(triggers.flatMap({ makeViolations($0.with(code: command + $0.code)) }).isEmpty, + file: file, line: line) } } @@ -322,22 +362,28 @@ extension XCTestCase { // "disable" commands do not correct ruleDescription.corrections.forEach { before, _ in for command in disableCommands { - let beforeDisabled = command + before - let expectedCleaned = cleanedContentsAndMarkerOffsets(from: beforeDisabled).0 + let beforeDisabled = command + before.code + let expectedCleaned = before.with(code: cleanedContentsAndMarkerOffsets(from: beforeDisabled).0) config.assertCorrection(expectedCleaned, expected: expectedCleaned) } } } - private func verifyExamples(triggers: [String], nonTriggers: [String], - configuration config: Configuration, requiresFileOnDisk: Bool) { + // swiftlint:disable:next function_body_length + private func verifyExamples(triggers: [Example], nonTriggers: [Example], + configuration config: Configuration, requiresFileOnDisk: Bool, + file callSiteFile: StaticString = #file, + line callSiteLine: UInt = #line) { // Non-triggering examples don't violate for nonTrigger in nonTriggers { let unexpectedViolations = violations(nonTrigger, config: config, requiresFileOnDisk: requiresFileOnDisk) if unexpectedViolations.isEmpty { continue } - let nonTriggerWithViolations = render(violations: unexpectedViolations, in: nonTrigger) - XCTFail("nonTriggeringExample violated: \n\(nonTriggerWithViolations)") + let nonTriggerWithViolations = render(violations: unexpectedViolations, in: nonTrigger.code) + XCTFail( + "nonTriggeringExample violated: \n\(nonTriggerWithViolations)", + file: nonTrigger.file, + line: nonTrigger.line) } // Triggering examples violate @@ -346,10 +392,13 @@ extension XCTestCase { requiresFileOnDisk: requiresFileOnDisk) // Triggering examples with violation markers violate at the marker's location - let (cleanTrigger, markerOffsets) = cleanedContentsAndMarkerOffsets(from: trigger) + let (cleanTrigger, markerOffsets) = cleanedContentsAndMarkerOffsets(from: trigger.code) if markerOffsets.isEmpty { if triggerViolations.isEmpty { - XCTFail("triggeringExample did not violate: \n```\n\(trigger)\n```") + XCTFail( + "triggeringExample did not violate: \n```\n\(trigger)\n```", + file: trigger.file, + line: trigger.line) } continue } @@ -361,7 +410,9 @@ extension XCTestCase { .filter { !expectedLocations.contains($0.location) } if !violationsAtUnexpectedLocation.isEmpty { XCTFail("triggeringExample violate at unexpected location: \n" + - "\(render(violations: violationsAtUnexpectedLocation, in: trigger))") + "\(render(violations: violationsAtUnexpectedLocation, in: trigger.code))", + file: trigger.file, + line: trigger.line) } // Assert locations missing violation @@ -370,27 +421,38 @@ extension XCTestCase { .filter { !violatedLocations.contains($0) } if !locationsWithoutViolation.isEmpty { XCTFail("triggeringExample did not violate at expected location: \n" + - "\(render(locations: locationsWithoutViolation, in: cleanTrigger))") + "\(render(locations: locationsWithoutViolation, in: cleanTrigger))", + file: trigger.file, + line: trigger.line) } - XCTAssertEqual(triggerViolations.count, expectedLocations.count) + XCTAssertEqual(triggerViolations.count, expectedLocations.count, + file: trigger.file, line: trigger.line) for (triggerViolation, expectedLocation) in zip(triggerViolations, expectedLocations) { - XCTAssertEqual(triggerViolation.location, expectedLocation, - "'\(trigger)' violation didn't match expected location.") + XCTAssertEqual( + triggerViolation.location, expectedLocation, + "'\(trigger)' violation didn't match expected location.", + file: trigger.file, + line: trigger.line) } } } - func checkError(_ error: T, closure: () throws -> Void) { + // file and line parameters are first so we can use trailing closure syntax with the closure + func checkError( + file: StaticString = #file, + line: UInt = #line, + _ error: T, + closure: () throws -> Void) { do { try closure() - XCTFail("No error caught") + XCTFail("No error caught", file: file, line: line) } catch let rError as T { if error != rError { - XCTFail("Wrong error caught. Got \(rError) but was expecting \(error)") + XCTFail("Wrong error caught. Got \(rError) but was expecting \(error)", file: file, line: line) } } catch { - XCTFail("Wrong error caught") + XCTFail("Wrong error caught", file: file, line: line) } } } diff --git a/Tests/SwiftLintFrameworkTests/TodoRuleTests.swift b/Tests/SwiftLintFrameworkTests/TodoRuleTests.swift index 2ed6b87128..ca3d525fd5 100644 --- a/Tests/SwiftLintFrameworkTests/TodoRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/TodoRuleTests.swift @@ -7,21 +7,21 @@ class TodoRuleTests: XCTestCase { } func testTodoMessage() { - let string = "fatalError() // TODO: Implement" - let violations = self.violations(string) + let example = Example("fatalError() // TODO: Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "TODOs should be resolved (Implement).") } func testFixMeMessage() { - let string = "fatalError() // FIXME: Implement" - let violations = self.violations(string) + let example = Example("fatalError() // FIXME: Implement") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first!.reason, "FIXMEs should be resolved (Implement).") } - private func violations(_ string: String) -> [StyleViolation] { + private func violations(_ example: Example) -> [StyleViolation] { let config = makeConfig(nil, TodoRule.description.identifier)! - return SwiftLintFrameworkTests.violations(string, config: config) + return SwiftLintFrameworkTests.violations(example, config: config) } } diff --git a/Tests/SwiftLintFrameworkTests/TrailingClosureRuleTests.swift b/Tests/SwiftLintFrameworkTests/TrailingClosureRuleTests.swift index 3b29153353..6a88a168fe 100644 --- a/Tests/SwiftLintFrameworkTests/TrailingClosureRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/TrailingClosureRuleTests.swift @@ -10,11 +10,11 @@ class TrailingClosureRuleTests: XCTestCase { let originalDescription = TrailingClosureRule.description let description = originalDescription .with(nonTriggeringExamples: originalDescription.nonTriggeringExamples + [ - "foo.reduce(0, combine: { $0 + 1 })", - "offsets.sorted(by: { $0.offset < $1.offset })", - "foo.something(0, { $0 + 1 })" + Example("foo.reduce(0, combine: { $0 + 1 })"), + Example("offsets.sorted(by: { $0.offset < $1.offset })"), + Example("foo.something(0, { $0 + 1 })") ]) - .with(triggeringExamples: ["foo.map({ $0 + 1 })"]) + .with(triggeringExamples: [Example("foo.map({ $0 + 1 })")]) verifyRule(description, ruleConfiguration: ["only_single_muted_parameter": true]) } diff --git a/Tests/SwiftLintFrameworkTests/TrailingCommaRuleTests.swift b/Tests/SwiftLintFrameworkTests/TrailingCommaRuleTests.swift index df1ad85e33..448e4c2541 100644 --- a/Tests/SwiftLintFrameworkTests/TrailingCommaRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/TrailingCommaRuleTests.swift @@ -6,14 +6,14 @@ class TrailingCommaRuleTests: XCTestCase { // Verify TrailingCommaRule with test values for when mandatory_comma is false (default). if SwiftVersion.current >= .fourDotOne { let triggeringExamples = TrailingCommaRule.description.triggeringExamples + - ["class C {\n #if true\n func f() {\n let foo = [1, 2, 3↓,]\n }\n #endif\n}"] + [Example("class C {\n #if true\n func f() {\n let foo = [1, 2, 3↓,]\n }\n #endif\n}")] verifyRule(TrailingCommaRule.description.with(triggeringExamples: triggeringExamples)) } else { verifyRule(TrailingCommaRule.description) } // Ensure the rule produces the correct reason string. - let failingCase = "let array = [\n\t1,\n\t2,\n]\n" + let failingCase = Example("let array = [\n\t1,\n\t2,\n]\n") XCTAssertEqual(trailingCommaViolations(failingCase), [ StyleViolation( ruleDescription: TrailingCommaRule.description, @@ -24,34 +24,34 @@ class TrailingCommaRuleTests: XCTestCase { } private static let triggeringExamples = [ - "let foo = [1, 2,\n 3↓]\n", - "let foo = [1: 2,\n 2: 3↓]\n", - "let foo = [1: 2,\n 2: 3↓ ]\n", - "struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n", - "let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n", - "let foo = [\"אבג\", \"αβγ\",\n\"🇺🇸\"↓]\n" + Example("let foo = [1, 2,\n 3↓]\n"), + Example("let foo = [1: 2,\n 2: 3↓]\n"), + Example("let foo = [1: 2,\n 2: 3↓ ]\n"), + Example("struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n"), + Example("let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n"), + Example("let foo = [\"אבג\", \"αβγ\",\n\"🇺🇸\"↓]\n") ] private static let nonTriggeringExamples = [ - "let foo = []\n", - "let foo = [:]\n", - "let foo = [1, 2, 3,]\n", - "let foo = [1, 2, 3, ]\n", - "let foo = [1, 2, 3 ,]\n", - "let foo = [1: 2, 2: 3, ]\n", - "struct Bar {\n let foo = [1: 2, 2: 3,]\n}\n", - "let foo = [Void]()\n", - "let foo = [(Void, Void)]()\n", - "let foo = [1, 2, 3]\n", - "let foo = [1: 2, 2: 3]\n", - "let foo = [1: 2, 2: 3 ]\n", - "struct Bar {\n let foo = [1: 2, 2: 3]\n}\n", - "let foo = [1, 2, 3] + [4, 5, 6]\n" + Example("let foo = []\n"), + Example("let foo = [:]\n"), + Example("let foo = [1, 2, 3,]\n"), + Example("let foo = [1, 2, 3, ]\n"), + Example("let foo = [1, 2, 3 ,]\n"), + Example("let foo = [1: 2, 2: 3, ]\n"), + Example("struct Bar {\n let foo = [1: 2, 2: 3,]\n}\n"), + Example("let foo = [Void]()\n"), + Example("let foo = [(Void, Void)]()\n"), + Example("let foo = [1, 2, 3]\n"), + Example("let foo = [1: 2, 2: 3]\n"), + Example("let foo = [1: 2, 2: 3 ]\n"), + Example("struct Bar {\n let foo = [1: 2, 2: 3]\n}\n"), + Example("let foo = [1, 2, 3] + [4, 5, 6]\n") ] - private static let corrections: [String: String] = { - let fixed = triggeringExamples.map { $0.replacingOccurrences(of: "↓", with: ",") } - var result: [String: String] = [:] + private static let corrections: [Example: Example] = { + let fixed = triggeringExamples.map { $0.with(code: $0.code.replacingOccurrences(of: "↓", with: ",")) } + var result: [Example: Example] = [:] for (triggering, correction) in zip(triggeringExamples, fixed) { result[triggering] = correction } @@ -71,7 +71,7 @@ class TrailingCommaRuleTests: XCTestCase { verifyRule(ruleDescription, ruleConfiguration: ruleConfiguration) // Ensure the rule produces the correct reason string. - let failingCase = "let array = [\n\t1,\n\t2\n]\n" + let failingCase = Example("let array = [\n\t1,\n\t2\n]\n") XCTAssertEqual(trailingCommaViolations(failingCase, ruleConfiguration: ruleConfiguration), [ StyleViolation( ruleDescription: TrailingCommaRule.description, @@ -81,8 +81,8 @@ class TrailingCommaRuleTests: XCTestCase { ]) } - private func trailingCommaViolations(_ string: String, ruleConfiguration: Any? = nil) -> [StyleViolation] { + private func trailingCommaViolations(_ example: Example, ruleConfiguration: Any? = nil) -> [StyleViolation] { let config = makeConfig(ruleConfiguration, TrailingCommaRule.description.identifier)! - return violations(string, config: config) + return violations(example, config: config) } } diff --git a/Tests/SwiftLintFrameworkTests/TrailingWhitespaceTests.swift b/Tests/SwiftLintFrameworkTests/TrailingWhitespaceTests.swift index 5463c09f8c..706e206a28 100644 --- a/Tests/SwiftLintFrameworkTests/TrailingWhitespaceTests.swift +++ b/Tests/SwiftLintFrameworkTests/TrailingWhitespaceTests.swift @@ -10,7 +10,7 @@ class TrailingWhitespaceTests: XCTestCase { // Perform additional tests with the ignores_empty_lines setting enabled. // The set of non-triggering examples is extended by a whitespace-indented empty line let baseDescription = TrailingWhitespaceRule.description - let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [" \n"] + let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [Example(" \n")] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) verifyRule(description, @@ -20,7 +20,10 @@ class TrailingWhitespaceTests: XCTestCase { func testWithIgnoresCommentsDisabled() { // Perform additional tests with the ignores_comments settings disabled. let baseDescription = TrailingWhitespaceRule.description - let triggeringComments = ["// \n", "let name: String // \n"] + let triggeringComments = [ + Example("// \n"), + Example("let name: String // \n") + ] let nonTriggeringExamples = baseDescription.nonTriggeringExamples .filter { !triggeringComments.contains($0) } let triggeringExamples = baseDescription.triggeringExamples + triggeringComments diff --git a/Tests/SwiftLintFrameworkTests/TypeContentsOrderRuleTests.swift b/Tests/SwiftLintFrameworkTests/TypeContentsOrderRuleTests.swift index 73a42395a6..78832bd3e2 100644 --- a/Tests/SwiftLintFrameworkTests/TypeContentsOrderRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/TypeContentsOrderRuleTests.swift @@ -10,14 +10,14 @@ class TypeContentsOrderRuleTests: XCTestCase { func testTypeContentsOrderReversedOrder() { // Test with reversed `order` entries let nonTriggeringExamples = [ - [ + Example([ "class TestViewController: UIViewController {", TypeContentsOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n"), "}" - ].joined(separator: "\n") + ].joined(separator: "\n")) ] let triggeringExamples = [ - """ + Example(""" class TestViewController: UIViewController { // Type Aliases ↓typealias CompletionHandler = ((TestEnum) -> Void) @@ -27,8 +27,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // 10 lines } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Subtypes ↓class TestClass { @@ -38,8 +38,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // Stored Type Properties static let cellIdentifier: String = "AmazingCell" } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Stored Type Properties ↓static let cellIdentifier: String = "AmazingCell" @@ -47,8 +47,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // Stored Instance Properties var shouldLayoutView1: Bool! } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Computed Instance Properties private ↓var hasAnyLayoutedView: Bool { @@ -58,8 +58,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // IBOutlets @IBOutlet private var view1: UIView! } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // IBOutlets @IBOutlet private ↓var view1: UIView! @@ -74,8 +74,8 @@ class TypeContentsOrderRuleTests: XCTestCase { log.debug("deinit") } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Type Methods ↓static func makeViewController() -> TestViewController { @@ -91,8 +91,8 @@ class TypeContentsOrderRuleTests: XCTestCase { hasLayoutedView1 = true } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // View Life-Cycle Methods override ↓func viewDidLoad() { @@ -109,8 +109,8 @@ class TypeContentsOrderRuleTests: XCTestCase { delegate?.didPressTrackedButton() } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // IBActions @IBAction ↓func goNextButtonPressed() { @@ -121,8 +121,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // Other Methods func goToNextVc() { /* TODO */ } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // MARK: Other Methods ↓func goToNextVc() { /* TODO */ } @@ -138,7 +138,7 @@ class TypeContentsOrderRuleTests: XCTestCase { } } } - """ + """) ] let reversedOrderDescription = TypeContentsOrderRule.description @@ -171,7 +171,7 @@ class TypeContentsOrderRuleTests: XCTestCase { func testTypeContentsOrderGroupedOrder() { // Test with grouped `order` entries let nonTriggeringExamples = [ - """ + Example(""" class TestViewController: UIViewController { // Type Alias typealias CompletionHandler = ((TestClass) -> Void) @@ -279,10 +279,10 @@ class TypeContentsOrderRuleTests: XCTestCase { hasLayoutedView2 = true } } - """ + """) ] let triggeringExamples = [ - """ + Example(""" class TestViewController: UIViewController { // Type Alias typealias CompletionHandler = ((TestClass) -> Void) @@ -300,8 +300,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // 10 lines } } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Instance Property var shouldLayoutView1: Bool! @@ -314,8 +314,8 @@ class TypeContentsOrderRuleTests: XCTestCase { // Type Property static let cellIdentifier: String = "AmazingCell" } - """, - """ + """), + Example(""" class TestViewController: UIViewController { // Initializer override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { @@ -330,7 +330,7 @@ class TypeContentsOrderRuleTests: XCTestCase { // some code } } - """ + """) ] let groupedOrderDescription = TypeContentsOrderRule.description diff --git a/Tests/SwiftLintFrameworkTests/TypeNameRuleTests.swift b/Tests/SwiftLintFrameworkTests/TypeNameRuleTests.swift index 7e271e00a0..36204e28bf 100644 --- a/Tests/SwiftLintFrameworkTests/TypeNameRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/TypeNameRuleTests.swift @@ -9,11 +9,11 @@ class TypeNameRuleTests: XCTestCase { func testTypeNameWithAllowedSymbols() { let baseDescription = TypeNameRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "class MyType$ {}", - "struct MyType$ {}", - "enum MyType$ {}", - "typealias Foo$ = Void", - "protocol Foo {\n associatedtype Bar$\n }" + Example("class MyType$ {}"), + Example("struct MyType$ {}"), + Example("enum MyType$ {}"), + Example("typealias Foo$ = Void"), + Example("protocol Foo {\n associatedtype Bar$\n }") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) @@ -23,7 +23,7 @@ class TypeNameRuleTests: XCTestCase { func testTypeNameWithAllowedSymbolsAndViolation() { let baseDescription = TypeNameRule.description let triggeringExamples = [ - "class ↓My_Type$ {}" + Example("class ↓My_Type$ {}") ] let description = baseDescription.with(triggeringExamples: triggeringExamples) @@ -33,13 +33,13 @@ class TypeNameRuleTests: XCTestCase { func testTypeNameWithIgnoreStartWithLowercase() { let baseDescription = TypeNameRule.description let triggeringExamplesToRemove = [ - "private typealias ↓foo = Void", - "class ↓myType {}", - "struct ↓myType {}", - "enum ↓myType {}" + Example("private typealias ↓foo = Void"), + Example("class ↓myType {}"), + Example("struct ↓myType {}"), + Example("enum ↓myType {}") ] let nonTriggeringExamples = baseDescription.nonTriggeringExamples + - triggeringExamplesToRemove.map { $0.replacingOccurrences(of: "↓", with: "") } + triggeringExamplesToRemove.removingViolationMarkers() let triggeringExamples = baseDescription.triggeringExamples .filter { !triggeringExamplesToRemove.contains($0) } diff --git a/Tests/SwiftLintFrameworkTests/UnusedOptionalBindingRuleTests.swift b/Tests/SwiftLintFrameworkTests/UnusedOptionalBindingRuleTests.swift index 01fdd5513e..8cc20f0b06 100644 --- a/Tests/SwiftLintFrameworkTests/UnusedOptionalBindingRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/UnusedOptionalBindingRuleTests.swift @@ -5,7 +5,7 @@ class UnusedOptionalBindingRuleTests: XCTestCase { func testDefaultConfiguration() { let baseDescription = UnusedOptionalBindingRule.description let triggeringExamples = baseDescription.triggeringExamples + [ - "guard let _ = try? alwaysThrows() else { return }" + Example("guard let _ = try? alwaysThrows() else { return }") ] let description = baseDescription.with(triggeringExamples: triggeringExamples) @@ -16,7 +16,7 @@ class UnusedOptionalBindingRuleTests: XCTestCase { // Perform additional tests with the ignore_optional_try settings enabled. let baseDescription = UnusedOptionalBindingRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ - "guard let _ = try? alwaysThrows() else { return }" + Example("guard let _ = try? alwaysThrows() else { return }") ] let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) diff --git a/Tests/SwiftLintFrameworkTests/VerticalWhitespaceRuleTests.swift b/Tests/SwiftLintFrameworkTests/VerticalWhitespaceRuleTests.swift index fdd7b34387..ab6634ae44 100644 --- a/Tests/SwiftLintFrameworkTests/VerticalWhitespaceRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/VerticalWhitespaceRuleTests.swift @@ -12,8 +12,8 @@ class VerticalWhitespaceRuleTests: XCTestCase { func testAttributesWithMaxEmptyLines() { // Test with custom `max_empty_lines` let maxEmptyLinesDescription = VerticalWhitespaceRule.description - .with(nonTriggeringExamples: ["let aaaa = 0\n\n\n"]) - .with(triggeringExamples: ["struct AAAA {}\n\n\n\n"]) + .with(nonTriggeringExamples: [Example("let aaaa = 0\n\n\n")]) + .with(triggeringExamples: [Example("struct AAAA {}\n\n\n\n")]) .with(corrections: [:]) verifyRule(maxEmptyLinesDescription, @@ -25,8 +25,8 @@ class VerticalWhitespaceRuleTests: XCTestCase { .with(nonTriggeringExamples: []) .with(triggeringExamples: []) .with(corrections: [ - "let b = 0\n\n↓\n↓\n↓\n\nclass AAA {}\n": "let b = 0\n\n\nclass AAA {}\n", - "let b = 0\n\n\nclass AAA {}\n": "let b = 0\n\n\nclass AAA {}\n" + Example("let b = 0\n\n↓\n↓\n↓\n\nclass AAA {}\n"): Example("let b = 0\n\n\nclass AAA {}\n"), + Example("let b = 0\n\n\nclass AAA {}\n"): Example("let b = 0\n\n\nclass AAA {}\n") ]) verifyRule(maxEmptyLinesDescription, @@ -38,9 +38,9 @@ class VerticalWhitespaceRuleTests: XCTestCase { XCTFail("Failed to create configuration") return } - let allViolations = violations("let aaaa = 0\n\n\n\nlet bbb = 2\n", config: config) + let allViolations = violations(Example("let aaaa = 0\n\n\n\nlet bbb = 2\n"), config: config) - let verticalWhiteSpaceViolation = allViolations.first { $0.ruleDescription.identifier == ruleID } + let verticalWhiteSpaceViolation = allViolations.first { $0.ruleIdentifier == ruleID } if let violation = verticalWhiteSpaceViolation { XCTAssertEqual(violation.reason, "Limit vertical whitespace to maximum 2 empty lines. Currently 3.") } else { @@ -49,8 +49,8 @@ class VerticalWhitespaceRuleTests: XCTestCase { } func testViolationMessageWithDefaultConfiguration() { - let allViolations = violations("let aaaa = 0\n\n\n\nlet bbb = 2\n") - let verticalWhiteSpaceViolation = allViolations.first(where: { $0.ruleDescription.identifier == ruleID }) + let allViolations = violations(Example("let aaaa = 0\n\n\n\nlet bbb = 2\n")) + let verticalWhiteSpaceViolation = allViolations.first(where: { $0.ruleIdentifier == ruleID }) if let violation = verticalWhiteSpaceViolation { XCTAssertEqual(violation.reason, "Limit vertical whitespace to a single empty line. Currently 3.") } else { diff --git a/Tests/SwiftLintFrameworkTests/XCTSpecificMatcherRuleTests.swift b/Tests/SwiftLintFrameworkTests/XCTSpecificMatcherRuleTests.swift index 971d2fb813..8deac65d6e 100644 --- a/Tests/SwiftLintFrameworkTests/XCTSpecificMatcherRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/XCTSpecificMatcherRuleTests.swift @@ -9,48 +9,48 @@ class XCTSpecificMatcherRuleTests: XCTestCase { // MARK: - Reasons func testEqualTrue() { - let string = "XCTAssertEqual(a, true)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(a, true)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead.") } func testEqualFalse() { - let string = "XCTAssertEqual(a, false)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(a, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead.") } func testEqualNil() { - let string = "XCTAssertEqual(a, nil)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(a, nil)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNil' instead.") } func testNotEqualTrue() { - let string = "XCTAssertNotEqual(a, true)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(a, true)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead.") } func testNotEqualFalse() { - let string = "XCTAssertNotEqual(a, false)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(a, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead.") } func testNotEqualNil() { - let string = "XCTAssertNotEqual(a, nil)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(a, nil)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotNil' instead.") @@ -59,70 +59,70 @@ class XCTSpecificMatcherRuleTests: XCTestCase { // MARK: - Additional Tests func testEqualOptionalFalse() { - let string = "XCTAssertEqual(a?.b, false)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(a?.b, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 0) } func testEqualUnwrappedOptionalFalse() { - let string = "XCTAssertEqual(a!.b, false)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(a!.b, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead.") } func testEqualNilNil() { - let string = "XCTAssertEqual(nil, nil)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(nil, nil)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNil' instead.") } func testEqualTrueTrue() { - let string = "XCTAssertEqual(true, true)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(true, true)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead.") } func testEqualFalseFalse() { - let string = "XCTAssertEqual(false, false)" - let violations = self.violations(string) + let example = Example("XCTAssertEqual(false, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead.") } func testNotEqualNilNil() { - let string = "XCTAssertNotEqual(nil, nil)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(nil, nil)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotNil' instead.") } func testNotEqualTrueTrue() { - let string = "XCTAssertNotEqual(true, true)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(true, true)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead.") } func testNotEqualFalseFalse() { - let string = "XCTAssertNotEqual(false, false)" - let violations = self.violations(string) + let example = Example("XCTAssertNotEqual(false, false)") + let violations = self.violations(example) XCTAssertEqual(violations.count, 1) XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead.") } - private func violations(_ string: String) -> [StyleViolation] { + private func violations(_ example: Example) -> [StyleViolation] { guard let config = makeConfig(nil, XCTSpecificMatcherRule.description.identifier) else { return [] } - return SwiftLintFrameworkTests.violations(string, config: config) + return SwiftLintFrameworkTests.violations(example, config: config) } }