import lint from './lint'; test('throws without params', async () => { const error = (lint as any)(); await expect(error).rejects.toThrow('Expected a raw commit'); }); test('positive on empty message', async () => { expect(await lint('')).toMatchObject({ valid: true, errors: [], warnings: [], }); }); test('positive on stub message and no rule', async () => { const actual = await lint('foo: bar'); expect(actual.valid).toBe(true); }); test('positive on stub message and adhered rule', async () => { const actual = await lint('foo: bar', { 'type-enum': [2, 'always', ['foo']], }); expect(actual.valid).toBe(true); }); test('negative on stub message and broken rule', async () => { const actual = await lint('foo: bar', { 'type-enum': [2, 'never', ['foo']], }); expect(actual.valid).toBe(false); }); test('positive on ignored message and broken rule', async () => { const actual = await lint('Revert "some bogus commit"', { 'type-empty': [2, 'never'], }); expect(actual.valid).toBe(true); expect(actual.input).toBe('Revert "some bogus commit"'); }); test('negative on ignored message, disabled ignored messages and broken rule', async () => { const actual = await lint( 'Revert "some bogus commit"', { 'type-empty': [2, 'never'], }, { defaultIgnores: false, } ); expect(actual.valid).toBe(false); }); test('positive on custom ignored message and broken rule', async () => { const ignoredMessage = 'some ignored custom message'; const actual = await lint( ignoredMessage, { 'type-empty': [2, 'never'], }, { ignores: [(c) => c === ignoredMessage], } ); expect(actual.valid).toBe(true); expect(actual.input).toBe(ignoredMessage); }); test('positive on stub message and opts', async () => { const actual = await lint( 'foo-bar', { 'type-enum': [2, 'always', ['foo']], 'type-empty': [2, 'never'], }, { parserOpts: { headerPattern: /^(\w*)(?:\((.*)\))?-(.*)$/, }, } ); expect(actual.valid).toBe(true); }); test('throws for invalid rule names', async () => { const error = lint('foo', {foo: [2, 'always'], bar: [1, 'never']}); await expect(error).rejects.toThrow(/^Found invalid rule names: foo, bar/); }); test('throws for invalid rule config', async () => { const error = lint('type(scope): foo', { 'type-enum': 1, 'scope-enum': {0: 2, 1: 'never', 2: ['foo'], length: 3}, } as any); await expect(error).rejects.toThrow('type-enum must be array'); await expect(error).rejects.toThrow('scope-enum must be array'); }); test('allows disable shorthand', async () => { const result = lint('foo', {'type-enum': [0], 'scope-enum': [0]}); await expect(result).resolves.toEqual({ errors: [], input: 'foo', valid: true, warnings: [], }); }); test('throws for rule with invalid length', async () => { const error = lint('type(scope): foo', {'scope-enum': [1, 2, 3, 4]} as any); await expect(error).rejects.toThrow('scope-enum must be 2 or 3 items long'); }); test('throws for rule with invalid level', async () => { const error = lint('type(scope): foo', { 'type-enum': ['2', 'always'] as any, 'header-max-length': [{}, 'always'] as any, }); await expect(error).rejects.toThrow('rule type-enum must be number'); await expect(error).rejects.toThrow('rule header-max-length must be number'); }); test('throws for rule with out of range level', async () => { const error = lint('type(scope): foo', { 'type-enum': [-1, 'always'] as any, 'header-max-length': [3, 'always'] as any, }); await expect(error).rejects.toThrow('rule type-enum must be between 0 and 2'); await expect(error).rejects.toThrow( 'rule header-max-length must be between 0 and 2' ); }); test('throws for rule with invalid condition', async () => { const error = lint('type(scope): foo', { 'type-enum': [1, 2] as any, 'header-max-length': [1, {}] as any, }); await expect(error).rejects.toThrow('type-enum must be string'); await expect(error).rejects.toThrow('header-max-length must be string'); }); test('throws for rule with out of range condition', async () => { const error = lint('type(scope): foo', { 'type-enum': [1, 'foo'] as any, 'header-max-length': [1, 'bar'] as any, }); await expect(error).rejects.toThrow('type-enum must be "always" or "never"'); await expect(error).rejects.toThrow( 'header-max-length must be "always" or "never"' ); }); test('succeds for issue', async () => { const report = await lint('somehting #1', { 'references-empty': [2, 'never'], }); expect(report.valid).toBe(true); }); test('fails for issue', async () => { const report = await lint('somehting #1', { 'references-empty': [2, 'always'], }); expect(report.valid).toBe(false); }); test('succeds for custom issue prefix', async () => { const report = await lint( 'somehting REF-1', { 'references-empty': [2, 'never'], }, { parserOpts: { issuePrefixes: ['REF-'], }, } ); expect(report.valid).toBe(true); }); test('fails for custom issue prefix', async () => { const report = await lint( 'somehting #1', { 'references-empty': [2, 'never'], }, { parserOpts: { issuePrefixes: ['REF-'], }, } ); expect(report.valid).toBe(false); }); test('fails for custom plugin rule', async () => { const report = await lint( 'somehting #1', { 'plugin-rule': [2, 'never'], }, { plugins: { 'plugin-example': { rules: { 'plugin-rule': () => [false], }, }, }, } ); expect(report.valid).toBe(false); }); test('passes for custom plugin rule', async () => { const report = await lint( 'somehting #1', { 'plugin-rule': [2, 'never'], }, { plugins: { 'plugin-example': { rules: { 'plugin-rule': () => [true], }, }, }, } ); expect(report.valid).toBe(true); }); test('returns original message only with commit header', async () => { const message = 'foo: bar'; const report = await lint(message); expect(report.input).toBe(message); }); test('returns original message with commit header and body', async () => { const message = 'foo: bar/n/nFoo bar bizz buzz.'; const report = await lint(message); expect(report.input).toBe(message); }); test('returns original message with commit header, body and footer', async () => { const message = 'foo: bar/n/nFoo bar bizz buzz./n/nCloses #1'; const report = await lint(message); expect(report.input).toBe(message); }); test('returns original message with commit header, body and footer, parsing comments', async () => { const expected = 'foo: bar/n/nFoo bar bizz buzz./n/nCloses #1'; const message = `${expected}\n\n# Some comment to ignore`; const report = await lint( message, { 'references-empty': [2, 'never'], }, { parserOpts: { commentChar: '#', }, } ); expect(report.input).toBe(expected); }); test('passes for async rule', async () => { const report = await lint( 'somehting #1', { 'async-rule': [2, 'never'], }, { plugins: { 'example-plugin': { rules: { 'async-rule': async () => [true, 'all good'] as const, }, }, }, } ); expect(report.valid).toBe(true); });