1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
16 | return new (P || (P = Promise))(function (resolve, reject) {
|
17 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
18 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
19 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
20 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
21 | });
|
22 | };
|
23 | Object.defineProperty(exports, "__esModule", { value: true });
|
24 | const chai_1 = require("chai");
|
25 | const path = require("path");
|
26 | const polymer_project_config_1 = require("polymer-project-config");
|
27 | const sinon = require("sinon");
|
28 | const stream_1 = require("stream");
|
29 | const util_1 = require("./util");
|
30 | const analyzer_1 = require("../analyzer");
|
31 | const streams_1 = require("../streams");
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | class NoopStream extends stream_1.Writable {
|
38 | constructor() {
|
39 | super({ objectMode: true });
|
40 | }
|
41 | _write(_chunk, _encoding, callback) {
|
42 | callback();
|
43 | }
|
44 | }
|
45 | suite('Analyzer', () => {
|
46 | suite('DepsIndex', () => {
|
47 | test('fragment to deps list has only uniques', () => {
|
48 | const config = new polymer_project_config_1.ProjectConfig({
|
49 | root: `test-fixtures/analyzer-data`,
|
50 | entrypoint: 'entrypoint.html',
|
51 | fragments: [
|
52 | 'a.html',
|
53 | 'b.html',
|
54 | ],
|
55 | sources: ['a.html', 'b.html', 'entrypoint.html'],
|
56 | });
|
57 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
58 | analyzer.sources().pipe(new NoopStream());
|
59 | analyzer.dependencies().pipe(new NoopStream());
|
60 | return streams_1.waitForAll([analyzer.sources(), analyzer.dependencies()])
|
61 | .then(() => {
|
62 | return analyzer.analyzeDependencies;
|
63 | })
|
64 | .then((depsIndex) => {
|
65 | const ftd = depsIndex.fragmentToDeps;
|
66 | for (const frag of ftd.keys()) {
|
67 | chai_1.assert.deepEqual(ftd.get(frag), ['shared-1.html', 'shared-2.html'].map((u) => u));
|
68 | }
|
69 | });
|
70 | });
|
71 | test('analyzing shell and entrypoint doesn\'t double load files', () => {
|
72 | const root = `test-fixtures/analyzer-data`;
|
73 | const sourceFiles = ['shell.html', 'entrypoint.html'].map((p) => path.resolve(root, p));
|
74 | const config = new polymer_project_config_1.ProjectConfig({
|
75 | root: root,
|
76 | entrypoint: 'entrypoint.html',
|
77 | shell: 'shell.html',
|
78 | sources: sourceFiles,
|
79 | });
|
80 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
81 | analyzer.sources().pipe(new NoopStream());
|
82 | analyzer.dependencies().pipe(new NoopStream());
|
83 | return streams_1.waitForAll([analyzer.sources(), analyzer.dependencies()])
|
84 | .then(() => {
|
85 | return analyzer.analyzeDependencies;
|
86 | })
|
87 | .then((depsIndex) => {
|
88 | chai_1.assert.isTrue(depsIndex.depsToFragments.has('shared-2.html'));
|
89 | chai_1.assert.isFalse(depsIndex.depsToFragments.has('shell.html'));
|
90 | chai_1.assert.isFalse(depsIndex.depsToFragments.has('shared-banana.html'));
|
91 | });
|
92 | });
|
93 | });
|
94 | suite('.dependencies', () => {
|
95 | test('outputs all dependencies needed by source', () => {
|
96 | const foundDependencies = new Set();
|
97 | const root = `test-fixtures/analyzer-data`;
|
98 | const sourceFiles = ['shell.html', 'entrypoint.html'].map((p) => path.resolve(root, p));
|
99 | const config = new polymer_project_config_1.ProjectConfig({
|
100 | root: root,
|
101 | entrypoint: 'entrypoint.html',
|
102 | shell: 'shell.html',
|
103 | sources: sourceFiles,
|
104 | });
|
105 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
106 | analyzer.sources().pipe(new NoopStream());
|
107 | analyzer.dependencies().on('data', (file) => {
|
108 | foundDependencies.add(file.path);
|
109 | });
|
110 | return streams_1.waitForAll([analyzer.sources(), analyzer.dependencies()])
|
111 | .then(() => {
|
112 |
|
113 |
|
114 | chai_1.assert.isFalse(foundDependencies.has(path.resolve(root, 'shared-1.html')));
|
115 |
|
116 | chai_1.assert.isTrue(foundDependencies.has(path.resolve(root, 'shared-2.html')));
|
117 | });
|
118 | });
|
119 | test('outputs all dependencies needed by source and given fragments', () => {
|
120 | const foundDependencies = new Set();
|
121 | const root = `test-fixtures/analyzer-data`;
|
122 | const sourceFiles = ['a.html', 'b.html', 'shell.html', 'entrypoint.html'].map((p) => path.resolve(root, p));
|
123 | const config = new polymer_project_config_1.ProjectConfig({
|
124 | root: root,
|
125 | entrypoint: 'entrypoint.html',
|
126 | shell: 'shell.html',
|
127 | fragments: [
|
128 | 'a.html',
|
129 | 'b.html',
|
130 | ],
|
131 | sources: sourceFiles,
|
132 | });
|
133 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
134 | analyzer.sources().pipe(new NoopStream());
|
135 | analyzer.dependencies().on('data', (file) => {
|
136 | foundDependencies.add(file.path);
|
137 | });
|
138 | return streams_1.waitForAll([analyzer.sources(), analyzer.dependencies()])
|
139 | .then(() => {
|
140 |
|
141 |
|
142 | chai_1.assert.isTrue(foundDependencies.has(path.resolve(root, 'shared-1.html')));
|
143 |
|
144 |
|
145 | chai_1.assert.isTrue(foundDependencies.has(path.resolve(root, 'shared-2.html')));
|
146 | });
|
147 | });
|
148 | });
|
149 | test('propagates an error when a dependency filepath is analyzed but cannot be found', (done) => {
|
150 | const root = `test-fixtures/bad-src-import`;
|
151 | const config = new polymer_project_config_1.ProjectConfig({
|
152 | root: root,
|
153 | entrypoint: 'index.html',
|
154 | sources: ['src/**/*'],
|
155 | });
|
156 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
157 | let errorCounter = 0;
|
158 | const errorListener = (err) => {
|
159 | chai_1.assert.equal(err.message, '3 error(s) occurred during build.');
|
160 | errorCounter++;
|
161 | if (errorCounter >= 2) {
|
162 | done();
|
163 | }
|
164 | };
|
165 | analyzer.sources().pipe(new NoopStream());
|
166 | analyzer.sources().on('error', errorListener);
|
167 | analyzer.dependencies().pipe(new NoopStream());
|
168 | analyzer.dependencies().on('error', errorListener);
|
169 | });
|
170 | test('propagates an error when a source filepath is analyzed but cannot be found', (done) => {
|
171 | const root = `test-fixtures/bad-dependency-import`;
|
172 | const config = new polymer_project_config_1.ProjectConfig({
|
173 | root: root,
|
174 | entrypoint: 'index.html',
|
175 | sources: ['src/**/*'],
|
176 | });
|
177 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
178 | analyzer.dependencies().pipe(new NoopStream());
|
179 | analyzer.dependencies().on('error', (err) => {
|
180 | chai_1.assert.match(err.message, /ENOENT\: no such file or directory.*does\-not\-exist\-in\-dependencies\.html/);
|
181 | done();
|
182 | });
|
183 | });
|
184 | test('both file streams will emit a analysis warning of type "error"', (done) => {
|
185 | const root = path.resolve('test-fixtures/project-analysis-error');
|
186 | const sourceFiles = path.join(root, '**');
|
187 | const config = new polymer_project_config_1.ProjectConfig({
|
188 | root: root,
|
189 | sources: [sourceFiles],
|
190 | });
|
191 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
192 | let errorCounter = 0;
|
193 | const errorListener = (err) => {
|
194 | chai_1.assert.equal(err.message, '1 error(s) occurred during build.');
|
195 | errorCounter++;
|
196 | if (errorCounter >= 2) {
|
197 | done();
|
198 | }
|
199 | };
|
200 | analyzer.sources().pipe(new NoopStream());
|
201 | analyzer.sources().on('error', errorListener);
|
202 | analyzer.dependencies().pipe(new NoopStream());
|
203 | analyzer.dependencies().on('error', errorListener);
|
204 | });
|
205 | test('the analyzer stream will log all analysis warnings at the end of the stream', () => {
|
206 | const root = path.resolve('test-fixtures/project-analysis-error');
|
207 | const sourceFiles = path.join(root, '**');
|
208 | const config = new polymer_project_config_1.ProjectConfig({
|
209 | root: root,
|
210 | sources: [sourceFiles],
|
211 | });
|
212 | let prematurePrintWarnings = false;
|
213 | const prematurePrintWarningsCheck = () => prematurePrintWarnings =
|
214 | prematurePrintWarnings ||
|
215 | analyzer.allFragmentsToAnalyze.size > 0 && printWarningsSpy.called;
|
216 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
217 | const printWarningsSpy = sinon.spy(analyzer, 'printWarnings');
|
218 | analyzer.sources().on('data', prematurePrintWarningsCheck);
|
219 | analyzer.dependencies().on('data', prematurePrintWarningsCheck);
|
220 | return streams_1.waitForAll([analyzer.sources(), analyzer.dependencies()])
|
221 | .then(() => {
|
222 | throw new Error('Parse error expected!');
|
223 | }, (_err) => {
|
224 | chai_1.assert.isFalse(prematurePrintWarnings);
|
225 | chai_1.assert.isTrue(printWarningsSpy.calledOnce);
|
226 | });
|
227 | });
|
228 | test('analyzer filters warnings', () => {
|
229 | const root = path.resolve('test-fixtures/project-analysis-warning');
|
230 | const sources = [path.join(root, '**')];
|
231 | const config = new polymer_project_config_1.ProjectConfig({
|
232 | root,
|
233 | sources,
|
234 | lint: { rules: ['polymer-2'], ignoreWarnings: ['invalid-polymer-expression'] }
|
235 | });
|
236 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
237 | analyzer.sources().pipe(new NoopStream());
|
238 | return streams_1.waitFor(analyzer.sources()).then(() => {
|
239 | chai_1.assert.isTrue(analyzer.warnings.size === 0);
|
240 | });
|
241 | });
|
242 | test('calling sources() starts analysis', () => __awaiter(this, void 0, void 0, function* () {
|
243 | const config = new polymer_project_config_1.ProjectConfig({
|
244 | root: `test-fixtures/analyzer-data`,
|
245 | entrypoint: 'entrypoint.html',
|
246 | fragments: [
|
247 | 'a.html',
|
248 | 'b.html',
|
249 | ],
|
250 | sources: ['a.html', 'b.html', 'entrypoint.html'],
|
251 | });
|
252 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
253 | chai_1.assert.isFalse(analyzer.started);
|
254 | analyzer.sources().pipe(new NoopStream());
|
255 | chai_1.assert.isTrue(analyzer.started);
|
256 | }));
|
257 | test('calling dependencies() starts analysis', () => {
|
258 | const config = new polymer_project_config_1.ProjectConfig({
|
259 | root: `test-fixtures/analyzer-data`,
|
260 | entrypoint: 'entrypoint.html',
|
261 | fragments: [
|
262 | 'a.html',
|
263 | 'b.html',
|
264 | ],
|
265 | sources: ['a.html', 'b.html', 'entrypoint.html'],
|
266 | });
|
267 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
268 | chai_1.assert.isFalse(analyzer.started);
|
269 | analyzer.dependencies().pipe(new NoopStream());
|
270 | chai_1.assert.isTrue(analyzer.started);
|
271 | });
|
272 | test('the source/dependency streams remain paused until use', () => {
|
273 | const config = new polymer_project_config_1.ProjectConfig({
|
274 | root: `test-fixtures/analyzer-data`,
|
275 | entrypoint: 'entrypoint.html',
|
276 | fragments: [
|
277 | 'a.html',
|
278 | 'b.html',
|
279 | ],
|
280 | sources: ['a.html', 'b.html', 'entrypoint.html'],
|
281 | });
|
282 | const analyzer = new analyzer_1.BuildAnalyzer(config, null);
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 | const analyzerWithPrivates = analyzer;
|
289 | chai_1.assert.isUndefined(analyzerWithPrivates._sourcesStream);
|
290 | chai_1.assert.isUndefined(analyzerWithPrivates._dependenciesStream);
|
291 | analyzerWithPrivates.sources();
|
292 | chai_1.assert.isDefined(analyzerWithPrivates._sourcesStream);
|
293 | chai_1.assert.isDefined(analyzerWithPrivates._dependenciesStream);
|
294 | chai_1.assert.isTrue(util_1.getFlowingState(analyzerWithPrivates._sourcesStream));
|
295 | chai_1.assert.isTrue(util_1.getFlowingState(analyzerWithPrivates._dependenciesStream));
|
296 |
|
297 |
|
298 |
|
299 | chai_1.assert.isNull(util_1.getFlowingState(analyzer.sources()));
|
300 | chai_1.assert.isNull(util_1.getFlowingState(analyzer.dependencies()));
|
301 | analyzer.sources().on('data', () => { });
|
302 | chai_1.assert.isTrue(util_1.getFlowingState(analyzer.sources()));
|
303 | chai_1.assert.isNull(util_1.getFlowingState(analyzer.dependencies()));
|
304 | analyzer.dependencies().pipe(new NoopStream());
|
305 | chai_1.assert.isTrue(util_1.getFlowingState(analyzer.sources()));
|
306 | chai_1.assert.isTrue(util_1.getFlowingState(analyzer.dependencies()));
|
307 | });
|
308 |
|
309 |
|
310 | suite.skip('.printWarnings()', () => { });
|
311 | });
|
312 |
|
\ | No newline at end of file |