From 7bbfa99e073fb2ebb260c0594cdfd8ee421ae755 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Sun, 17 May 2015 11:26:38 +0200 Subject: [PATCH] added type body length violation --- Source/SwiftLintFramework/Linter.swift | 30 +++++++++++++++++++ .../SwiftLintFrameworkTests/LinterTests.swift | 21 ++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Source/SwiftLintFramework/Linter.swift b/Source/SwiftLintFramework/Linter.swift index 87dcd2d23..b9fac4f8a 100644 --- a/Source/SwiftLintFramework/Linter.swift +++ b/Source/SwiftLintFramework/Linter.swift @@ -237,11 +237,41 @@ extension File { let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { violations.extend(self.validateTypeName(kind, dict: subDict)) violations.extend(self.validateVariableName(kind, dict: subDict)) + violations.extend(self.validateTypeBodyLength(kind, dict: subDict)) } return violations }, [], +) } + func validateTypeBodyLength(kind: SwiftDeclarationKind, dict: XPCDictionary) -> + [StyleViolation] { + let typeKinds: [SwiftDeclarationKind] = [ + .Class, + .Struct, + .Enum + ] + if !contains(typeKinds, kind) { + return [] + } + var violations = [StyleViolation]() + if let name = dict["key.name"] as? String, + let offset = flatMap(dict["key.offset"] as? Int64, { Int($0) }), + let bodyOffset = flatMap(dict["key.bodyoffset"] as? Int64, { Int($0) }), + let bodyLength = flatMap(dict["key.bodylength"] as? Int64, { Int($0) }) { + let location = Location(file: self, offset: offset) + let startLine = self.contents.lineAndCharacterForByteOffset(bodyOffset) + let endLine = self.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength) + if let startLine = startLine?.line, let endLine = endLine?.line + where endLine - startLine > 200 { + violations.append(StyleViolation(type: .Length, + location: location, + reason: "Type body should be span 200 lines or less: currently spans " + + "\(endLine - startLine) lines")) + } + } + return violations + } + func validateTypeName(kind: SwiftDeclarationKind, dict: XPCDictionary) -> [StyleViolation] { let typeKinds: [SwiftDeclarationKind] = [ .Class, diff --git a/Source/SwiftLintFrameworkTests/LinterTests.swift b/Source/SwiftLintFrameworkTests/LinterTests.swift index a269925e7..9d525cf89 100644 --- a/Source/SwiftLintFrameworkTests/LinterTests.swift +++ b/Source/SwiftLintFrameworkTests/LinterTests.swift @@ -17,12 +17,6 @@ func violations(string: String) -> [StyleViolation] { class LinterTests: XCTestCase { - // MARK: Integration Tests - - func testThisFile() { - XCTAssertEqual(violations(File(path: __FILE__)!.contents), []) - } - // MARK: AST Violations func testTypeNames() { @@ -123,8 +117,19 @@ class LinterTests: XCTestCase { // TODO: Functions should be 40 lines or less. } - func testTypeLengths() { - // TODO: Types should be 200 lines or less. + func testTypeBodyLengths() { + for kind in ["class", "struct", "enum"] { + let longTypeBody = "\(kind) Abc {" + + join("", Array(count: 200, repeatedValue: "\n")) + + "}\n" + XCTAssertEqual(violations(longTypeBody), []) + let longerTypeBody = "\(kind) Abc {" + + join("", Array(count: 201, repeatedValue: "\n")) + + "}\n" + XCTAssertEqual(violations(longerTypeBody), [StyleViolation(type: .Length, + location: Location(file: nil, line: 1), + reason: "Type body should be span 200 lines or less: currently spans 201 lines")]) + } } func testNesting() {