Skip to content

Commit

Permalink
feat: allow to override preconfigured options
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdlg committed Jul 8, 2018
1 parent 44822e6 commit 7be9c89
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ issueParser('Issue description, ref group/user/package#1, !2, implement #3, /dup
### Bitbucket format

```js
const issueParser = require('issue-parser')
const issueParser = require('issue-parser');
const parse = issueParser('bitbucket');

issueParser('Issue description, ref user/package#1, fixing #2. /cc @user');
Expand All @@ -76,7 +76,7 @@ issueParser('Issue description, ref user/package#1, fixing #2. /cc @user');
### Custom format

```js
const issueParser = require('issue-parser')
const issueParser = require('issue-parser');
const parse = issueParser({referenceActions: ['complete'], issuePrefixes: ['🐛']});

issueParser('Issue description, related to user/package🐛1, Complete 🐛2');
Expand Down Expand Up @@ -266,7 +266,7 @@ Fix #1 Fix #2a Fix a#3

## API

### issueParser([options]) => parse
### issueParser([options], [overrides]) => parse

Create a [parser](#parsetext--result).

Expand Down Expand Up @@ -317,6 +317,17 @@ Default: `['issues', 'pull', 'merge_requests']`

List of URL segment used to identify issues and pull requests with [full URL](#parse-references-with-full-issue-url).

#### overrides

Type: `Object`<br>
Option overrides. Useful when using predefined [`options`](#options) (such as `github`, `gitlab` or `bitbucket`). The `overrides` object can define the same properties as [`options`](#options).

For example, the following will use all the `github` predefined options but with a different `hosts` option:
```js
const issueParser = require('issue-parser');
const parse = issueParser('github', {hosts: ['https://custom-url.com']});
```

### parse(text) => Result

Parse an issue description and returns a [Result](#result) object.
Expand Down
19 changes: 16 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,25 @@ function parse(text, regexp, mentionRegexp, {issuePrefixes, hosts, referenceActi
return results;
}

module.exports = options => {
if (options !== undefined && !isString(options) && !isPlainObject(options)) {
module.exports = (options = 'default', overrides = {}) => {
if (!isString(options) && !isPlainObject(options)) {
throw new TypeError('Options must be a String or an Object');
}

const opts = Object.assign({}, hostConfig.default, isString(options) ? hostConfig[options.toLowerCase()] : options);
if (isString(options) && !includesIgnoreCase(Object.keys(hostConfig), options)) {
throw new TypeError(`The supported configuration are [${Object.keys(hostConfig).join(', ')}], got '${options}'`);
}

if (!isPlainObject(overrides)) {
throw new TypeError('Override must be an Object');
}

const opts = Object.assign(
{},
hostConfig.default,
isString(options) ? hostConfig[options.toLowerCase()] : options,
overrides
);

for (const opt of Object.keys(opts)) {
if (isString(opts[opt])) {
Expand Down
39 changes: 39 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,35 @@ test('Parse with custom options', t => {
);
});

test('Parse with options overrides', t => {
t.deepEqual(
m('default', {
referenceActions: ['fix'],
duplicateActions: [],
mentionsPrefixes: '!',
issuePrefixes: ['#'],
hosts: ['http://host1.com/', 'http://host2.com'],
issueURLSegments: ['bugs'],
})(
'Fix #1 reSOLved gh-2 CLOSES Gh-3 fixed o/r#4 #5 o/r#6 fixing #7 http://host1.com/o/r/bugs/8 http://host2.com/o/r/bugs/9 Duplicate OF #10 !user @other'
),
{
actions: [{raw: 'Fix #1', action: 'Fix', slug: undefined, prefix: '#', issue: '1'}],
refs: [
{raw: 'o/r#4', slug: 'o/r', prefix: '#', issue: '4'},
{raw: '#5', slug: undefined, prefix: '#', issue: '5'},
{raw: 'o/r#6', slug: 'o/r', prefix: '#', issue: '6'},
{raw: '#7', slug: undefined, prefix: '#', issue: '7'},
{raw: 'http://host1.com/o/r/bugs/8', slug: 'o/r', prefix: undefined, issue: '8'},
{raw: 'http://host2.com/o/r/bugs/9', slug: 'o/r', prefix: undefined, issue: '9'},
{raw: '#10', slug: undefined, prefix: '#', issue: '10'},
],
duplicates: [],
mentions: [{raw: '!user', prefix: '!', user: 'user'}],
}
);
});

test('"allRefs" returns "refs", "actions" and "duplicates"', t => {
t.deepEqual(m('github')('Fix #1 #2 Duplicate of #3').allRefs, [
{raw: 'Fix #1', action: 'Fix', slug: undefined, prefix: '#', issue: '1'},
Expand Down Expand Up @@ -269,12 +298,22 @@ test('Empty String', t => {
});

test('Throw TypeError for invalid options', t => {
t.throws(() => m('missing-option'), TypeError);
t.throws(() => m([]), TypeError);
t.throws(() => m(1), TypeError);
t.throws(() => m({referenceActions: 1}), TypeError);
t.throws(() => m({referenceActions: [1]}), TypeError);
});

test('Throw TypeError for invalid overrides', t => {
t.throws(() => m({}, []), TypeError);
t.throws(() => m({}, 1), TypeError);
t.throws(() => m({}, {referenceActions: 1}), TypeError);
t.throws(() => m({}, {referenceActions: [1]}), TypeError);
t.throws(() => m({}, ''), TypeError);
t.throws(() => m({}, 'string'), TypeError);
});

test('Throw TypeError for invalid input', t => {
t.throws(() => m()(), TypeError);
t.throws(() => m()(1), TypeError);
Expand Down

0 comments on commit 7be9c89

Please sign in to comment.