Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/domains/commits/tokens/SquashMarkerToken.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ describe("in the default configuration", () => {
${"squash the bugs"} | ${["squash the bugs"]}
${"Squash tennis and pumpkins"} | ${["Squash tennis and pumpkins"]}
${"!!!amend!!!this"} | ${["!!!amend!!!this"]}
${"Done!"} | ${["Done!"]}
${"let's go!!"} | ${["let's go!!"]}
${"amend!"} | ${[squashMarker("amend!")]}
${" amend!Apply strawberry jam to make the code sweeter"} | ${[squashMarker(" amend!"), "Apply strawberry jam to make the code sweeter"]}
${" fixup! "} | ${[squashMarker(" fixup! ")]}
Expand Down
179 changes: 179 additions & 0 deletions src/domains/rules/NoSquashMarkers.tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { describe, expect, it } from "vitest"
import { fakeCommit } from "#commits/Commit.fixtures.ts"
import type { Commit } from "#commits/Commit.ts"
import type { RuleKey, RuleOptionsOf } from "#configurations/Configuration.ts"
import type { Concerns } from "#rules/concerns/Concern.ts"
import { subjectLineConcern } from "#rules/concerns/SubjectLineConcern.ts"
import { noSquashMarkers } from "#rules/NoSquashMarkers.ts"
import type { CharacterRange } from "#types/CharacterRange.ts"
import type { Vector } from "#types/Vector.ts"

const rule: RuleKey = "noSquashMarkers"

const enabled: RuleOptionsOf<typeof noSquashMarkers> = {}
const disabled: RuleOptionsOf<typeof noSquashMarkers> = null

describe.each`
subjectLine | expectedRange
${"fixup!"} | ${[0, 6]}
${"amend! Resolve a bug that thought it was a feature"} | ${[0, 6]}
${"squash! make the program act like a clown"} | ${[0, 7]}
${" Fixup! Added some extra love to the code"} | ${[1, 7]}
${"amend!Solved the problem"} | ${[0, 6]}
${" squash! organise the bookshelf"} | ${[3, 10]}
${'!fixup Revert "Bugfix"'} | ${[0, 6]}
${"!amend Wonder if this will work?"} | ${[0, 6]}
${"!SqUaSh retrieve data from third-party service"} | ${[0, 7]}
${"fixup!! another attempt"} | ${[0, 7]}
${"amend!! Update the documentation"} | ${[0, 7]}
${" squash!!! make changes"} | ${[1, 10]}
`(
"when the subject line of $subjectLine starts with a single squash marker",
(props: { subjectLine: string; expectedRange: CharacterRange }) => {
const commit = fakeCommit({ message: props.subjectLine })

describe("and the rule is enabled", () => {
it("raises a concern about the squash marker", () => {
const actualConcerns = noSquashMarkers([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([
subjectLineConcern(rule, commit.sha, { range: props.expectedRange }),
])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
},
)

describe.each`
subjectLine | expectedRange
${"squash!amend!"} | ${[0, 13]}
${"fixup! FIXUP!! Enforce the linting rules"} | ${[0, 14]}
${" squash! amend! fixup! long polling"} | ${[1, 26]}
`(
"when the subject line of $subjectLine starts with multiple squash markers",
(props: { subjectLine: string; expectedRange: CharacterRange }) => {
const commit = fakeCommit({ message: props.subjectLine })

describe("and the rule is enabled", () => {
it("raises a concern about all squash markers", () => {
const actualConcerns = noSquashMarkers([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([
subjectLineConcern(rule, commit.sha, { range: props.expectedRange }),
])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
},
)

describe.each`
subjectLine
${""}
${" "}
${"\t\t"}
${"Refactor the taxi module"}
${" Unsubscribe from the service"}
${"Formatting."}
${"WIP"}
${"Fix the bug"}
${"Update the documentation"}
${"Add new feature"}
${"Make the commit scream fixup! again"}
${"there's no squash! to see here"}
${"All done!"}
${"#7044: Solve the problem"}
${'Revert "Release the robot butler"'}
${" Hunt down the bugs "}
${"Compare the list of items to the objects downloaded from the server"}
${"Resolve issues in #21 to make the code work better"}
${"Finally..."}
${"Let `SoftIceMachineAdapter` produce the goods that we need"}
${"fixup the code"}
${"squash the commits"}
${"amend the message"}
`(
"when the subject line of $subjectLine does not contain a squash marker",
(props: { subjectLine: string }) => {
const commit = fakeCommit({ message: props.subjectLine })

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
},
)

describe("when verifying a set of multiple commits and some commits have squash markers", () => {
const commits: Vector<Commit, 7> = [
fakeCommit({ message: "fixup! resolve a bug that thought it was a feature" }),
fakeCommit({ message: "Squash! Make the program act like a clown" }),
fakeCommit({ message: "Refactor the taxi module" }),
fakeCommit({ message: "WIP" }),
fakeCommit({ message: " amend! update the code" }),
fakeCommit({ message: " Unsubscribe from the service" }),
fakeCommit({ message: "Fix the bug" }),
]

describe("and the rule is enabled", () => {
it("raises concerns about the commits with squash markers", () => {
const actualConcerns = noSquashMarkers(commits, enabled)
expect(actualConcerns).toEqual<Concerns>([
subjectLineConcern(rule, commits[0].sha, { range: [0, 6] }),
subjectLineConcern(rule, commits[1].sha, { range: [0, 7] }),
subjectLineConcern(rule, commits[4].sha, { range: [1, 7] }),
])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers(commits, disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
})

describe("when verifying a set of multiple commits and no commits have squash markers", () => {
const commits: Vector<Commit, 5> = [
fakeCommit({ message: "let's go!!" }),
fakeCommit({ message: "squash the bugs" }),
fakeCommit({ message: 'Revert "Bugfix"' }),
fakeCommit({ message: "Make the commit scream fixup! again" }),
fakeCommit({ message: "1 2 3 this is a test" }),
]

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers(commits, enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = noSquashMarkers(commits, disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
})
29 changes: 25 additions & 4 deletions src/domains/rules/NoSquashMarkers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
import type { Commits } from "#commits/Commit.ts"
import type { Concerns } from "#rules/concerns/Concern.ts"
import type { Commit, Commits } from "#commits/Commit.ts"
import { isSquashMarker } from "#commits/tokens/SquashMarkerToken.ts"
import type { RuleKey } from "#configurations/Configuration.ts"
import type { Concern, Concerns } from "#rules/concerns/Concern.ts"
import { subjectLineConcern } from "#rules/concerns/SubjectLineConcern.ts"
import type { EmptyObject } from "#types/EmptyObject.ts"
import { notNullish } from "#utilities/Arrays.ts"

export function noSquashMarkers(_commits: Commits, _configuration: EmptyObject | null): Concerns {
throw new Error("The `noSquashMarkers` rule has not been implemented yet") // TODO: To be implemented.
const rule: RuleKey = "noSquashMarkers"

export function noSquashMarkers(commits: Commits, configuration: EmptyObject | null): Concerns {
return configuration !== null ? commits.map(verifyCommit).filter(notNullish) : []
}

function verifyCommit(commit: Commit): Concern | null {
const [firstToken] = commit.subjectLine

if (firstToken && isSquashMarker(firstToken)) {
const leadingWhitespaceOffset = firstToken.value.length - firstToken.value.trimStart().length
const trimmedTokenLength = firstToken.value.trim().length

return subjectLineConcern(rule, commit.sha, {
range: [leadingWhitespaceOffset, leadingWhitespaceOffset + trimmedTokenLength],
})
}

return null
}
29 changes: 16 additions & 13 deletions src/domains/rules/UseCapitalisedSubjectLines.tests.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest"
import { fakeCommit } from "#commits/Commit.fixtures.ts"
import type { Commit } from "#commits/Commit.ts"
import type { RuleKey } from "#configurations/Configuration.ts"
import type { RuleKey, RuleOptionsOf } from "#configurations/Configuration.ts"
import type { Concerns } from "#rules/concerns/Concern.ts"
import { subjectLineConcern } from "#rules/concerns/SubjectLineConcern.ts"
import { useCapitalisedSubjectLines } from "#rules/UseCapitalisedSubjectLines.ts"
Expand All @@ -10,6 +10,9 @@ import type { Vector } from "#types/Vector.ts"

const rule: RuleKey = "useCapitalisedSubjectLines"

const enabled: RuleOptionsOf<typeof useCapitalisedSubjectLines> = {}
const disabled: RuleOptionsOf<typeof useCapitalisedSubjectLines> = null

describe.each`
subjectLine | expectedRange
${"test"} | ${[0, 1]}
Expand All @@ -33,7 +36,7 @@ describe.each`

describe("and the rule is enabled", () => {
it("raises a concern about the first non-capitalised character", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], {})
const actualConcerns = useCapitalisedSubjectLines([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([
subjectLineConcern(rule, commit.sha, { range: props.expectedRange }),
])
Expand All @@ -42,7 +45,7 @@ describe.each`

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], null)
const actualConcerns = useCapitalisedSubjectLines([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand Down Expand Up @@ -72,14 +75,14 @@ describe.each`

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], {})
const actualConcerns = useCapitalisedSubjectLines([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], null)
const actualConcerns = useCapitalisedSubjectLines([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand All @@ -101,14 +104,14 @@ describe.each`

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], {})
const actualConcerns = useCapitalisedSubjectLines([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], null)
const actualConcerns = useCapitalisedSubjectLines([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand All @@ -127,14 +130,14 @@ describe.each`

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], {})
const actualConcerns = useCapitalisedSubjectLines([commit], enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines([commit], null)
const actualConcerns = useCapitalisedSubjectLines([commit], disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand All @@ -155,7 +158,7 @@ describe("when verifying a set of multiple commits and some commits have non-cap

describe("and the rule is enabled", () => {
it("raises concerns about the commits with non-capitalised subject lines", () => {
const actualConcerns = useCapitalisedSubjectLines(commits, {})
const actualConcerns = useCapitalisedSubjectLines(commits, enabled)
expect(actualConcerns).toEqual<Concerns>([
subjectLineConcern(rule, commits[0].sha, { range: [0, 1] }),
subjectLineConcern(rule, commits[3].sha, { range: [0, 1] }),
Expand All @@ -166,7 +169,7 @@ describe("when verifying a set of multiple commits and some commits have non-cap

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines(commits, null)
const actualConcerns = useCapitalisedSubjectLines(commits, disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand All @@ -182,14 +185,14 @@ describe("when verifying a set of multiple commits and all commits have capitali

describe("and the rule is enabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines(commits, {})
const actualConcerns = useCapitalisedSubjectLines(commits, enabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})

describe("and the rule is disabled", () => {
it("does not raise any concerns", () => {
const actualConcerns = useCapitalisedSubjectLines(commits, null)
const actualConcerns = useCapitalisedSubjectLines(commits, disabled)
expect(actualConcerns).toEqual<Concerns>([])
})
})
Expand Down
4 changes: 3 additions & 1 deletion src/domains/rules/UseCapitalisedSubjectLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ function verifyCommit(commit: Commit): Concern | null {
const leadingWhitespaceOffset = token.length - trimmedToken.length
const startIndex = index + leadingWhitespaceOffset

return subjectLineConcern(rule, commit.sha, { range: [startIndex, startIndex + 1] })
return subjectLineConcern(rule, commit.sha, {
range: [startIndex, startIndex + 1],
})
}

return null
Expand Down
Loading
Loading