1 | var extend = require('./utils').extend;
|
2 |
|
3 | function isFlag(token) {
|
4 | return token.slice(0, 1) === '[' && token.slice(-1) === ']';
|
5 | }
|
6 | function isAlternation(token) {
|
7 | return token.slice(0, 1) === '(' && token.slice(-1) === ')';
|
8 | }
|
9 | function removeEmptyStrings(texts) {
|
10 | return texts.filter(function (text) { return text !== ''; });
|
11 | }
|
12 | function createPermutations(tokens, index) {
|
13 | if (index === tokens.length) {
|
14 | return [{ text: '', flags: {}, alternations: [] }];
|
15 | }
|
16 |
|
17 | var token = tokens[index];
|
18 | var tail = createPermutations(tokens, index + 1);
|
19 | if (isFlag(token)) {
|
20 | var flag = token.slice(1, -1);
|
21 | return tail
|
22 | .map(function (pattern) {
|
23 | var flags = {};
|
24 | flags[flag] = true;
|
25 | return {
|
26 | text: (flag + " " + (pattern.text)),
|
27 | flags: extend(flags, pattern.flags),
|
28 | alternations: pattern.alternations
|
29 | };
|
30 | })
|
31 | .concat(
|
32 | tail.map(function (pattern) {
|
33 | var flags = {};
|
34 | flags[flag] = false;
|
35 | return {
|
36 | text: pattern.text,
|
37 | flags: extend(flags, pattern.flags),
|
38 | alternations: pattern.alternations
|
39 | };
|
40 | })
|
41 | );
|
42 | } else if (isAlternation(token)) {
|
43 | return token
|
44 | .substr(1, token.length - 2)
|
45 | .split(/\|/)
|
46 | .reduce(
|
47 | function (result, alternation) { return result.concat(
|
48 | tail.map(function (ref) {
|
49 | var text = ref.text;
|
50 | var flags = ref.flags;
|
51 | var alternations = ref.alternations;
|
52 |
|
53 | return ({
|
54 |
|
55 | text: alternation ? alternation + text : text.replace(/^ /, ''),
|
56 |
|
57 | flags: flags,
|
58 | alternations: [alternation ].concat( alternations)
|
59 | });
|
60 | })
|
61 | ); },
|
62 | []
|
63 | );
|
64 | } else {
|
65 | return tail.map(function (ref) {
|
66 | var text = ref.text;
|
67 | var flags = ref.flags;
|
68 | var alternations = ref.alternations;
|
69 |
|
70 | return ({
|
71 | text: token + text,
|
72 | flags: flags,
|
73 | alternations: alternations
|
74 | });
|
75 | });
|
76 | }
|
77 | }
|
78 |
|
79 | function expandAssertion(pattern) {
|
80 | pattern = pattern.replace(/(\[[^\]]+\]) ?/g, '$1');
|
81 | var splitRegex = /\[[^\]]+\]|\([^)]+\)/g;
|
82 | var tokens = [];
|
83 | var m;
|
84 | var lastIndex = 0;
|
85 | while ((m = splitRegex.exec(pattern))) {
|
86 | tokens.push(pattern.slice(lastIndex, m.index));
|
87 | tokens.push(pattern.slice(m.index, splitRegex.lastIndex));
|
88 | lastIndex = splitRegex.lastIndex;
|
89 | }
|
90 | tokens.push(pattern.slice(lastIndex));
|
91 | tokens = removeEmptyStrings(tokens);
|
92 | var permutations = createPermutations(tokens, 0);
|
93 | permutations.forEach(function (permutation) {
|
94 | permutation.text = permutation.text.trim();
|
95 | if (permutation.text === '') {
|
96 |
|
97 | throw new Error('Assertion patterns must not only contain flags');
|
98 | }
|
99 | });
|
100 | return permutations;
|
101 | }
|
102 |
|
103 | module.exports = expandAssertion;
|