Skip to content

Commit a3ac52c

Browse files
FetzLuis Silva
authored and
Luis Silva
committed
feat(config-conventional): footer/body-max-line
update config-conventional with all the configurations add footer and body max line length rule with the value 100 add tests to all the rules of config-conventional
1 parent 9d14792 commit a3ac52c

File tree

5 files changed

+313
-0
lines changed

5 files changed

+313
-0
lines changed

@commitlint/config-conventional/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Consult [docs/rules](https://conventional-changelog.github.io/commitlint/#/refer
2424

2525
- **condition**: `type` is found in value
2626
- **rule**: `always`
27+
- **level**: `error`
2728
- **value**
2829

2930
```
@@ -51,6 +52,7 @@ echo "fix: some message" # passes
5152

5253
- **description**: `type` is in case `value`
5354
- **rule**: `always`
55+
- **level**: `error`
5456
- **value**
5557
```
5658
'lowerCase'
@@ -65,6 +67,7 @@ echo "fix: some message" # passes
6567

6668
- **condition**: `type` is empty
6769
- **rule**: `never`
70+
- **level**: `error`
6871

6972
```sh
7073
echo ": some message" # fails
@@ -75,6 +78,7 @@ echo "fix: some message" # passes
7578

7679
- **condition**: `scope` is in case `value`
7780
- **rule**: `always`
81+
- **level**: `error`
7882

7983
```
8084
'lowerCase'
@@ -89,6 +93,7 @@ echo "fix(scope): some message" # passes
8993

9094
- **condition**: `subject` is in one of the cases `['sentence-case', 'start-case', 'pascal-case', 'upper-case']`
9195
- **rule**: `never`
96+
- **level**: `error`
9297

9398
```sh
9499
echo "fix(SCOPE): Some message" # fails
@@ -103,6 +108,7 @@ echo "fix(scope): some Message" # passes
103108

104109
- **condition**: `subject` is empty
105110
- **rule**: `never`
111+
- **level**: `error`
106112

107113
```sh
108114
echo "fix:" # fails
@@ -113,6 +119,7 @@ echo "fix: some message" # passes
113119

114120
- **condition**: `subject` ends with `value`
115121
- **rule**: `never`
122+
- **level**: `error`
116123
- **value**
117124

118125
```
@@ -128,6 +135,7 @@ echo "fix: some message" # passes
128135

129136
- **condition**: `header` has `value` or less characters
130137
- **rule**: `always`
138+
- **level**: `error`
131139
- **value**
132140

133141
```
@@ -138,3 +146,82 @@ echo "fix: some message" # passes
138146
echo "fix: some message that is way too long and breaks the line max-length by several characters" # fails
139147
echo "fix: some message" # passes
140148
```
149+
150+
#### footer-leading-blank
151+
* **condition**: `footer` should have a leading blank line
152+
* **rule**: `always`
153+
* level: `warning`
154+
* **value**
155+
```
156+
100
157+
```
158+
159+
```sh
160+
echo "fix: some message
161+
BREAKING CHANGE: It will be significant" # warning
162+
163+
echo "fix: some message
164+
165+
BREAKING CHANGE: It will be significant" # passes
166+
```
167+
168+
#### footer-max-line-length
169+
* **condition**: `footer` each line has `value` or less characters
170+
* **rule**: `always`
171+
* level: `error`
172+
* **value**
173+
```
174+
100
175+
```
176+
177+
```sh
178+
echo "fix: some message
179+
180+
BREAKING CHANGE: footer with multiple lines
181+
has a message that is way too long and will break the line rule 'line-max-length' by several characters" # fails
182+
183+
echo "fix: some message
184+
185+
BREAKING CHANGE: footer with multiple lines
186+
but still no line is too long" # passes
187+
```
188+
189+
#### body-leading-blank
190+
* **condition**: `body` should have a leading blank line
191+
* **rule**: `always`
192+
* level: `warning`
193+
* **value**
194+
```js
195+
100
196+
```
197+
198+
```sh
199+
echo "fix: some message
200+
body" # warning
201+
202+
echo "fix: some message
203+
204+
body" # passes
205+
```
206+
207+
#### body-max-line-length
208+
* **condition**: `body` each line has `value` or less characters
209+
* **rule**: `always`
210+
* level: `error`
211+
* **value**
212+
```js
213+
100
214+
```
215+
216+
```sh
217+
echo "fix: some message
218+
219+
body with multiple lines
220+
has a message that is way too long and will break the line rule 'line-max-length' by several characters" # fails
221+
222+
echo "fix: some message
223+
224+
body with multiple lines
225+
but still no line is too long" # passes
226+
```
227+

@commitlint/config-conventional/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ module.exports = {
22
parserPreset: 'conventional-changelog-conventionalcommits',
33
rules: {
44
'body-leading-blank': [1, 'always'],
5+
'body-max-line-length': [2, 'always', 100],
56
'footer-leading-blank': [1, 'always'],
7+
'footer-max-line-length': [2, 'always', 100],
68
'header-max-length': [2, 'always', 100],
79
'scope-case': [2, 'always', 'lower-case'],
810
'subject-case': [
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import lint from '@commitlint/lint';
2+
import {rules} from '.';
3+
4+
const messages = {
5+
invalidTypeEnum: 'foo: some message',
6+
invalidTypeCase: 'FIX: some message',
7+
invalidTypeEmpty: ': some message',
8+
invalidScopeCase: 'fix(SCOPE): some message',
9+
invalidSubjectCases: [
10+
'fix(scope): Some message',
11+
'fix(scope): Some Message',
12+
'fix(scope): SomeMessage',
13+
'fix(scope): SOMEMESSAGE'
14+
],
15+
invalidSubjectEmpty: 'fix:',
16+
invalidSubjectFullStop: 'fix: some message.',
17+
invalidHeaderMaxLength:
18+
'fix: some message that is way too long and breaks the line max-length by several characters since the max is 100',
19+
warningFooterLeadingBlank:
20+
'fix: some message\n\nbody\nBREAKING CHANGE: It will be significant',
21+
invalidFooterMaxLineLength:
22+
'fix: some message\n\nbody\n\nBREAKING CHANGE: footer with multiple lines\nhas a message that is way too long and will break the line rule "line-max-length" by several characters',
23+
warningBodyLeadingBlank: 'fix: some message\nbody',
24+
invalidBodyMaxLineLength:
25+
'fix: some message\n\nbody with multiple lines\nhas a message that is way too long and will break the line rule "line-max-length" by several characters',
26+
validMessages: [
27+
'fix: some message',
28+
'fix(scope): some message',
29+
'fix(scope): some Message',
30+
'fix(scope): some message\n\nBREAKING CHANGE: it will be significant!',
31+
'fix(scope): some message\n\nbody'
32+
]
33+
};
34+
35+
const errors = {
36+
typeEnum: {
37+
level: 2,
38+
message:
39+
'type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]',
40+
name: 'type-enum',
41+
valid: false
42+
},
43+
typeCase: {
44+
level: 2,
45+
message: 'type must be lower-case',
46+
name: 'type-case',
47+
valid: false
48+
},
49+
typeEmpty: {
50+
level: 2,
51+
message: 'type may not be empty',
52+
name: 'type-empty',
53+
valid: false
54+
},
55+
scopeCase: {
56+
level: 2,
57+
message: 'scope must be lower-case',
58+
name: 'scope-case',
59+
valid: false
60+
},
61+
subjectCase: {
62+
level: 2,
63+
message:
64+
'subject must not be sentence-case, start-case, pascal-case, upper-case',
65+
name: 'subject-case',
66+
valid: false
67+
},
68+
subjectEmpty: {
69+
level: 2,
70+
message: 'subject may not be empty',
71+
name: 'subject-empty',
72+
valid: false
73+
},
74+
subjectFullStop: {
75+
level: 2,
76+
message: 'subject may not end with full stop',
77+
name: 'subject-full-stop',
78+
valid: false
79+
},
80+
headerMaxLength: {
81+
level: 2,
82+
message: 'header must not be longer than 100 characters, current length is 112',
83+
name: 'header-max-length',
84+
valid: false
85+
},
86+
footerMaxLineLength: {
87+
level: 2,
88+
message: "footer's lines must not be longer than 100 characters",
89+
name: 'footer-max-line-length',
90+
valid: false
91+
},
92+
bodyMaxLineLength: {
93+
level: 2,
94+
message: "body's lines must not be longer than 100 characters",
95+
name: 'body-max-line-length',
96+
valid: false
97+
}
98+
};
99+
100+
const warnings = {
101+
footerLeadingBlank: {
102+
level: 1,
103+
message: 'footer must have leading blank line',
104+
name: 'footer-leading-blank',
105+
valid: false
106+
},
107+
bodyLeadingBlank: {
108+
level: 1,
109+
message: 'body must have leading blank line',
110+
name: 'body-leading-blank',
111+
valid: false
112+
}
113+
};
114+
115+
test('type-enum', async () => {
116+
const result = await lint(messages.invalidTypeEnum, rules);
117+
118+
expect(result.valid).toBe(false);
119+
expect(result.errors).toEqual([errors.typeEnum]);
120+
});
121+
122+
test('type-case', async () => {
123+
const result = await lint(messages.invalidTypeCase, rules);
124+
125+
expect(result.valid).toBe(false);
126+
expect(result.errors).toEqual([errors.typeCase, errors.typeEnum]);
127+
});
128+
129+
test('type-empty', async () => {
130+
const result = await lint(messages.invalidTypeEmpty, rules);
131+
132+
expect(result.valid).toBe(false);
133+
expect(result.errors).toEqual([errors.typeEmpty]);
134+
});
135+
136+
test('scope-case', async () => {
137+
const result = await lint(messages.invalidScopeCase, rules);
138+
139+
expect(result.valid).toBe(false);
140+
expect(result.errors).toEqual([errors.scopeCase]);
141+
});
142+
143+
test('subject-case', async () => {
144+
const invalidInputs = await Promise.all(
145+
messages.invalidSubjectCases.map(invalidInput => lint(invalidInput, rules))
146+
);
147+
148+
invalidInputs.forEach(result => {
149+
expect(result.valid).toBe(false);
150+
expect(result.errors).toEqual([errors.subjectCase]);
151+
});
152+
});
153+
154+
test('subject-empty', async () => {
155+
const result = await lint(messages.invalidSubjectEmpty, rules);
156+
157+
expect(result.valid).toBe(false);
158+
expect(result.errors).toEqual([errors.subjectEmpty, errors.typeEmpty]);
159+
});
160+
161+
test('subject-full-stop', async () => {
162+
const result = await lint(messages.invalidSubjectFullStop, rules);
163+
164+
expect(result.valid).toBe(false);
165+
expect(result.errors).toEqual([errors.subjectFullStop]);
166+
});
167+
168+
test('header-max-length', async () => {
169+
const result = await lint(messages.invalidHeaderMaxLength, rules);
170+
171+
expect(result.valid).toBe(false);
172+
expect(result.errors).toEqual([errors.headerMaxLength]);
173+
});
174+
175+
test('footer-leading-blank', async () => {
176+
const result = await lint(messages.warningFooterLeadingBlank, rules);
177+
178+
expect(result.valid).toBe(true);
179+
expect(result.warnings).toEqual([warnings.footerLeadingBlank]);
180+
});
181+
182+
test('footer-max-line-length', async () => {
183+
const result = await lint(messages.invalidFooterMaxLineLength, rules);
184+
185+
expect(result.valid).toBe(false);
186+
expect(result.errors).toEqual([errors.footerMaxLineLength]);
187+
});
188+
189+
test('body-leading-blank', async () => {
190+
const result = await lint(messages.warningBodyLeadingBlank, rules);
191+
192+
expect(result.valid).toBe(true);
193+
expect(result.warnings).toEqual([warnings.bodyLeadingBlank]);
194+
});
195+
196+
test('body-max-line-length', async () => {
197+
const result = await lint(messages.invalidBodyMaxLineLength, rules);
198+
199+
expect(result.valid).toBe(false);
200+
expect(result.errors).toEqual([errors.bodyMaxLineLength]);
201+
});
202+
203+
test('valid messages', async () => {
204+
const validInputs = await Promise.all(
205+
messages.validMessages.map(input => lint(input, rules))
206+
);
207+
208+
validInputs.forEach(result => {
209+
expect(result.valid).toBe(true);
210+
expect(result.errors).toEqual([]);
211+
expect(result.warnings).toEqual([]);
212+
});
213+
});

@commitlint/config-conventional/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"node": ">=8"
3333
},
3434
"devDependencies": {
35+
"@commitlint/lint": "^8.3.4",
3536
"@commitlint/utils": "^8.3.4"
3637
},
3738
"dependencies": {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../../tsconfig.shared.json",
3+
"compilerOptions": {
4+
"composite": true,
5+
"rootDir": "./src",
6+
"outDir": "./lib"
7+
},
8+
"include": ["./**/*.ts"],
9+
"exclude": ["./**/*.test.ts"]
10+
}

0 commit comments

Comments
 (0)