Skip to content

Commit

Permalink
feat(match): implemented support for RegExp
Browse files Browse the repository at this point in the history
  • Loading branch information
FGRibreau committed Dec 29, 2015
1 parent 1c30884 commit e18ecfc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,27 @@ const protocols = repositories.map(match({
}))
```


##### Regular Expressions

match-when supports [regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) as well:

```js
['hey.com', 'fg@plop.com', 'fg+plop@plop.com', 'wat'].filter(match({
[when(/\S+@\S+\.\S+/)]: false, // **seems** to be a valid email (unsafe regex for doc purpose only)
[when()]: true // the email could be invalid, return it
}));

// ['hey.com', 'wat']
```


### Supported patterns:


- `{ x1: pattern1, ..., xn: patternn }` - matches any object with property names `x1` to `xn` matching patterns `pattern1` to `patternn`, respectively. Only the own properties of the pattern are used.
- `[pattern0, ..., patternn]` - matches any object with property names 0 to n matching patterns `pattern0` to `patternn`, respectively.
- `/pattern/flags` - matches any values than pass the regular expression test
- `when.or(pattern0, pattern1, ...)` - matches if one `pattern` matches.

### Todo:
Expand Down
17 changes: 17 additions & 0 deletions match.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ const _patternORStr = _patternOR.toString(); // dirty hack
const _patternAND = Symbol('match.pattern.AND');
const _patternANDStr = _patternAND.toString(); // dirty hack

const _patternREGEXP = Symbol('match.pattern.REGEXP');
const _patternREGEXPStr = _patternREGEXP.toString(); // dirty hack
const EXTRACT_PATTERN_AND_FLAGS = /\/(.*)\/(.*)/;

function MissingCatchAllPattern() {
Error.call(this, 'Missing when() catch-all pattern as last match argument, add [when()]: void 0');
if (!('stack' in this)){
Expand Down Expand Up @@ -46,6 +50,10 @@ function when(props){
return _catchAllSymbol;
}

if(props instanceof RegExp){
return JSON.stringify([_patternREGEXP.toString(), props.toString()]);
}

return JSON.stringify(props);
}

Expand All @@ -68,6 +76,11 @@ function _match(props){
return props[0].every((prop) => _matching(prop, input));
};
}

if(props[0] === _patternREGEXPStr){
const res = EXTRACT_PATTERN_AND_FLAGS.exec(props[1]);
return _matching.bind(null, new RegExp(res[1], res[2]));
}
}

function _matching(props, input){
Expand All @@ -77,6 +90,10 @@ function _match(props){
return JSON.stringify(props) === JSON.stringify(input);
}

if(props instanceof RegExp){
return props.test(input);
}

if(typeof input === 'object'){
for(let prop in props){
if(input[prop] !== props[prop]){
Expand Down
19 changes: 19 additions & 0 deletions match.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ describe('match', () => {

t.strictEqual(length([1, 2, 3]), 3);
t.strictEqual(length([{}, {}, {}, {}]), 4);
});

it('should support regexp match', () => {
const output = [3, ' 2', 1, 'zEro', 90].map(match({
[when(/1/)]: 'one',
[when(/2/g)]: 'two',
[when(/3/)]: 'three',
[when(/zero/i)]: 'zero',
[when()]: v => v
}));

t.deepEqual(output, ['three', 'two', 'one', 'zero', 90]);

const invalidEmails = ['hey.com', 'fg@plop.com', 'fg+plop@plop.com', 'wat'].filter(match({
[when(/\S+@\S+\.\S+/)]: false, // **seems** to be a valid email
[when()]: true // the email may be invalid, return it
}));

t.deepEqual(invalidEmails, ['hey.com', 'wat']);
})

describe('when.and', () => {
Expand Down

0 comments on commit e18ecfc

Please sign in to comment.