1 |
|
2 | const fs = require('fs');
|
3 | const questions = require('../questions.js');
|
4 |
|
5 | describe('cz-customizable', () => {
|
6 | let config;
|
7 |
|
8 | beforeEach(() => {
|
9 | config = null;
|
10 | });
|
11 |
|
12 | const mockedCz = {
|
13 |
|
14 |
|
15 | Separator: jest.fn(),
|
16 |
|
17 | };
|
18 |
|
19 | const getQuestion = number => questions.getQuestions(config, mockedCz)[number - 1];
|
20 |
|
21 | it('should array of questions be returned', () => {
|
22 | config = {
|
23 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
24 | scopes: [{ name: 'myScope' }],
|
25 | scopeOverrides: {
|
26 | fix: [{ name: 'fixOverride' }],
|
27 | },
|
28 | allowCustomScopes: true,
|
29 | allowBreakingChanges: ['feat'],
|
30 | allowTicketNumber: true,
|
31 | isTicketNumberRequired: true,
|
32 | ticketNumberPrefix: 'TICKET-',
|
33 | ticketNumberRegExp: '\\d{1,5}',
|
34 | subjectLimit: 40,
|
35 | };
|
36 |
|
37 |
|
38 | expect(getQuestion(1).name).toEqual('type');
|
39 | expect(getQuestion(1).type).toEqual('list');
|
40 | expect(getQuestion(1).choices[0]).toEqual({
|
41 | value: 'feat',
|
42 | name: 'feat: my feat',
|
43 | });
|
44 |
|
45 |
|
46 | expect(getQuestion(2).name).toEqual('scope');
|
47 | expect(getQuestion(2).choices({})[0]).toEqual({ name: 'myScope' });
|
48 | expect(getQuestion(2).choices({ type: 'fix' })[0]).toEqual({
|
49 | name: 'fixOverride',
|
50 | });
|
51 | expect(getQuestion(2).when({ type: 'fix' })).toEqual(true);
|
52 | expect(getQuestion(2).when({ type: 'WIP' })).toEqual(false);
|
53 | expect(getQuestion(2).when({ type: 'wip' })).toEqual(false);
|
54 |
|
55 |
|
56 | expect(getQuestion(3).name).toEqual('scope');
|
57 | expect(getQuestion(3).when({ scope: 'custom' })).toEqual(true);
|
58 | expect(getQuestion(3).when({ scope: false })).toEqual(false);
|
59 | expect(getQuestion(3).when({ scope: 'scope' })).toEqual(false);
|
60 |
|
61 |
|
62 | expect(getQuestion(4).name).toEqual('ticketNumber');
|
63 | expect(getQuestion(4).type).toEqual('input');
|
64 | expect(getQuestion(4).message.indexOf('Enter the ticket number following this pattern')).toEqual(0);
|
65 | expect(getQuestion(4).validate()).toEqual(false);
|
66 |
|
67 |
|
68 | expect(getQuestion(5).name).toEqual('subject');
|
69 | expect(getQuestion(5).type).toEqual('input');
|
70 |
|
71 | expect(getQuestion(5).message).toMatch(/IMPERATIVE tense description/);
|
72 | expect(getQuestion(5).filter('Subject')).toEqual('subject');
|
73 | expect(getQuestion(5).validate('bad subject that exceed limit for 6 characters')).toEqual('Exceed limit: 40');
|
74 | expect(getQuestion(5).validate('good subject')).toEqual(true);
|
75 |
|
76 |
|
77 | expect(getQuestion(6).name).toEqual('body');
|
78 | expect(getQuestion(6).type).toEqual('input');
|
79 | expect(getQuestion(6).default).toEqual(null);
|
80 |
|
81 |
|
82 | expect(getQuestion(7).name).toEqual('breaking');
|
83 | expect(getQuestion(7).type).toEqual('input');
|
84 | expect(getQuestion(7).when({ type: 'feat' })).toEqual(true);
|
85 | expect(getQuestion(7).when({ type: 'fix' })).toEqual(false);
|
86 |
|
87 |
|
88 | expect(getQuestion(8).name).toEqual('footer');
|
89 | expect(getQuestion(8).type).toEqual('input');
|
90 | expect(getQuestion(8).when({ type: 'fix' })).toEqual(true);
|
91 | expect(getQuestion(8).when({ type: 'WIP' })).toEqual(false);
|
92 |
|
93 |
|
94 | expect(getQuestion(9).name).toEqual('confirmCommit');
|
95 | expect(getQuestion(9).type).toEqual('expand');
|
96 |
|
97 | const answers = {
|
98 | confirmCommit: 'yes',
|
99 | type: 'feat',
|
100 | scope: 'myScope',
|
101 | subject: 'create a new cool feature',
|
102 | };
|
103 | expect(getQuestion(9).message(answers)).toMatch('Are you sure you want to proceed with the commit above?');
|
104 | });
|
105 |
|
106 | it('default length limit of subject should be 100', () => {
|
107 | config = {
|
108 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
109 | };
|
110 | expect(getQuestion(5).validate('good subject')).toEqual(true);
|
111 | expect(
|
112 | getQuestion(5).validate(
|
113 | 'bad subject that exceed limit bad subject that exceed limitbad subject that exceed limit test test test'
|
114 | )
|
115 | ).toEqual('Exceed limit: 100');
|
116 | });
|
117 |
|
118 | it('subject should be lowercased by default', () => {
|
119 | config = {};
|
120 | expect(getQuestion(5).filter('Some subject')).toEqual('some subject');
|
121 | });
|
122 |
|
123 | it('subject should be capitilized when config property "upperCaseSubject" is set to true', () => {
|
124 | config = {
|
125 | upperCaseSubject: true,
|
126 | };
|
127 |
|
128 | expect(getQuestion(5).filter('some subject')).toEqual('Some subject');
|
129 | });
|
130 |
|
131 | describe('optional fixOverride and allowBreakingChanges', () => {
|
132 | it('should restrict BREAKING CHANGE question when config property "allowBreakingChanges" specifies array of types', () => {
|
133 | config = {
|
134 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
135 | scopes: [{ name: 'myScope' }],
|
136 | allowBreakingChanges: ['fix'],
|
137 | };
|
138 | expect(getQuestion(7).name).toEqual('breaking');
|
139 |
|
140 | const answers = {
|
141 | type: 'feat',
|
142 | };
|
143 |
|
144 | expect(getQuestion(7).when(answers)).toEqual(false);
|
145 | });
|
146 |
|
147 | it('should allow BREAKING CHANGE question when config property "allowBreakingChanges" specifies array of types and answer is one of those', () => {
|
148 | config = {
|
149 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
150 | scopes: [{ name: 'myScope' }],
|
151 | allowBreakingChanges: ['fix', 'feat'],
|
152 | };
|
153 | expect(getQuestion(7).name).toEqual('breaking');
|
154 |
|
155 | const answers = {
|
156 | type: 'feat',
|
157 | };
|
158 |
|
159 | expect(getQuestion(7).when(answers)).toEqual(true);
|
160 | });
|
161 | });
|
162 |
|
163 | describe('Optional scopes', () => {
|
164 | it('should use scope override', () => {
|
165 | config = {
|
166 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
167 | scopeOverrides: {
|
168 | feat: [{ name: 'myScope' }],
|
169 | },
|
170 | };
|
171 |
|
172 |
|
173 | expect(getQuestion(2).name).toEqual('scope');
|
174 | expect(getQuestion(2).choices({})[0]).toBeUndefined();
|
175 | expect(getQuestion(2).choices({ type: 'feat' })[0]).toEqual({
|
176 | name: 'myScope',
|
177 | });
|
178 | expect(getQuestion(2).when({ type: 'feat' })).toEqual(true);
|
179 |
|
180 | const answers = { type: 'fix' };
|
181 | expect(getQuestion(2).when(answers)).toEqual(false);
|
182 | expect(answers.scope).toEqual('custom');
|
183 | });
|
184 | });
|
185 |
|
186 | describe('no TicketNumber question', () => {
|
187 | it('should use scope override', () => {
|
188 | config = {
|
189 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
190 | allowTicketNumber: false,
|
191 | };
|
192 |
|
193 | expect(getQuestion(4).name).toEqual('ticketNumber');
|
194 | expect(getQuestion(4).when()).toEqual(false);
|
195 | });
|
196 | });
|
197 |
|
198 | describe('ask for breaking change first', () => {
|
199 | it('when config askForBreakingChangeFirst is true', () => {
|
200 | config = {
|
201 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
202 | askForBreakingChangeFirst: true,
|
203 | };
|
204 |
|
205 | expect(getQuestion(1).name).toEqual('breaking');
|
206 | expect(getQuestion(1).when()).toEqual(true);
|
207 | });
|
208 | });
|
209 |
|
210 | describe('TicketNumber', () => {
|
211 | it('disable TicketNumber question', () => {
|
212 | config = {
|
213 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
214 | allowTicketNumber: false,
|
215 | };
|
216 |
|
217 | expect(getQuestion(4).name).toEqual('ticketNumber');
|
218 | expect(getQuestion(4).when()).toEqual(false);
|
219 | });
|
220 |
|
221 | it('custom message defined', () => {
|
222 | config = {
|
223 | types: [{ value: 'feat', name: 'feat: my feat' }],
|
224 | allowTicketNumber: true,
|
225 | messages: {
|
226 | ticketNumber: 'ticket number',
|
227 | },
|
228 | };
|
229 |
|
230 | expect(getQuestion(4).name).toEqual('ticketNumber');
|
231 | expect(getQuestion(4).message).toEqual('ticket number');
|
232 | });
|
233 |
|
234 | describe('validation', () => {
|
235 | it('invalid because empty and required', () => {
|
236 | config = {
|
237 | isTicketNumberRequired: true,
|
238 | };
|
239 | expect(getQuestion(4).validate('')).toEqual(false);
|
240 | });
|
241 | it('empty but valid because optional', () => {
|
242 | config = {
|
243 | isTicketNumberRequired: false,
|
244 | };
|
245 | expect(getQuestion(4).validate('')).toEqual(true);
|
246 | });
|
247 | it('valid because there is no regexp defined', () => {
|
248 | config = {
|
249 | isTicketNumberRequired: true,
|
250 | ticketNumberRegExp: undefined,
|
251 | };
|
252 | expect(getQuestion(4).validate('21234')).toEqual(true);
|
253 | });
|
254 | it("invalid because regexp don't match", () => {
|
255 | config = {
|
256 | isTicketNumberRequired: true,
|
257 | ticketNumberRegExp: '\\d{1,5}',
|
258 | };
|
259 | expect(getQuestion(4).validate('sddsa')).toEqual(false);
|
260 | });
|
261 | it('valid because regexp match', () => {
|
262 | config = {
|
263 | isTicketNumberRequired: true,
|
264 | ticketNumberRegExp: '\\d{1,5}',
|
265 | };
|
266 | expect(getQuestion(4).validate('12345')).toEqual(true);
|
267 | });
|
268 | });
|
269 | });
|
270 |
|
271 | describe.skip('commit already prepared', () => {
|
272 | let existsSync;
|
273 | let readFileSync;
|
274 |
|
275 | beforeEach(() => {
|
276 | config = {};
|
277 | existsSync = spyOn(fs, 'existsSync');
|
278 | readFileSync = spyOn(fs, 'readFileSync');
|
279 | });
|
280 |
|
281 | it('should ignore if there is no prepared commit file', () => {
|
282 | existsSync.andReturn(false);
|
283 | expect(getQuestion(5).default).toEqual(null);
|
284 | expect(getQuestion(6).default).toEqual(null);
|
285 | });
|
286 |
|
287 | it('should ignore an empty prepared commit', () => {
|
288 | existsSync.andReturn(true);
|
289 | readFileSync.andReturn('');
|
290 | expect(getQuestion(5).default).toEqual(null);
|
291 | expect(getQuestion(6).default).toEqual(null);
|
292 | });
|
293 |
|
294 | it('should take a single line commit as the subject', () => {
|
295 | existsSync.andReturn(true);
|
296 | readFileSync.andReturn('my commit');
|
297 | expect(getQuestion(5).default).toEqual('my commit');
|
298 | expect(getQuestion(6).default).toEqual(null);
|
299 | });
|
300 |
|
301 | it('should split multi line commit between the subject and the body', () => {
|
302 | existsSync.andReturn(true);
|
303 | readFileSync.andReturn('my commit\nmessage\n\nis on several lines');
|
304 | expect(getQuestion(5).default).toEqual('my commit');
|
305 | expect(getQuestion(6).default).toEqual(`message|is on several lines`);
|
306 | });
|
307 | });
|
308 | });
|