diff --git a/.github/workflows/gha_pull_request.yml b/.github/workflows/gha_pull_request.yml index 354e2c5..f09c040 100644 --- a/.github/workflows/gha_pull_request.yml +++ b/.github/workflows/gha_pull_request.yml @@ -11,7 +11,7 @@ jobs: steps: - uses: actions/checkout@v1 - run: npm install -g danger - - run: swift run danger-swift ci -c release + - run: swift run danger-swift ci -c release --id "Lint" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_SWIFT_GITHUB_TOKEN }} @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@v1 - run: npm install -g danger - run: swift test --enable-code-coverage - - run: swift run danger-swift ci -c release --dangerfile DangerfileCoverage.swift + - run: swift run danger-swift ci -c release --dangerfile DangerfileCoverage.swift --id "Coverage" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_SWIFT_GITHUB_TOKEN }} diff --git a/DangerfileCoverage.swift b/DangerfileCoverage.swift index d672089..3415c7c 100644 --- a/DangerfileCoverage.swift +++ b/DangerfileCoverage.swift @@ -5,7 +5,7 @@ import Foundation let danger = Danger() if FileManager.default.fileExists(atPath: ".build/debug/codecov") { - Coverage.spmCoverage(minimumCoverage: 60) + Coverage.spmCoverage(minimumCoverage: 70) } else { warn("Cannot find SPM code coverage report, please run `swift test --enable-code-coverage` before danger.") } diff --git a/Package.swift b/Package.swift index 02a6a0f..b4482bb 100644 --- a/Package.swift +++ b/Package.swift @@ -22,10 +22,7 @@ let package = Package( .target(name: "DangerSwiftCommitLint", dependencies: [.product(name: "Danger", package: "danger-swift")]), .testTarget( name: "DangerSwiftCommitLintTests", - dependencies: [ - "DangerSwiftCommitLint", - .product(name: "DangerFixtures", package: "danger-swift"), - ] + dependencies: ["DangerSwiftCommitLint"] ), ] ) diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/BodyEmptyLineCheck.swift b/Sources/DangerSwiftCommitLint/CommitChecker/BodyEmptyLineCheck.swift new file mode 100644 index 0000000..204ef3f --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/BodyEmptyLineCheck.swift @@ -0,0 +1,15 @@ +import Foundation + +struct BodyEmptyLineCheck: CommitChecker { + static var warningMessage = "Please separate commit message subject from body with newline." + + private let bodyLinesOfText: [String] + + init(message: CommitMessage) { + bodyLinesOfText = message.bodyLinesOfText + } + + var fail: Bool { + bodyLinesOfText.isEmpty ? false : bodyLinesOfText.first?.isEmpty == false + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/CommitChecker.swift b/Sources/DangerSwiftCommitLint/CommitChecker/CommitChecker.swift new file mode 100644 index 0000000..e54f76e --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/CommitChecker.swift @@ -0,0 +1,16 @@ +import Foundation + +protocol CommitChecker: Hashable { + static var warningMessage: String { get } + var fail: Bool { get } + + init(message: CommitMessage) + + static func fail(message: CommitMessage) -> Bool +} + +extension CommitChecker { + static func fail(message: CommitMessage) -> Bool { + Self(message: message).fail + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/CommitMessage.swift b/Sources/DangerSwiftCommitLint/CommitChecker/CommitMessage.swift new file mode 100644 index 0000000..6f14898 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/CommitMessage.swift @@ -0,0 +1,28 @@ +import Danger +import Foundation + +struct CommitMessage: Hashable { + /// First line of the commit message + let subject: String + /// Rest of the commit message + let bodyLinesOfText: [String] + // Commit SHA value + let sha: String + + init( + subject: String, + bodyLinesOfText: [String], + sha: String + ) { + self.subject = subject + self.bodyLinesOfText = bodyLinesOfText + self.sha = sha + } + + init(_ commit: GitHub.Commit) { + let commitMessageLines = commit.commit.message.components(separatedBy: .newlines) + subject = commitMessageLines.first ?? "" + bodyLinesOfText = Array(commitMessageLines.dropFirst()) + sha = commit.sha + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/SubjectCapCheck.swift b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectCapCheck.swift new file mode 100644 index 0000000..a17df85 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectCapCheck.swift @@ -0,0 +1,15 @@ +import Foundation + +struct SubjectCapCheck: CommitChecker { + static let warningMessage = "Please start commit message subject with capital letter." + + private let firstCharacter: Character? + + init(message: CommitMessage) { + firstCharacter = message.subject.first + } + + var fail: Bool { + firstCharacter?.isLowercase ?? false + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/SubjectLengthCheck.swift b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectLengthCheck.swift new file mode 100644 index 0000000..50f4517 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectLengthCheck.swift @@ -0,0 +1,26 @@ +import Foundation + +struct SubjectLengthCheck: CommitChecker { + private enum GeneratedSubjectPattern { + static let git = #"^Merge branch '.+' into "# + static let gitHub = #"^Merge pull request #\d+ from "# + } + + static let warningMessage = "Please limit commit message subject line to 50 characters." + + private let subject: String + + init(message: CommitMessage) { + subject = message.subject + } + + var fail: Bool { + subject.count > 50 && isMergeCommit == false + } +} + +private extension SubjectLengthCheck { + var isMergeCommit: Bool { + subject =~ GeneratedSubjectPattern.git || subject =~ GeneratedSubjectPattern.gitHub + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/SubjectPeriodCheck.swift b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectPeriodCheck.swift new file mode 100644 index 0000000..b6e2c96 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectPeriodCheck.swift @@ -0,0 +1,15 @@ +import Foundation + +struct SubjectPeriodCheck: CommitChecker { + static var warningMessage = "Please remove period from end of commit message subject line." + + private let subject: String + + init(message: CommitMessage) { + subject = message.subject + } + + var fail: Bool { + subject.last == "." + } +} diff --git a/Sources/DangerSwiftCommitLint/CommitChecker/SubjectWordCheck.swift b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectWordCheck.swift new file mode 100644 index 0000000..6c30f76 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/CommitChecker/SubjectWordCheck.swift @@ -0,0 +1,15 @@ +import Foundation + +struct SubjectWordCheck: CommitChecker { + static var warningMessage = "Please use more than one word in commit message." + + private let subject: String + + init(message: CommitMessage) { + subject = message.subject + } + + var fail: Bool { + subject.split(separator: " ").count < 2 + } +} diff --git a/Sources/DangerSwiftCommitLint/DangerSwiftCommitLint.swift b/Sources/DangerSwiftCommitLint/DangerSwiftCommitLint.swift index e225d34..d78cdb2 100644 --- a/Sources/DangerSwiftCommitLint/DangerSwiftCommitLint.swift +++ b/Sources/DangerSwiftCommitLint/DangerSwiftCommitLint.swift @@ -1,4 +1,4 @@ import Danger import Foundation -final class DangerSwiftCommitLint {} +public final class DangerSwiftCommitLint {} diff --git a/Sources/DangerSwiftCommitLint/Extensions/RegexHelper.swift b/Sources/DangerSwiftCommitLint/Extensions/RegexHelper.swift new file mode 100644 index 0000000..b929b79 --- /dev/null +++ b/Sources/DangerSwiftCommitLint/Extensions/RegexHelper.swift @@ -0,0 +1,33 @@ +import Foundation + +infix operator =~: RegularExpressionPrecedence +precedencegroup RegularExpressionPrecedence { + associativity: none + higherThan: AdditionPrecedence + lowerThan: MultiplicationPrecedence +} + +func =~ (input: String, regexPattern: String) -> Bool { + do { + return try RegexHelper(regexPattern).match(input) + } catch { + return false + } +} + +private struct RegexHelper { + private let regex: NSRegularExpression + + init(_ pattern: String) throws { + regex = try NSRegularExpression(pattern: pattern, options: []) + } + + func match(_ input: String) -> Bool { + regex.matches( + in: input, + options: [], + range: NSRange(location: 0, length: input.utf16.count) + ) + .count > 0 + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/BodyEmptyLineCheckTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/BodyEmptyLineCheckTests.swift new file mode 100644 index 0000000..b310e51 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/BodyEmptyLineCheckTests.swift @@ -0,0 +1,27 @@ +import Danger +@testable import DangerSwiftCommitLint +import XCTest + +final class BodyEmptyLineCheckTests: XCTestCase { + private let commitSubjectAndBody = CommitMessage(subject: "Title Test", bodyLinesOfText: ["", "Body Test"], sha: "Test SHA") + private let commitSubjectOnly = CommitMessage(subject: "Title Test", bodyLinesOfText: [], sha: "Test SHA") + private let commitNoNewline = CommitMessage(subject: "Title Test", bodyLinesOfText: ["Body Test"], sha: "Test SHA") + + func testSuccessCommitSubjectAndBody() { + let testSubject = BodyEmptyLineCheck(message: commitSubjectAndBody) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(BodyEmptyLineCheck.fail(message: commitSubjectAndBody)) + } + + func testSuccessSubjectOnly() { + let testSubject = BodyEmptyLineCheck(message: commitSubjectOnly) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(BodyEmptyLineCheck.fail(message: commitSubjectOnly)) + } + + func testFailureNoNewlineOnly() { + let testSubject = BodyEmptyLineCheck(message: commitNoNewline) + XCTAssertTrue(testSubject.fail) + XCTAssertTrue(BodyEmptyLineCheck.fail(message: commitNoNewline)) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/CommitMessageTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/CommitMessageTests.swift new file mode 100644 index 0000000..dc9aa62 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/CommitMessageTests.swift @@ -0,0 +1,20 @@ +import Danger +@testable import DangerSwiftCommitLint +import XCTest + +final class CommitMessageTests: XCTestCase { + func testInitializeWithDangerGitHubCommit() { + let commit = CommitParser.parseCommitJSON(with: commitMessageJSON) + let expectedCommitMessage = commit.commit.message.components(separatedBy: .newlines) + let testSubject = CommitMessage(commit) + XCTAssertEqual(testSubject.sha, commit.sha) + XCTAssertEqual( + [ + [testSubject.subject], + testSubject.bodyLinesOfText, + ] + .flatMap { $0 }, + expectedCommitMessage + ) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitJSONParser.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitJSONParser.swift new file mode 100644 index 0000000..d07e562 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitJSONParser.swift @@ -0,0 +1,11 @@ +import Danger +import Foundation + +enum CommitParser { + static func parseCommitJSON(with commitJSON: String) -> GitHub.Commit { + let data = Data(commitJSON.utf8) + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .custom(DateFormatter.dateFormatterHandler) + return try! decoder.decode(GitHub.Commit.self, from: data) // swiftlint:disable:this force_try + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitMessageJSON.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitMessageJSON.swift new file mode 100644 index 0000000..a55a325 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/Fixtures/CommitMessageJSON.swift @@ -0,0 +1,80 @@ +// swiftlint:disable line_length +let commitMessageJSON = """ +{ + "sha": "93ae30cf2aee4241c442fb3242543490998cffdb", + "commit": { + "author": { + "name": "Ash Furrow", + "email": "ash@ashfurrow.com", + "date": "2016-07-26T19:54:16Z" + }, + "committer": { + "name": "Ash Furrow", + "email": "ash@ashfurrow.com", + "date": "2016-07-26T19:55:00Z" + }, + "message": "[Xcode] Updates for compatibility with Xcode 7.3.1.\\n\\nTest only", + "tree": { + "sha": "fb6bc3fda2456c5ff0a4e8f307f24ee73f281fc1", + "url": "https://api.github.com/repos/artsy/eidolon/git/trees/fb6bc3fda2456c5ff0a4e8f307f24ee73f281fc1" + }, + "url": "https://api.github.com/repos/artsy/eidolon/git/commits/93ae30cf2aee4241c442fb3242543490998cffdb", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\\nVersion: GnuPG v1\\n\\niQEcBAABAgAGBQJXl8AUAAoJEAGZOscENF/tIA8H/Ri9VdHJAzfO1aAtnoQ5W8Kw\\n1yYd5BTVnr0nVw95qxBgoRbBLMUIKg0TOPQQa1h7hk6SO0py6 E4HSpCJQq97f8J\\nvgeiFHuyfcW/ePSS8WwJbIzTP3xkckvdZIPjXM1KtvzQ1vCoOrOwBxMqH2twoTQk\\nuGd5cgfsahUGHcwYA6B4vfkmAGLkOyFVjUzbgf1n T5CMbPVlbFgss3aEi8Ql81S\\ncNjtMGiUm9n3LUG5lMiwOC3898fpE8YYoAPy1CtLuwokGws3Tu9jMSnUCi2Al7KC\\nzWMpIS3L2WVoCdhiv2NbXxUDTban8ll KGdtzw3QLZ0AL5ZEkuKrxtDQGyimpaw=\\n=aGrl\\n-----END PGP SIGNATURE-----", + "payload": "tree fb6bc3fda2456c5ff0a4e8f307f24ee73f281fc1\\nparent 68c8db83776c1942145f530159a3fffddb812577\\nauthor AshFurrow 1469562856 -0400\\ncommitter Ash Furrow 1469562900 -0400\\n\\n[Xcode]Updates for compatibility with Xcode 7.3.1.\\n" + } + }, + "url": "https://api.github.com/repos/artsy/eidolon/commits/93ae30cf2aee4241c442fb3242543490998cffdb", + "html_url": "https://github.com/artsy/eidolon/commit/93ae30cf2aee4241c442fb3242543490998cffdb", + "comments_url": "https://api.github.com/repos/artsy/eidolon/commits/93ae30cf2aee4241c442fb3242543490998cffdb/comments", + "author": { + "login": "ashfurrow", + "id": 498212, + "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/ashfurrow", + "html_url": "https://github.com/ashfurrow", + "followers_url": "https://api.github.com/users/ashfurrow/followers", + "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", + "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", + "organizations_url": "https://api.github.com/users/ashfurrow/orgs", + "repos_url": "https://api.github.com/users/ashfurrow/repos", + "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", + "received_events_url": "https://api.github.com/users/ashfurrow/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "ashfurrow", + "id": 498212, + "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/ashfurrow", + "html_url": "https://github.com/ashfurrow", + "followers_url": "https://api.github.com/users/ashfurrow/followers", + "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", + "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", + "organizations_url": "https://api.github.com/users/ashfurrow/orgs", + "repos_url": "https://api.github.com/users/ashfurrow/repos", + "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", + "received_events_url": "https://api.github.com/users/ashfurrow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "68c8db83776c1942145f530159a3fffddb812577", + "url": "https://api.github.com/repos/artsy/eidolon/commits/68c8db83776c1942145f530159a3fffddb812577", + "html_url": "https://github.com/artsy/eidolon/commit/68c8db83776c1942145f530159a3fffddb812577" + } + ] +} +""" +// swiftlint:enable line_length diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectCapCheckTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectCapCheckTests.swift new file mode 100644 index 0000000..2b7d21f --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectCapCheckTests.swift @@ -0,0 +1,33 @@ +@testable import DangerSwiftCommitLint +import XCTest + +final class SubjectCapCheckTests: XCTestCase { + func testSuccess() { + let commitMessage = CommitMessage(subject: "Subject", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectCapCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectCapCheck.fail(message: commitMessage)) + } + + func testFailure() { + let commitMessage = CommitMessage(subject: "subject", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectCapCheck(message: commitMessage) + XCTAssertTrue(testSubject.fail) + XCTAssertTrue(SubjectCapCheck.fail(message: commitMessage)) + } + + func testSuccessWithNonLetterCharacters() { + let commitMessage = CommitMessage(subject: "[TEST-123] Subject", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectCapCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectCapCheck.fail(message: commitMessage)) + } + + /// Git generally disallows empty commit message, so subject should at least contain non empty text. This test case is only capturing a unlikely edge case. + func testEdgeCase() { + let commitMessage = CommitMessage(subject: "", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectCapCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectCapCheck.fail(message: commitMessage)) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectLengthCheckTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectLengthCheckTests.swift new file mode 100644 index 0000000..3c8b468 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectLengthCheckTests.swift @@ -0,0 +1,44 @@ +@testable import DangerSwiftCommitLint +import XCTest + +final class SubjectLengthCheckTests: XCTestCase { + func testSuccess() { + let commitMessage = CommitMessage(subject: "Valid title", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectLengthCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectLengthCheck.fail(message: commitMessage)) + } + + func testFailure() { + let commitMessage = CommitMessage( + subject: "This is a long git commit subject for testing purpose.", + bodyLinesOfText: [], + sha: "Test SHA" + ) + let testSubject = SubjectLengthCheck(message: commitMessage) + XCTAssertTrue(testSubject.fail) + XCTAssertTrue(SubjectLengthCheck.fail(message: commitMessage)) + } + + func testSuccessWithGitHubMergeCommit() { + let commitMessage = CommitMessage( + subject: "Merge pull request #123 from AppDifferentia/test-branching", + bodyLinesOfText: [], + sha: "Test SHA" + ) + let testSubject = SubjectLengthCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectLengthCheck.fail(message: commitMessage)) + } + + func testSuccessWithGitMergeCommit() { + let commitMessage = CommitMessage( + subject: "Merge branch 'master' into AppDifferentia/test-branching", + bodyLinesOfText: [], + sha: "Test SHA" + ) + let testSubject = SubjectLengthCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectLengthCheck.fail(message: commitMessage)) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectPeriodCheckTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectPeriodCheckTests.swift new file mode 100644 index 0000000..5079eeb --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectPeriodCheckTests.swift @@ -0,0 +1,18 @@ +@testable import DangerSwiftCommitLint +import XCTest + +final class SubjectPeriodCheckTests: XCTestCase { + func testSuccess() { + let commitMessage = CommitMessage(subject: "Test title without period at the end", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectPeriodCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectPeriodCheck.fail(message: commitMessage)) + } + + func testFailure() { + let commitMessage = CommitMessage(subject: "Test title with period at the end.", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectPeriodCheck(message: commitMessage) + XCTAssertTrue(testSubject.fail) + XCTAssertTrue(SubjectPeriodCheck.fail(message: commitMessage)) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectWorkCheckTests.swift b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectWorkCheckTests.swift new file mode 100644 index 0000000..e3fe224 --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/CommitChecker/SubjectWorkCheckTests.swift @@ -0,0 +1,18 @@ +@testable import DangerSwiftCommitLint +import XCTest + +final class SubjectWordCheckTests: XCTestCase { + func testSuccess() { + let commitMessage = CommitMessage(subject: "Test title more than one word", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectWordCheck(message: commitMessage) + XCTAssertFalse(testSubject.fail) + XCTAssertFalse(SubjectWordCheck.fail(message: commitMessage)) + } + + func testFailure() { + let commitMessage = CommitMessage(subject: "Failure", bodyLinesOfText: [], sha: "Test SHA") + let testSubject = SubjectWordCheck(message: commitMessage) + XCTAssertTrue(testSubject.fail) + XCTAssertTrue(SubjectWordCheck.fail(message: commitMessage)) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/Extensions/RegexHelperTests.swift b/Tests/DangerSwiftCommitLintTests/Extensions/RegexHelperTests.swift new file mode 100644 index 0000000..e51411f --- /dev/null +++ b/Tests/DangerSwiftCommitLintTests/Extensions/RegexHelperTests.swift @@ -0,0 +1,22 @@ +@testable import DangerSwiftCommitLint +import XCTest + +final class RegexHelperTests: XCTestCase { + private let pattern = #"((?:KEY|JIRA)-[0-9]+)"# + private let invalidPattern = #"((?\:KEY|JIRA)-[0-9]+)"# + + func testSuccessfullyMatch() { + XCTAssertTrue("Test Subject [KEY-123]" =~ pattern) + XCTAssertTrue("[JIRA-321] Test Subject" =~ pattern) + } + + func testFailedToMatch() { + XCTAssertFalse("Test Subject" =~ pattern) + XCTAssertFalse("Test Subject [TEST-123]" =~ pattern) + } + + func testInvalidPattern() { + XCTAssertFalse("Test Subject [KEY-123]" =~ invalidPattern) + XCTAssertFalse("[JIRA-321] Test Subject" =~ invalidPattern) + } +} diff --git a/Tests/DangerSwiftCommitLintTests/XCTestManifests.swift b/Tests/DangerSwiftCommitLintTests/XCTestManifests.swift index 4b735f8..508ce68 100644 --- a/Tests/DangerSwiftCommitLintTests/XCTestManifests.swift +++ b/Tests/DangerSwiftCommitLintTests/XCTestManifests.swift @@ -1,6 +1,26 @@ #if !canImport(ObjectiveC) import XCTest + extension BodyEmptyLineCheckTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__BodyEmptyLineCheckTests = [ + ("testFailureNoNewlineOnly", testFailureNoNewlineOnly), + ("testSuccessCommitSubjectAndBody", testSuccessCommitSubjectAndBody), + ("testSuccessSubjectOnly", testSuccessSubjectOnly), + ] + } + + extension CommitMessageTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__CommitMessageTests = [ + ("testInitializeWithDangerGitHubCommit", testInitializeWithDangerGitHubCommit), + ] + } + extension DangerSwiftCommitLintTests { // DO NOT MODIFY: This is autogenerated, use: // `swift test --generate-linuxmain` @@ -10,9 +30,71 @@ ] } + extension RegexHelperTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__RegexHelperTests = [ + ("testFailedToMatch", testFailedToMatch), + ("testInvalidPattern", testInvalidPattern), + ("testSuccessfullyMatch", testSuccessfullyMatch), + ] + } + + extension SubjectCapCheckTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__SubjectCapCheckTests = [ + ("testEdgeCase", testEdgeCase), + ("testFailure", testFailure), + ("testSuccess", testSuccess), + ("testSuccessWithNonLetterCharacters", testSuccessWithNonLetterCharacters), + ] + } + + extension SubjectLengthCheckTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__SubjectLengthCheckTests = [ + ("testFailure", testFailure), + ("testSuccess", testSuccess), + ("testSuccessWithGitHubMergeCommit", testSuccessWithGitHubMergeCommit), + ("testSuccessWithGitMergeCommit", testSuccessWithGitMergeCommit), + ] + } + + extension SubjectPeriodCheckTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__SubjectPeriodCheckTests = [ + ("testFailure", testFailure), + ("testSuccess", testSuccess), + ] + } + + extension SubjectWordCheckTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__SubjectWordCheckTests = [ + ("testFailure", testFailure), + ("testSuccess", testSuccess), + ] + } + public func __allTests() -> [XCTestCaseEntry] { [ + testCase(BodyEmptyLineCheckTests.__allTests__BodyEmptyLineCheckTests), + testCase(CommitMessageTests.__allTests__CommitMessageTests), testCase(DangerSwiftCommitLintTests.__allTests__DangerSwiftCommitLintTests), + testCase(RegexHelperTests.__allTests__RegexHelperTests), + testCase(SubjectCapCheckTests.__allTests__SubjectCapCheckTests), + testCase(SubjectLengthCheckTests.__allTests__SubjectLengthCheckTests), + testCase(SubjectPeriodCheckTests.__allTests__SubjectPeriodCheckTests), + testCase(SubjectWordCheckTests.__allTests__SubjectWordCheckTests), ] } #endif