aboutsummaryrefslogtreecommitdiff
path: root/node_modules/call-matcher/README.md
blob: b7ee0b28a526ac6a0dd53402aa895c1843538581 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
call-matcher
================================

ECMAScript CallExpression matcher made from function/method signature

[![Build Status][travis-image]][travis-url]
[![NPM version][npm-image]][npm-url]
[![Dependency Status][depstat-image]][depstat-url]
[![License][license-image]][license-url]


EXAMPLE
---------------------------------------

Creating CallExpression matcher for method signature `'assert.equal(actual, expected, [message])'`.

Then match against `path/to/some_test.js`.

```javascript
var CallMatcher = require('call-matcher');
var esprima = require('esprima');
var estraverse = require('estraverse');
var fs = require('fs');

var ast = esprima.parse('assert.equal(actual, expected, [message])');
var expression = ast.body[0].expression;
var matcher = new CallMatcher(expression);

estraverse.traverse(esprima.parse(fs.readFileSync('path/to/some_test.js')), {
    enter: function (currentNode, parentNode) {
        if (matcher.test(currentNode)) {
            // currentNode is a CallExpression that matches to the signature
        }
        var argMatched = matcher.matchArgument(currentNode, parentNode);
        if (argMatched) {
            if (argMatched.kind === 'mandatory') {
                // mandatory arg (in this case, `actual` or `expected`)
            } else if (argMatched.kind === 'optional') {
                // optional arg (in this case, `message`)
            }
        }
    }
});
```

where content of `path/to/some_test.js` is:

```javascript
var assert = require('assert');
var anotherAssert = assert;
var equal = assert.equal.bind(assert);
var foo = '2';
var bar = 2;

assert.equal(foo, bar);  // matches
assert.equal(bar, foo);  // matches
assert.equal(foo, bar, 'foo shoule be equal to bar');  // matches (with optional arg)

assert.equal();  // does not match (less args)
assert.equal(foo);  // does not match (less args)
assert.equal(foo, bar, 'hoge', 'fuga');  // does not match (too much args)

assert.notEqual(foo, bar);  // does not match (callee method name differs)
anotherAssert.equal(foo, bar);  // does not match (callee object name differs)
equal(foo, bar);  // does not match (callee does not match)
```

`call-matcher` is a spin-off product of [power-assert](https://github.com/twada/power-assert) project.

Pull-requests, issue reports and patches are always welcomed.


API
---------------------------------------

### var matcher = new CallMatcher(signatureAst, [options])

Create matcher object for a given expression.

```javascript
var ast = esprima.parse('assert.equal(actual, expected, [message])');
var expression = ast.body[0].expression;
var matcher = new CallMatcher(expression);
```

Any signature string enclosed in bracket (for example, `[message]`) means optional parameters. Without bracket means mandatory parameters.

Returns `matcher` object having four methods, `test`, `matchArgument`, `calleeAst`, and `argumentSignatures`.


#### options

an `object` for configuration options. If not passed, default options will be used.


#### options.visitorKeys

| type     | default value |
|:---------|:--------------|
| `object` | (return value of `estraverse.VisitorKeys`)   |

VisitorKeys for AST traversal. See [estraverse.VisitorKeys](https://github.com/estools/estraverse/blob/4.0.0/estraverse.js#L217-L288) and [babel.types.VISITOR_KEYS](https://github.com/babel/babel/blob/v5.1.11/src/babel/types/visitor-keys.json).


#### options.astWhiteList

| type     | default value |
|:---------|:--------------|
| `object` | N/A           |

Type and property whitelist on creating AST clone. `astWhiteList` is an object containing NodeType as keys and properties as values.

```js
{
    ArrayExpression: ['type', 'elements'],
    ArrayPattern: ['type', 'elements'],
    ArrowFunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'expression'],
    AssignmentExpression: ['type', 'operator', 'left', 'right'],
    ...
```


### var isMatched = matcher.test(node)

Tests whether `node` matches the signature or not.

 - Returns `true` if matched.
 - Returns `false` if not matched.

`node` should be an AST node object defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)).


### var argMatched = matcher.matchArgument(node, parentNode)

Returns match result object representing whether `node` (and its `parentNode`) matches some argument of the signature or not.

 - Returns `null` if not matched.
 - If matched, returns object like `{name: 'actual', kind: 'mandatory'}`, whose `name` is an argument name in the signature and `kind` is `'mandatory'` or `'optional'`.

`node` and `parentNode` should be AST node objects defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)).


### var calleeAst = matcher.calleeAst()

Returns clone of callee AST object based on signature passed to `CallMatcher` function. Returned tree is one of AST node objects defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)) (in most cases, `Identifier` or `MemberExpression`).


### var argSigs = matcher.argumentSignatures()

Returns array of argument signature objects based on signature passed to `CallMatcher` function. Returns array of objects like `[{name: 'actual', kind: 'mandatory'}]`, whose `name` is an argument name in the signature and `kind` is `'mandatory'` or `'optional'`.



INSTALL
---------------------------------------

### via npm

Install

    $ npm install --save call-matcher


#### use call-matcher module on browser

`CallMatcher` function is exported

    <script type="text/javascript" src="./path/to/node_modules/call-matcher/dist/call-matcher.js"></script>



CHANGELOG
---------------------------------------
See [CHANGELOG](https://github.com/twada/call-matcher/blob/master/CHANGELOG.md)


AUTHOR
---------------------------------------
* [Takuto Wada](https://github.com/twada)


LICENSE
---------------------------------------
Licensed under the [MIT](https://github.com/twada/call-matcher/blob/master/MIT-LICENSE.txt) license.


[npm-url]: https://npmjs.org/package/call-matcher
[npm-image]: https://badge.fury.io/js/call-matcher.svg

[travis-url]: https://travis-ci.org/twada/call-matcher
[travis-image]: https://secure.travis-ci.org/twada/call-matcher.svg?branch=master

[depstat-url]: https://gemnasium.com/twada/call-matcher
[depstat-image]: https://gemnasium.com/twada/call-matcher.svg

[license-url]: https://github.com/twada/call-matcher/blob/master/MIT-LICENSE.txt
[license-image]: https://img.shields.io/badge/license-MIT-brightgreen.svg