Skip to content

Commit 97aa1fb

Browse files
clydinalan-agius4
authored andcommitted
test(@angular-devkit/build-angular): add browser builder assets option tests
This change adds expanded unit tests for the browser builder's `assets` option using the builder test harness.
1 parent 6985c3e commit 97aa1fb

File tree

1 file changed

+394
-0
lines changed
  • packages/angular_devkit/build_angular/src/browser/tests/options

1 file changed

+394
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,394 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
// tslint:disable:no-big-function
9+
import { buildWebpackBrowser } from '../../index';
10+
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
13+
describe('Option: "assets"', () => {
14+
beforeEach(async () => {
15+
// Application code is not needed for asset tests
16+
await harness.writeFile('src/main.ts', '');
17+
});
18+
19+
it('supports an empty array value', async () => {
20+
harness.useTarget('build', {
21+
...BASE_OPTIONS,
22+
assets: [],
23+
});
24+
25+
const { result } = await harness.executeOnce();
26+
27+
expect(result?.success).toBe(true);
28+
});
29+
30+
it('supports mixing shorthand and longhand syntax', async () => {
31+
await harness.writeFile('src/files/test.svg', '<svg></svg>');
32+
await harness.writeFile('src/files/another.file', 'asset file');
33+
await harness.writeFile('src/extra.file', 'extra file');
34+
35+
harness.useTarget('build', {
36+
...BASE_OPTIONS,
37+
assets: ['src/extra.file', { glob: '*', input: 'src/files', output: '.' }],
38+
});
39+
40+
const { result } = await harness.executeOnce();
41+
42+
expect(result?.success).toBe(true);
43+
44+
harness.expectFile('dist/extra.file').content.toBe('extra file');
45+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
46+
harness.expectFile('dist/another.file').content.toBe('asset file');
47+
});
48+
49+
describe('shorthand syntax', () => {
50+
it('copies a single asset', async () => {
51+
await harness.writeFile('src/test.svg', '<svg></svg>');
52+
53+
harness.useTarget('build', {
54+
...BASE_OPTIONS,
55+
assets: ['src/test.svg'],
56+
});
57+
58+
const { result } = await harness.executeOnce();
59+
60+
expect(result?.success).toBe(true);
61+
62+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
63+
});
64+
65+
it('copies multiple assets', async () => {
66+
await harness.writeFile('src/test.svg', '<svg></svg>');
67+
await harness.writeFile('src/another.file', 'asset file');
68+
69+
harness.useTarget('build', {
70+
...BASE_OPTIONS,
71+
assets: ['src/test.svg', 'src/another.file'],
72+
});
73+
74+
const { result } = await harness.executeOnce();
75+
76+
expect(result?.success).toBe(true);
77+
78+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
79+
harness.expectFile('dist/another.file').content.toBe('asset file');
80+
});
81+
82+
it('copies an asset with directory and maintains directory in output', async () => {
83+
await harness.writeFile('src/subdirectory/test.svg', '<svg></svg>');
84+
85+
harness.useTarget('build', {
86+
...BASE_OPTIONS,
87+
assets: ['src/subdirectory/test.svg'],
88+
});
89+
90+
const { result } = await harness.executeOnce();
91+
92+
expect(result?.success).toBe(true);
93+
94+
harness.expectFile('dist/subdirectory/test.svg').content.toBe('<svg></svg>');
95+
});
96+
97+
it('does not fail if asset does not exist', async () => {
98+
harness.useTarget('build', {
99+
...BASE_OPTIONS,
100+
assets: ['src/test.svg'],
101+
});
102+
103+
const { result } = await harness.executeOnce();
104+
105+
expect(result?.success).toBe(true);
106+
107+
harness.expectFile('dist/test.svg').toNotExist();
108+
});
109+
110+
it('throws exception if asset path is not within project source root', async () => {
111+
await harness.writeFile('test.svg', '<svg></svg>');
112+
113+
harness.useTarget('build', {
114+
...BASE_OPTIONS,
115+
assets: ['test.svg'],
116+
});
117+
118+
const { result, error } = await harness.executeOnce({ outputLogsOnException: false });
119+
120+
expect(result).toBeUndefined();
121+
expect(error).toEqual(
122+
jasmine.objectContaining({
123+
message: jasmine.stringMatching('path must start with the project source root'),
124+
}),
125+
);
126+
127+
harness.expectFile('dist/test.svg').toNotExist();
128+
});
129+
});
130+
131+
describe('longhand syntax', () => {
132+
it('copies a single asset', async () => {
133+
await harness.writeFile('src/test.svg', '<svg></svg>');
134+
135+
harness.useTarget('build', {
136+
...BASE_OPTIONS,
137+
assets: [{ glob: 'test.svg', input: 'src', output: '.' }],
138+
});
139+
140+
const { result } = await harness.executeOnce();
141+
142+
expect(result?.success).toBe(true);
143+
144+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
145+
});
146+
147+
it('copies multiple assets as separate entries', async () => {
148+
await harness.writeFile('src/test.svg', '<svg></svg>');
149+
await harness.writeFile('src/another.file', 'asset file');
150+
151+
harness.useTarget('build', {
152+
...BASE_OPTIONS,
153+
assets: [
154+
{ glob: 'test.svg', input: 'src', output: '.' },
155+
{ glob: 'another.file', input: 'src', output: '.' },
156+
],
157+
});
158+
159+
const { result } = await harness.executeOnce();
160+
161+
expect(result?.success).toBe(true);
162+
163+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
164+
harness.expectFile('dist/another.file').content.toBe('asset file');
165+
});
166+
167+
it('copies multiple assets with a single entry glob pattern', async () => {
168+
await harness.writeFile('src/test.svg', '<svg></svg>');
169+
await harness.writeFile('src/another.file', 'asset file');
170+
171+
harness.useTarget('build', {
172+
...BASE_OPTIONS,
173+
assets: [{ glob: '{test.svg,another.file}', input: 'src', output: '.' }],
174+
});
175+
176+
const { result } = await harness.executeOnce();
177+
178+
expect(result?.success).toBe(true);
179+
180+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
181+
harness.expectFile('dist/another.file').content.toBe('asset file');
182+
});
183+
184+
it('copies multiple assets with a wildcard glob pattern', async () => {
185+
await harness.writeFile('src/files/test.svg', '<svg></svg>');
186+
await harness.writeFile('src/files/another.file', 'asset file');
187+
188+
harness.useTarget('build', {
189+
...BASE_OPTIONS,
190+
assets: [{ glob: '*', input: 'src/files', output: '.' }],
191+
});
192+
193+
const { result } = await harness.executeOnce();
194+
195+
expect(result?.success).toBe(true);
196+
197+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
198+
harness.expectFile('dist/another.file').content.toBe('asset file');
199+
});
200+
201+
it('copies multiple assets with a recursive wildcard glob pattern', async () => {
202+
await harness.writeFiles({
203+
'src/files/test.svg': '<svg></svg>',
204+
'src/files/another.file': 'asset file',
205+
'src/files/nested/extra.file': 'extra file',
206+
});
207+
208+
harness.useTarget('build', {
209+
...BASE_OPTIONS,
210+
assets: [{ glob: '**/*', input: 'src/files', output: '.' }],
211+
});
212+
213+
const { result } = await harness.executeOnce();
214+
215+
expect(result?.success).toBe(true);
216+
217+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
218+
harness.expectFile('dist/another.file').content.toBe('asset file');
219+
harness.expectFile('dist/nested/extra.file').content.toBe('extra file');
220+
});
221+
222+
it('automatically ignores "." prefixed files when using wildcard glob pattern', async () => {
223+
await harness.writeFile('src/files/.gitkeep', '');
224+
225+
harness.useTarget('build', {
226+
...BASE_OPTIONS,
227+
assets: [{ glob: '*', input: 'src/files', output: '.' }],
228+
});
229+
230+
const { result } = await harness.executeOnce();
231+
232+
expect(result?.success).toBe(true);
233+
234+
harness.expectFile('dist/.gitkeep').toNotExist();
235+
});
236+
237+
it('supports ignoring a specific file when using a glob pattern', async () => {
238+
await harness.writeFiles({
239+
'src/files/test.svg': '<svg></svg>',
240+
'src/files/another.file': 'asset file',
241+
'src/files/nested/extra.file': 'extra file',
242+
});
243+
244+
harness.useTarget('build', {
245+
...BASE_OPTIONS,
246+
assets: [
247+
{ glob: '**/*', input: 'src/files', output: '.', ignore: ['another.file'] },
248+
],
249+
});
250+
251+
const { result } = await harness.executeOnce();
252+
253+
expect(result?.success).toBe(true);
254+
255+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
256+
harness.expectFile('dist/another.file').toNotExist();
257+
harness.expectFile('dist/nested/extra.file').content.toBe('extra file');
258+
});
259+
260+
it('supports ignoring with a glob pattern when using a glob pattern', async () => {
261+
await harness.writeFiles({
262+
'src/files/test.svg': '<svg></svg>',
263+
'src/files/another.file': 'asset file',
264+
'src/files/nested/extra.file': 'extra file',
265+
});
266+
267+
harness.useTarget('build', {
268+
...BASE_OPTIONS,
269+
assets: [
270+
{ glob: '**/*', input: 'src/files', output: '.', ignore: ['**/*.file'] },
271+
],
272+
});
273+
274+
const { result } = await harness.executeOnce();
275+
276+
expect(result?.success).toBe(true);
277+
278+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
279+
harness.expectFile('dist/another.file').toNotExist();
280+
harness.expectFile('dist/nested/extra.file').toNotExist();
281+
});
282+
283+
it('copies an asset with directory and maintains directory in output', async () => {
284+
await harness.writeFile('src/subdirectory/test.svg', '<svg></svg>');
285+
286+
harness.useTarget('build', {
287+
...BASE_OPTIONS,
288+
assets: [{ glob: 'subdirectory/test.svg', input: 'src', output: '.' }],
289+
});
290+
291+
const { result } = await harness.executeOnce();
292+
293+
expect(result?.success).toBe(true);
294+
295+
harness.expectFile('dist/subdirectory/test.svg').content.toBe('<svg></svg>');
296+
});
297+
298+
it('does not fail if asset does not exist', async () => {
299+
harness.useTarget('build', {
300+
...BASE_OPTIONS,
301+
assets: [{ glob: 'test.svg', input: 'src', output: '.' }],
302+
});
303+
304+
const { result } = await harness.executeOnce();
305+
306+
expect(result?.success).toBe(true);
307+
308+
harness.expectFile('dist/test.svg').toNotExist();
309+
});
310+
311+
it('uses project output path when output option is empty string', async () => {
312+
await harness.writeFile('src/test.svg', '<svg></svg>');
313+
314+
harness.useTarget('build', {
315+
...BASE_OPTIONS,
316+
assets: [{ glob: 'test.svg', input: 'src', output: '' }],
317+
});
318+
319+
const { result } = await harness.executeOnce();
320+
321+
expect(result?.success).toBe(true);
322+
323+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
324+
});
325+
326+
it('uses project output path when output option is "."', async () => {
327+
await harness.writeFile('src/test.svg', '<svg></svg>');
328+
329+
harness.useTarget('build', {
330+
...BASE_OPTIONS,
331+
assets: [{ glob: 'test.svg', input: 'src', output: '.' }],
332+
});
333+
334+
const { result } = await harness.executeOnce();
335+
336+
expect(result?.success).toBe(true);
337+
338+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
339+
});
340+
341+
it('uses project output path when output option is "/"', async () => {
342+
await harness.writeFile('src/test.svg', '<svg></svg>');
343+
344+
harness.useTarget('build', {
345+
...BASE_OPTIONS,
346+
assets: [{ glob: 'test.svg', input: 'src', output: '/' }],
347+
});
348+
349+
const { result } = await harness.executeOnce();
350+
351+
expect(result?.success).toBe(true);
352+
353+
harness.expectFile('dist/test.svg').content.toBe('<svg></svg>');
354+
});
355+
356+
it('creates a project output sub-path when output option path does not exist', async () => {
357+
await harness.writeFile('src/test.svg', '<svg></svg>');
358+
359+
harness.useTarget('build', {
360+
...BASE_OPTIONS,
361+
assets: [{ glob: 'test.svg', input: 'src', output: 'subdirectory' }],
362+
});
363+
364+
const { result } = await harness.executeOnce();
365+
366+
expect(result?.success).toBe(true);
367+
368+
harness.expectFile('dist/subdirectory/test.svg').content.toBe('<svg></svg>');
369+
});
370+
371+
it('throws exception if output option is not within project output path', async () => {
372+
await harness.writeFile('test.svg', '<svg></svg>');
373+
374+
harness.useTarget('build', {
375+
...BASE_OPTIONS,
376+
assets: [{ glob: 'test.svg', input: 'src', output: '..' }],
377+
});
378+
379+
const { result, error } = await harness.executeOnce({ outputLogsOnException: false });
380+
381+
expect(result).toBeUndefined();
382+
expect(error).toEqual(
383+
jasmine.objectContaining({
384+
message: jasmine.stringMatching(
385+
'An asset cannot be written to a location outside of the output path',
386+
),
387+
}),
388+
);
389+
390+
harness.expectFile('dist/test.svg').toNotExist();
391+
});
392+
});
393+
});
394+
});

0 commit comments

Comments
 (0)