Skip to content

Commit 745443e

Browse files
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 ed2dc7f commit 745443e

File tree

4 files changed

+325
-3
lines changed

4 files changed

+325
-3
lines changed

@commitlint/config-conventional/README.md

+87-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Consult [docs/rules](https://marionebl.github.io/commitlint/#/reference-rules) f
2727
#### type-enum
2828
* **condition**: `type` is found in value
2929
* **rule**: `always`
30+
* level: `error`
3031
* **value**
3132

3233
```js
@@ -53,6 +54,7 @@ echo "fix: some message" # passes
5354
#### type-case
5455
* **description**: `type` is in case `value`
5556
* **rule**: `always`
57+
* level: `error`
5658
* **value**
5759
```js
5860
'lowerCase'
@@ -66,6 +68,7 @@ echo "fix: some message" # passes
6668
#### type-empty
6769
* **condition**: `type` is empty
6870
* **rule**: `never`
71+
* level: `error`
6972

7073
```sh
7174
echo ": some message" # fails
@@ -75,6 +78,7 @@ echo "fix: some message" # passes
7578
#### scope-case
7679
* **condition**: `scope` is in case `value`
7780
* **rule**: `always`
81+
* level: `error`
7882
```js
7983
'lowerCase'
8084
```
@@ -87,6 +91,7 @@ echo "fix(scope): some message" # passes
8791
#### subject-case
8892
* **condition**: `subject` is in one of the cases `['sentence-case', 'start-case', 'pascal-case', 'upper-case']`
8993
* **rule**: `never`
94+
* level: `error`
9095

9196
```sh
9297
echo "fix(SCOPE): Some message" # fails
@@ -100,6 +105,7 @@ echo "fix(scope): some Message" # passes
100105
#### subject-empty
101106
* **condition**: `subject` is empty
102107
* **rule**: `never`
108+
* level: `error`
103109

104110
```sh
105111
echo "fix:" # fails
@@ -109,6 +115,7 @@ echo "fix: some message" # passes
109115
#### subject-full-stop
110116
* **condition**: `subject` ends with `value`
111117
* **rule**: `never`
118+
* level: `error`
112119
* **value**
113120
```js
114121
'.'
@@ -119,10 +126,10 @@ echo "fix: some message." # fails
119126
echo "fix: some message" # passes
120127
```
121128

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

@commitlint/config-conventional/index.js

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

0 commit comments

Comments
 (0)