Skip to content

Commit 46596a3

Browse files
committed
refactor: port parse to typescript
1 parent 6332d97 commit 46596a3

File tree

6 files changed

+99
-90
lines changed

6 files changed

+99
-90
lines changed

@commitlint/parse/package.json

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,13 @@
33
"version": "8.1.0",
44
"description": "Lint your commit messages",
55
"main": "lib/index.js",
6+
"types": "lib/index.d.ts",
67
"files": [
78
"lib/"
89
],
910
"scripts": {
10-
"build": "cross-env NODE_ENV=production babel src --out-dir lib --source-maps",
1111
"deps": "dep-check",
12-
"pkg": "pkg-check",
13-
"start": "concurrently \"ava -c 4 --verbose --watch\" \"yarn run watch\"",
14-
"test": "ava -c 4 --verbose",
15-
"watch": "babel src --out-dir lib --watch --source-maps"
16-
},
17-
"ava": {
18-
"files": [
19-
"src/**/*.test.js",
20-
"!lib/**/*"
21-
],
22-
"source": [
23-
"src/**/*.js",
24-
"!lib/**/*"
25-
],
26-
"babel": "inherit",
27-
"require": [
28-
"babel-register"
29-
]
30-
},
31-
"babel": {
32-
"presets": [
33-
"babel-preset-commitlint"
34-
]
12+
"pkg": "pkg-check"
3513
},
3614
"engines": {
3715
"node": ">=4"
@@ -58,13 +36,14 @@
5836
"devDependencies": {
5937
"@commitlint/test": "8.0.0",
6038
"@commitlint/utils": "^8.1.0",
61-
"ava": "0.22.0",
39+
"@types/lodash": "^4.14.136",
6240
"babel-cli": "6.26.0",
6341
"babel-preset-commitlint": "^8.0.0",
6442
"babel-register": "6.26.0",
6543
"concurrently": "3.6.1",
6644
"cross-env": "5.1.1",
67-
"import-from": "3.0.0"
45+
"import-from": "3.0.0",
46+
"typescript": "^3.5.3"
6847
},
6948
"dependencies": {
7049
"conventional-changelog-angular": "^1.3.3",
Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
import importFrom from 'import-from';
2-
import test from 'ava';
32
import parse from '.';
43

5-
test('throws when called without params', async t => {
6-
const error = await t.throws(parse());
7-
t.is(error.message, 'Expected a raw commit');
4+
test('throws when called without params', () => {
5+
expect(parse()).rejects.toThrowError('Expected a raw commit');
86
});
97

10-
test('throws when called with empty message', async t => {
11-
const error = await t.throws(parse());
12-
t.is(error.message, 'Expected a raw commit');
8+
test('throws when called with empty message', () => {
9+
expect(parse()).rejects.toThrowError('Expected a raw commit');
1310
});
1411

15-
test('returns object with raw message', async t => {
12+
test('returns object with raw message', async () => {
1613
const message = 'type(scope): subject';
1714
const actual = await parse(message);
18-
t.is(actual.raw, message);
15+
16+
expect(actual).toHaveProperty('raw', message);
1917
});
2018

21-
test('calls parser with message and passed options', async t => {
19+
test('calls parser with message and passed options', async () => {
2220
const message = 'message';
2321

24-
await parse(message, m => {
25-
t.is(message, m);
22+
expect.assertions(1);
23+
await parse(message, (m: string) => {
24+
expect(m).toBe(message);
2625
return {};
2726
});
2827
});
2928

30-
test('passes object up from parser function', async t => {
29+
test('passes object up from parser function', async () => {
3130
const message = 'message';
3231
const result = {};
3332
const actual = await parse(message, () => result);
34-
t.is(actual, result);
33+
34+
expect(actual).toBe(result);
3535
});
3636

37-
test('returns object with expected keys', async t => {
37+
test('returns object with expected keys', async () => {
3838
const message = 'message';
3939
const actual = await parse(message);
4040
const expected = {
@@ -51,10 +51,11 @@ test('returns object with expected keys', async t => {
5151
subject: null,
5252
type: null
5353
};
54-
t.deepEqual(actual, expected);
54+
55+
expect(actual).toMatchObject(expected);
5556
});
5657

57-
test('uses angular grammar', async t => {
58+
test('uses angular grammar', async () => {
5859
const message = 'type(scope): subject';
5960
const actual = await parse(message);
6061
const expected = {
@@ -71,14 +72,15 @@ test('uses angular grammar', async t => {
7172
subject: 'subject',
7273
type: 'type'
7374
};
74-
t.deepEqual(actual, expected);
75+
76+
expect(actual).toMatchObject(expected);
7577
});
7678

77-
test('uses custom opts parser', async t => {
79+
test('uses custom opts parser', async () => {
7880
const message = 'type(scope)-subject';
79-
const changelogOpts = await importFrom(
80-
process.cwd(),
81-
'./fixtures/parser-preset/conventional-changelog-custom'
81+
const changelogOpts: any = await importFrom(
82+
__dirname,
83+
'../fixtures/parser-preset/conventional-changelog-custom.js'
8284
);
8385
const actual = await parse(message, undefined, changelogOpts.parserOpts);
8486
const expected = {
@@ -95,10 +97,11 @@ test('uses custom opts parser', async t => {
9597
subject: 'subject',
9698
type: 'type'
9799
};
98-
t.deepEqual(actual, expected);
100+
101+
expect(actual).toMatchObject(expected);
99102
});
100103

101-
test('does not merge array properties with custom opts', async t => {
104+
test('does not merge array properties with custom opts', async () => {
102105
const message = 'type: subject';
103106
const actual = await parse(message, undefined, {
104107
headerPattern: /^(.*):\s(.*)$/,
@@ -117,54 +120,59 @@ test('does not merge array properties with custom opts', async t => {
117120
subject: 'subject',
118121
type: 'type'
119122
};
120-
t.deepEqual(actual, expected);
123+
124+
expect(actual).toMatchObject(expected);
121125
});
122126

123-
test('supports scopes with /', async t => {
127+
test('supports scopes with /', async () => {
124128
const message = 'type(some/scope): subject';
125129
const actual = await parse(message);
126-
t.is(actual.scope, 'some/scope');
127-
t.is(actual.subject, 'subject');
130+
131+
expect(actual.scope).toBe('some/scope');
132+
expect(actual.subject).toBe('subject');
128133
});
129134

130-
test('supports scopes with / and empty parserOpts', async t => {
135+
test('supports scopes with / and empty parserOpts', async () => {
131136
const message = 'type(some/scope): subject';
132137
const actual = await parse(message, undefined, {});
133-
t.is(actual.scope, 'some/scope');
134-
t.is(actual.subject, 'subject');
138+
139+
expect(actual.scope).toBe('some/scope');
140+
expect(actual.subject).toBe('subject');
135141
});
136142

137-
test('ignores comments', async t => {
143+
test('ignores comments', async () => {
138144
const message = 'type(some/scope): subject\n# some comment';
139-
const changelogOpts = await importFrom(
145+
const changelogOpts: any = await importFrom(
140146
process.cwd(),
141147
'conventional-changelog-angular'
142148
);
143149
const opts = Object.assign({}, changelogOpts.parserOpts, {
144150
commentChar: '#'
145151
});
146152
const actual = await parse(message, undefined, opts);
147-
t.is(actual.body, null);
148-
t.is(actual.footer, null);
149-
t.is(actual.subject, 'subject');
153+
154+
expect(actual.body).toBe(null);
155+
expect(actual.footer).toBe(null);
156+
expect(actual.subject).toBe('subject');
150157
});
151158

152-
test('registers inline #', async t => {
159+
test('registers inline #', async () => {
153160
const message =
154161
'type(some/scope): subject #reference\n# some comment\nthings #reference';
155-
const changelogOpts = await importFrom(
162+
const changelogOpts: any = await importFrom(
156163
process.cwd(),
157164
'conventional-changelog-angular'
158165
);
159166
const opts = Object.assign({}, changelogOpts.parserOpts, {
160167
commentChar: '#'
161168
});
162169
const actual = await parse(message, undefined, opts);
163-
t.is(actual.subject, 'subject #reference');
164-
t.is(actual.body, 'things #reference');
170+
171+
expect(actual.subject).toBe('subject #reference');
172+
expect(actual.body).toBe('things #reference');
165173
});
166174

167-
test('parses references leading subject', async t => {
175+
test('parses references leading subject', async () => {
168176
const message = '#1 some subject';
169177
const opts = await importFrom(
170178
process.cwd(),
@@ -173,17 +181,18 @@ test('parses references leading subject', async t => {
173181
const {
174182
references: [actual]
175183
} = await parse(message, undefined, opts);
176-
t.is(actual.issue, '1');
184+
185+
expect(actual.issue).toBe('1');
177186
});
178187

179-
test('parses custom references', async t => {
188+
test('parses custom references', async () => {
180189
const message = '#1 some subject PREFIX-2';
181190
const {references} = await parse(message, undefined, {
182191
issuePrefixes: ['PREFIX-']
183192
});
184193

185-
t.falsy(references.find(ref => ref.issue === '1'));
186-
t.deepEqual(references.find(ref => ref.issue === '2'), {
194+
expect(references.find((ref: any) => ref.issue === '1')).toBeFalsy();
195+
expect(references.find((ref: any) => ref.issue === '2')).toMatchObject({
187196
action: null,
188197
issue: '2',
189198
owner: null,
@@ -193,44 +202,44 @@ test('parses custom references', async t => {
193202
});
194203
});
195204

196-
test('uses permissive default regex without parser opts', async t => {
205+
test('uses permissive default regex without parser opts', async () => {
197206
const message = 'chore(component,demo): bump';
198207
const actual = await parse(message);
199208

200-
t.is(actual.scope, 'component,demo');
209+
expect(actual.scope).toBe('component,demo');
201210
});
202211

203-
test('uses permissive default regex with other parser opts', async t => {
212+
test('uses permissive default regex with other parser opts', async () => {
204213
const message = 'chore(component,demo): bump';
205214
const actual = await parse(message, undefined, {commentChar: '#'});
206215

207-
t.is(actual.scope, 'component,demo');
216+
expect(actual.scope).toBe('component,demo');
208217
});
209218

210-
test('uses restrictive default regex in passed parser opts', async t => {
219+
test('uses restrictive default regex in passed parser opts', async () => {
211220
const message = 'chore(component,demo): bump';
212221
const actual = await parse(message, undefined, {
213222
headerPattern: /^(\w*)(?:\(([a-z]*)\))?: (.*)$/
214223
});
215224

216-
t.is(actual.subject, null);
217-
t.is(actual.scope, null);
225+
expect(actual.subject).toBe(null);
226+
expect(actual.scope).toBe(null);
218227
});
219228

220-
test('works with chinese scope by default', async t => {
229+
test('works with chinese scope by default', async () => {
221230
const message = 'fix(面试评价): 测试';
222231
const actual = await parse(message, undefined, {commentChar: '#'});
223232

224-
t.not(actual.subject, null);
225-
t.not(actual.scope, null);
233+
expect(actual.subject).not.toBe(null);
234+
expect(actual.scope).not.toBe(null);
226235
});
227236

228-
test('does not work with chinese scopes with incompatible pattern', async t => {
237+
test('does not work with chinese scopes with incompatible pattern', async () => {
229238
const message = 'fix(面试评价): 测试';
230239
const actual = await parse(message, undefined, {
231240
headerPattern: /^(\w*)(?:\(([a-z]*)\))?: (.*)$/
232241
});
233242

234-
t.is(actual.subject, null);
235-
t.is(actual.scope, null);
243+
expect(actual.subject).toBe(null);
244+
expect(actual.scope).toBe(null);
236245
});

@commitlint/parse/src/index.js renamed to @commitlint/parse/src/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
import {sync} from 'conventional-commits-parser';
2-
import defaultChangelogOpts from 'conventional-changelog-angular';
31
import {isArray, mergeWith} from 'lodash';
42

3+
const {sync} = require('conventional-commits-parser');
4+
const defaultChangelogOpts = require('conventional-changelog-angular');
5+
56
export default parse;
67

7-
async function parse(message, parser = sync, parserOpts = undefined) {
8+
async function parse(
9+
message?: any,
10+
parser: any = sync,
11+
parserOpts: any = undefined
12+
) {
813
const defaultOpts = (await defaultChangelogOpts).parserOpts;
914
const parsed = parser(
1015
message,

@commitlint/parse/tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"extends": "../../tsconfig.shared.json",
3+
"compilerOptions": {
4+
"composite": true,
5+
"rootDir": "./src",
6+
"outDir": "./lib"
7+
},
8+
"include": [
9+
"./src"
10+
],
11+
"exclude": [
12+
"./src/**/*.test.ts",
13+
"./lib/**/*"
14+
]
15+
}

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
{ "path": "@commitlint/execute-rule" },
88
{ "path": "@commitlint/format" },
99
{ "path": "@commitlint/is-ignored" },
10+
{ "path": "@commitlint/parse" },
1011
{ "path": "@commitlint/resolve-extends" },
1112
{ "path": "@commitlint/to-lines" },
1213
{ "path": "@commitlint/top-level" },
1314
]
14-
}
15+
}

yarn.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,7 @@
12851285
dependencies:
12861286
"@types/jest-diff" "*"
12871287

1288-
1288+
"@types/[email protected]", "@types/lodash@^4.14.136":
12891289
version "4.14.136"
12901290
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.136.tgz#413e85089046b865d960c9ff1d400e04c31ab60f"
12911291
integrity sha512-0GJhzBdvsW2RUccNHOBkabI8HZVdOXmXbXhuKlDEd5Vv12P7oAVGfomGp3Ne21o5D/qu1WmthlNKFaoZJJeErA==
@@ -10913,7 +10913,7 @@ typedarray@^0.0.6:
1091310913
resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
1091410914
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
1091510915

10916-
10916+
[email protected], typescript@^3.5.3:
1091710917
version "3.5.3"
1091810918
resolved "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
1091910919
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==

0 commit comments

Comments
 (0)