1 | 'use strict';
|
2 |
|
3 | var fs = require('fs');
|
4 | var nPath = require('path');
|
5 | var readline = require('readline');
|
6 | var mkdirp = require('mkdirp');
|
7 |
|
8 | function readFeatureTestLines(output) {
|
9 | return readline.createInterface({
|
10 | input: fs.createReadStream(nPath.join(__dirname, '../browser/features.js')),
|
11 | historySize: 0
|
12 | });
|
13 | }
|
14 |
|
15 | function lineParser() {
|
16 | var currObj = void 0;
|
17 | return function (line) {
|
18 | var m = /^\s+'([^']+)':\s+(.)/.exec(line);
|
19 |
|
20 | if (!m) {
|
21 | var res = currObj ? { closing: true, object: currObj } : null;
|
22 | currObj = null;
|
23 | return res;
|
24 | }
|
25 |
|
26 | var name = m[1];
|
27 |
|
28 | if (m[2] === '{') {
|
29 | currObj = name;
|
30 | return { opening: true, object: name };
|
31 | }
|
32 |
|
33 | if (!currObj) {
|
34 | return { object: name };
|
35 | }
|
36 |
|
37 | return { object: currObj, method: name };
|
38 | };
|
39 | }
|
40 |
|
41 | function composeFeatures(features) {
|
42 | return new Promise(function (resolve) {
|
43 | var lines = [];
|
44 | var liner = readFeatureTestLines();
|
45 | var parseLine = lineParser();
|
46 |
|
47 | var methods = new Set();
|
48 | var objects = features.reduce(function (set, feature) {
|
49 | var parts = feature.split('.');
|
50 | set.add(parts[0]);
|
51 | if (parts[1]) {
|
52 | methods.add(feature);
|
53 | }
|
54 | return set;
|
55 | }, new Set());
|
56 |
|
57 | liner.on('line', function (line) {
|
58 | var res = parseLine(line);
|
59 |
|
60 | if ((res && objects.has(res.object) && (res.method && methods.has(res.object + '.' + res.method) || !res.method) || !res) && !/^\s*$/.test(line)) {
|
61 | lines.push(line);
|
62 | }
|
63 | });
|
64 |
|
65 | liner.on('close', function () {
|
66 | return resolve({ features: features, lines: lines });
|
67 | });
|
68 | });
|
69 | }
|
70 |
|
71 | function composeFeatureFile(features, filePath) {
|
72 | if (!filePath) {
|
73 | filePath = 'featuretest.js';
|
74 | }
|
75 |
|
76 | return composeFeatures(features).then(function (composedScript) {
|
77 | return new Promise(function (resolve, reject) {
|
78 | mkdirp(nPath.dirname(filePath), function (err) {
|
79 | if (err) {
|
80 | reject(err);
|
81 | }
|
82 |
|
83 | var writeStream = fs.createWriteStream(filePath);
|
84 | writeStream.write('const features = [\'' + composedScript.features.join("','") + '\'];\n');
|
85 | composedScript.lines[0] = composedScript.lines[0].replace('export default ', '');
|
86 | writeStream.write(composedScript.lines.join('\n'));
|
87 |
|
88 | resolve(writeStream);
|
89 | });
|
90 | });
|
91 | });
|
92 | }
|
93 |
|
94 | function readFeatures() {
|
95 | return new Promise(function (resolve) {
|
96 | var objects = new Set();
|
97 | var methods = new Map();
|
98 |
|
99 | var liner = readFeatureTestLines();
|
100 | var parseLine = lineParser();
|
101 |
|
102 | var waitForClosing = void 0;
|
103 |
|
104 | liner.on('line', function (line) {
|
105 | var res = parseLine(line);
|
106 |
|
107 | if (!res) {
|
108 | return;
|
109 | }
|
110 |
|
111 | if (res.opening) {
|
112 | waitForClosing = true;
|
113 | } else if (res.closing) {
|
114 | waitForClosing = false;
|
115 | } else if (waitForClosing && res.object === res.method) {
|
116 | objects.add(res.object);
|
117 | } else if (res.method) {
|
118 | var objList = methods.get(res.method) || [];
|
119 | objList.push(res.object);
|
120 | methods.set(res.method, objList);
|
121 | } else if (res.object) {
|
122 | objects.add(res.object);
|
123 | }
|
124 | });
|
125 |
|
126 | liner.on('close', function () {
|
127 | return resolve({ objects: objects, methods: methods });
|
128 | });
|
129 | });
|
130 | }
|
131 |
|
132 | module.exports.compose = composeFeatures;
|
133 | module.exports.write = composeFeatureFile;
|
134 | module.exports.read = readFeatures;
|