Skip to content

Commit dd9ce50

Browse files
authoredMay 15, 2020
test: coverage
1 parent 29254e3 commit dd9ce50

10 files changed

+375
-46
lines changed
 

‎src/options.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,6 @@
100100
}
101101
}
102102
}
103-
}
103+
},
104+
"required": ["patterns"]
104105
}

‎src/postProcessPattern.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default async function postProcessPattern(globalRef, pattern, file) {
2222
logger.debug(`getting stats for '${file.absoluteFrom}' to write to assets`);
2323

2424
const getStats = pattern.stats
25-
? Promise.resolve().then(() => pattern.stats)
25+
? pattern.stats
2626
: stat(inputFileSystem, file.absoluteFrom);
2727

2828
let stats;
@@ -31,13 +31,16 @@ export default async function postProcessPattern(globalRef, pattern, file) {
3131
stats = await getStats;
3232
} catch (error) {
3333
compilation.errors.push(error);
34+
3435
return;
3536
}
3637

3738
if (stats.isDirectory()) {
3839
logger.debug(
3940
`skipping '${file.absoluteFrom}' because it is empty directory`
4041
);
42+
43+
return;
4144
}
4245

4346
// If this came from a glob, add it to the file watchlist

‎src/processPattern.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ export default async function processPattern(globalRef, pattern) {
3131
return Promise.resolve();
3232
}
3333

34-
return paths.map((from) => {
34+
return paths.map((filepath) => {
35+
let from;
36+
37+
if (typeof filepath === 'string') {
38+
from = filepath;
39+
} else {
40+
from = filepath.path;
41+
}
42+
3543
const file = { absoluteFrom: path.resolve(pattern.context, from) };
3644

3745
file.relativeFrom = path.relative(pattern.context, file.absoluteFrom);
@@ -43,13 +51,10 @@ export default async function processPattern(globalRef, pattern) {
4351
logger.debug(`found ${from}`);
4452

4553
// Change the to path to be relative for webpack
46-
if (pattern.toType === 'dir') {
47-
file.webpackTo = path.join(pattern.to, file.relativeFrom);
48-
} else if (pattern.toType === 'file') {
49-
file.webpackTo = pattern.to || file.relativeFrom;
50-
} else if (pattern.toType === 'template') {
51-
file.webpackTo = pattern.to;
52-
}
54+
file.webpackTo =
55+
pattern.toType === 'dir'
56+
? path.join(pattern.to, file.relativeFrom)
57+
: pattern.to;
5358

5459
if (path.isAbsolute(file.webpackTo)) {
5560
file.webpackTo = path.relative(output, file.webpackTo);

‎src/utils/createPatternGlob.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ function createPatternGlob(pattern, globalRef) {
1818

1919
// eslint-disable-next-line no-param-reassign
2020
pattern.globOptions = {
21-
...{
22-
cwd: pattern.context,
23-
followSymbolicLinks: true,
24-
},
21+
...{ followSymbolicLinks: true },
2522
...(pattern.globOptions || {}),
23+
...{ cwd: pattern.context },
2624
};
2725

2826
switch (pattern.fromType) {
@@ -44,7 +42,6 @@ function createPatternGlob(pattern, globalRef) {
4442
pattern.globOptions.dot = true;
4543
}
4644
/* eslint-enable no-param-reassign */
47-
4845
break;
4946
case 'file':
5047
logger.debug(`determined '${pattern.absoluteFrom}' is a file`);
@@ -60,7 +57,6 @@ function createPatternGlob(pattern, globalRef) {
6057
pattern.globOptions.dot = true;
6158
}
6259
/* eslint-enable no-param-reassign */
63-
6460
break;
6561
default: {
6662
logger.debug(`determined '${pattern.absoluteFrom}' is a glob`);

‎test/CopyPlugin.test.js

+72-3
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ describe('CopyPlugin', () => {
488488
});
489489

490490
describe('logging', () => {
491-
it('should logging', (done) => {
491+
it('should logging when "from" is a file', (done) => {
492492
const expectedAssetKeys = ['file.txt'];
493493

494494
run({
@@ -504,12 +504,81 @@ describe('CopyPlugin', () => {
504504
.get('copy-webpack-plugin')
505505
.map((entry) =>
506506
entry.args[0].replace(/\\/g, '/').split(root).join('.')
507-
);
507+
)
508+
.sort();
508509

509510
expect(
510511
Array.from(Object.keys(readAssets(compiler, stats))).sort()
511512
).toEqual(expectedAssetKeys);
512-
expect({ result: logs }).toMatchSnapshot({ result: logs });
513+
expect({ logs }).toMatchSnapshot('logs');
514+
})
515+
.then(done)
516+
.catch(done);
517+
});
518+
519+
it('should logging when "from" is a directory', (done) => {
520+
const expectedAssetKeys = [
521+
'.dottedfile',
522+
'directoryfile.txt',
523+
'nested/deep-nested/deepnested.txt',
524+
'nested/nestedfile.txt',
525+
];
526+
527+
run({
528+
patterns: [
529+
{
530+
from: 'directory',
531+
},
532+
],
533+
})
534+
.then(({ compiler, stats }) => {
535+
const root = path.resolve(__dirname).replace(/\\/g, '/');
536+
const logs = stats.compilation.logging
537+
.get('copy-webpack-plugin')
538+
.map((entry) =>
539+
entry.args[0].replace(/\\/g, '/').split(root).join('.')
540+
)
541+
.sort();
542+
543+
expect(
544+
Array.from(Object.keys(readAssets(compiler, stats))).sort()
545+
).toEqual(expectedAssetKeys);
546+
expect({ logs }).toMatchSnapshot('logs');
547+
})
548+
.then(done)
549+
.catch(done);
550+
});
551+
552+
it('should logging when "from" is a glob', (done) => {
553+
const expectedAssetKeys = [
554+
'directory/directoryfile.txt',
555+
'directory/nested/deep-nested/deepnested.txt',
556+
'directory/nested/nestedfile.txt',
557+
];
558+
559+
run({
560+
patterns: [
561+
{
562+
from: 'directory/**',
563+
globOptions: {
564+
onlyFiles: false,
565+
},
566+
},
567+
],
568+
})
569+
.then(({ compiler, stats }) => {
570+
const root = path.resolve(__dirname).replace(/\\/g, '/');
571+
const logs = stats.compilation.logging
572+
.get('copy-webpack-plugin')
573+
.map((entry) =>
574+
entry.args[0].replace(/\\/g, '/').split(root).join('.')
575+
)
576+
.sort();
577+
578+
expect(
579+
Array.from(Object.keys(readAssets(compiler, stats))).sort()
580+
).toEqual(expectedAssetKeys);
581+
expect({ logs }).toMatchSnapshot('logs');
513582
})
514583
.then(done)
515584
.catch(done);
+80-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,94 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`CopyPlugin logging should logging 1`] = `
3+
exports[`CopyPlugin logging should logging when "from" is a directory: logs 1`] = `
44
Object {
5-
"result": Array [
5+
"logs": Array [
6+
"add ./fixtures/directory as contextDependencies",
7+
"begin globbing './fixtures/directory/**/*' with a context of './fixtures/directory'",
8+
"determined './fixtures/directory' is a directory",
9+
"determined that './fixtures/directory/.dottedfile' should write to '.dottedfile'",
10+
"determined that './fixtures/directory/directoryfile.txt' should write to 'directoryfile.txt'",
11+
"determined that './fixtures/directory/nested/deep-nested/deepnested.txt' should write to 'nested/deep-nested/deepnested.txt'",
12+
"determined that './fixtures/directory/nested/nestedfile.txt' should write to 'nested/nestedfile.txt'",
13+
"end to adding additional assets",
14+
"found ./fixtures/directory/.dottedfile",
15+
"found ./fixtures/directory/directoryfile.txt",
16+
"found ./fixtures/directory/nested/deep-nested/deepnested.txt",
17+
"found ./fixtures/directory/nested/nestedfile.txt",
18+
"getting stats for './fixtures/directory' to determinate 'fromType'",
19+
"getting stats for './fixtures/directory/.dottedfile' to write to assets",
20+
"getting stats for './fixtures/directory/directoryfile.txt' to write to assets",
21+
"getting stats for './fixtures/directory/nested/deep-nested/deepnested.txt' to write to assets",
22+
"getting stats for './fixtures/directory/nested/nestedfile.txt' to write to assets",
23+
"processing from: 'directory' to: '.'",
24+
"reading './fixtures/directory/.dottedfile' to write to assets",
25+
"reading './fixtures/directory/directoryfile.txt' to write to assets",
26+
"reading './fixtures/directory/nested/deep-nested/deepnested.txt' to write to assets",
27+
"reading './fixtures/directory/nested/nestedfile.txt' to write to assets",
628
"start to adding additional assets",
7-
"processing from: 'file.txt' to: '.'",
8-
"getting stats for './fixtures/file.txt' to determinate 'fromType'",
9-
"determined './fixtures/file.txt' is a file",
29+
"writing '.dottedfile' to compilation assets from './fixtures/directory/.dottedfile'",
30+
"writing 'directoryfile.txt' to compilation assets from './fixtures/directory/directoryfile.txt'",
31+
"writing 'nested/deep-nested/deepnested.txt' to compilation assets from './fixtures/directory/nested/deep-nested/deepnested.txt'",
32+
"writing 'nested/nestedfile.txt' to compilation assets from './fixtures/directory/nested/nestedfile.txt'",
33+
],
34+
}
35+
`;
36+
37+
exports[`CopyPlugin logging should logging when "from" is a file: logs 1`] = `
38+
Object {
39+
"logs": Array [
1040
"add ./fixtures/file.txt as fileDependencies",
1141
"begin globbing './fixtures/file.txt' with a context of './fixtures'",
12-
"found ./fixtures/file.txt",
42+
"determined './fixtures/file.txt' is a file",
1343
"determined that './fixtures/file.txt' should write to 'file.txt'",
44+
"end to adding additional assets",
45+
"found ./fixtures/file.txt",
46+
"getting stats for './fixtures/file.txt' to determinate 'fromType'",
1447
"getting stats for './fixtures/file.txt' to write to assets",
48+
"processing from: 'file.txt' to: '.'",
1549
"reading './fixtures/file.txt' to write to assets",
50+
"start to adding additional assets",
1651
"writing 'file.txt' to compilation assets from './fixtures/file.txt'",
52+
],
53+
}
54+
`;
55+
56+
exports[`CopyPlugin logging should logging when "from" is a glob: logs 1`] = `
57+
Object {
58+
"logs": Array [
59+
"add ./fixtures/directory as contextDependencies",
60+
"add ./fixtures/directory/directoryfile.txt as fileDependencies",
61+
"add ./fixtures/directory/nested/deep-nested/deepnested.txt as fileDependencies",
62+
"add ./fixtures/directory/nested/nestedfile.txt as fileDependencies",
63+
"begin globbing './fixtures/directory/**' with a context of './fixtures'",
64+
"determined './fixtures/directory/**' is a glob",
65+
"determined that './fixtures/directory/directoryfile.txt' should write to 'directory/directoryfile.txt'",
66+
"determined that './fixtures/directory/nested' should write to 'directory/nested'",
67+
"determined that './fixtures/directory/nested/deep-nested' should write to 'directory/nested/deep-nested'",
68+
"determined that './fixtures/directory/nested/deep-nested/deepnested.txt' should write to 'directory/nested/deep-nested/deepnested.txt'",
69+
"determined that './fixtures/directory/nested/nestedfile.txt' should write to 'directory/nested/nestedfile.txt'",
1770
"end to adding additional assets",
71+
"found ./fixtures/directory/directoryfile.txt",
72+
"found ./fixtures/directory/nested",
73+
"found ./fixtures/directory/nested/deep-nested",
74+
"found ./fixtures/directory/nested/deep-nested/deepnested.txt",
75+
"found ./fixtures/directory/nested/nestedfile.txt",
76+
"getting stats for './fixtures/directory/**' to determinate 'fromType'",
77+
"getting stats for './fixtures/directory/directoryfile.txt' to write to assets",
78+
"getting stats for './fixtures/directory/nested' to write to assets",
79+
"getting stats for './fixtures/directory/nested/deep-nested' to write to assets",
80+
"getting stats for './fixtures/directory/nested/deep-nested/deepnested.txt' to write to assets",
81+
"getting stats for './fixtures/directory/nested/nestedfile.txt' to write to assets",
82+
"processing from: 'directory/**' to: '.'",
83+
"reading './fixtures/directory/directoryfile.txt' to write to assets",
84+
"reading './fixtures/directory/nested/deep-nested/deepnested.txt' to write to assets",
85+
"reading './fixtures/directory/nested/nestedfile.txt' to write to assets",
86+
"skipping './fixtures/directory/nested' because it is empty directory",
87+
"skipping './fixtures/directory/nested/deep-nested' because it is empty directory",
88+
"start to adding additional assets",
89+
"writing 'directory/directoryfile.txt' to compilation assets from './fixtures/directory/directoryfile.txt'",
90+
"writing 'directory/nested/deep-nested/deepnested.txt' to compilation assets from './fixtures/directory/nested/deep-nested/deepnested.txt'",
91+
"writing 'directory/nested/nestedfile.txt' to compilation assets from './fixtures/directory/nested/nestedfile.txt'",
1892
],
1993
}
2094
`;

‎test/__snapshots__/validate-options.test.js.snap

+22-16
Original file line numberDiff line numberDiff line change
@@ -127,50 +127,56 @@ exports[`validate options should throw an error on the "patterns" option with "t
127127
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
128128
`;
129129
130+
exports[`validate options should throw an error on the "patterns" option with "undefined" value 1`] = `
131+
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
132+
- options misses the property 'patterns'. Should be:
133+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
134+
`;
135+
130136
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
131137
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
132-
- options has an unknown property 'unknown'. These properties are valid:
133-
object { patterns?, options? }"
138+
- options misses the property 'patterns'. Should be:
139+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
134140
`;
135141
136142
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
137143
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
138-
- options has an unknown property 'unknown'. These properties are valid:
139-
object { patterns?, options? }"
144+
- options misses the property 'patterns'. Should be:
145+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
140146
`;
141147
142148
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
143149
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
144-
- options has an unknown property 'unknown'. These properties are valid:
145-
object { patterns?, options? }"
150+
- options misses the property 'patterns'. Should be:
151+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
146152
`;
147153
148154
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
149155
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
150-
- options has an unknown property 'unknown'. These properties are valid:
151-
object { patterns?, options? }"
156+
- options misses the property 'patterns'. Should be:
157+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
152158
`;
153159
154160
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
155161
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
156-
- options has an unknown property 'unknown'. These properties are valid:
157-
object { patterns?, options? }"
162+
- options misses the property 'patterns'. Should be:
163+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
158164
`;
159165
160166
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
161167
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
162-
- options has an unknown property 'unknown'. These properties are valid:
163-
object { patterns?, options? }"
168+
- options misses the property 'patterns'. Should be:
169+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
164170
`;
165171
166172
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
167173
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
168-
- options has an unknown property 'unknown'. These properties are valid:
169-
object { patterns?, options? }"
174+
- options misses the property 'patterns'. Should be:
175+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
170176
`;
171177
172178
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
173179
"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
174-
- options has an unknown property 'unknown'. These properties are valid:
175-
object { patterns?, options? }"
180+
- options misses the property 'patterns'. Should be:
181+
[non-empty string | object { from, to?, context?, globOptions?, toType?, force?, flatten?, transform?, cacheTransform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)"
176182
`;

‎test/globOptions-option.test.js

+159-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,45 @@ import { runEmit } from './helpers/run';
44

55
const FIXTURES_DIR = path.join(__dirname, 'fixtures');
66

7-
describe('from option', () => {
8-
it('should move files exclude dot files', (done) => {
7+
describe('globOptions option', () => {
8+
// Expected behavior from `globby`/`fast-glob`
9+
it('should move files exclude dot files when "from" is a directory', (done) => {
10+
runEmit({
11+
expectedAssetKeys: ['.file.txt'],
12+
patterns: [
13+
{
14+
from: '.file.txt',
15+
globOptions: {
16+
dot: false,
17+
},
18+
},
19+
],
20+
})
21+
.then(done)
22+
.catch(done);
23+
});
24+
25+
it('should move files exclude dot files when "from" is a directory', (done) => {
26+
runEmit({
27+
expectedAssetKeys: [
28+
'directoryfile.txt',
29+
'nested/deep-nested/deepnested.txt',
30+
'nested/nestedfile.txt',
31+
],
32+
patterns: [
33+
{
34+
from: 'directory',
35+
globOptions: {
36+
dot: false,
37+
},
38+
},
39+
],
40+
})
41+
.then(done)
42+
.catch(done);
43+
});
44+
45+
it('should move files exclude dot files when "from" is a glob', (done) => {
946
runEmit({
1047
expectedAssetKeys: ['file.txt'],
1148
patterns: [
@@ -36,9 +73,7 @@ describe('from option', () => {
3673
.then(done)
3774
.catch(done);
3875
});
39-
});
4076

41-
describe('globOptions ignore option', () => {
4277
it('should ignore files when "from" is a file', (done) => {
4378
runEmit({
4479
expectedErrors: [
@@ -255,4 +290,124 @@ describe('globOptions ignore option', () => {
255290
.then(done)
256291
.catch(done);
257292
});
293+
294+
it('should ignore the "cwd" option', (done) => {
295+
runEmit({
296+
expectedAssetKeys: [
297+
'.dottedfile',
298+
'directoryfile.txt',
299+
'nested/deep-nested/deepnested.txt',
300+
'nested/nestedfile.txt',
301+
],
302+
patterns: [
303+
{
304+
from: 'directory',
305+
globOptions: {
306+
cwd: path.resolve(__dirname, 'fixtures/nested'),
307+
},
308+
},
309+
],
310+
})
311+
.then(done)
312+
.catch(done);
313+
});
314+
315+
it('should work with the "deep" option', (done) => {
316+
runEmit({
317+
expectedAssetKeys: [
318+
'.dottedfile',
319+
'directoryfile.txt',
320+
'nested/nestedfile.txt',
321+
],
322+
patterns: [
323+
{
324+
from: 'directory',
325+
globOptions: {
326+
deep: 2,
327+
},
328+
},
329+
],
330+
})
331+
.then(done)
332+
.catch(done);
333+
});
334+
335+
it('should work with the "markDirectories" option', (done) => {
336+
runEmit({
337+
expectedAssetKeys: [
338+
'.dottedfile',
339+
'directoryfile.txt',
340+
'nested/deep-nested/deepnested.txt',
341+
'nested/nestedfile.txt',
342+
],
343+
patterns: [
344+
{
345+
from: 'directory',
346+
globOptions: {
347+
markDirectories: true,
348+
},
349+
},
350+
],
351+
})
352+
.then(done)
353+
.catch(done);
354+
});
355+
356+
it('should work with the "objectMode" option', (done) => {
357+
runEmit({
358+
expectedAssetKeys: [
359+
'.dottedfile',
360+
'directoryfile.txt',
361+
'nested/deep-nested/deepnested.txt',
362+
'nested/nestedfile.txt',
363+
],
364+
patterns: [
365+
{
366+
from: 'directory',
367+
globOptions: {
368+
objectMode: true,
369+
},
370+
},
371+
],
372+
})
373+
.then(done)
374+
.catch(done);
375+
});
376+
377+
it('should work with the "onlyDirectories" option', (done) => {
378+
runEmit({
379+
expectedAssetKeys: [],
380+
patterns: [
381+
{
382+
from: 'directory',
383+
globOptions: {
384+
onlyDirectories: true,
385+
},
386+
},
387+
],
388+
})
389+
.then(done)
390+
.catch(done);
391+
});
392+
393+
it('should work with the "onlyFiles" option', (done) => {
394+
runEmit({
395+
expectedAssetKeys: [
396+
'.dottedfile',
397+
'directoryfile.txt',
398+
'nested/deep-nested/deepnested.txt',
399+
'nested/nestedfile.txt',
400+
],
401+
patterns: [
402+
{
403+
from: 'directory',
404+
globOptions: {
405+
onlyFiles: true,
406+
},
407+
},
408+
],
409+
})
410+
.then(done)
411+
.catch(done);
412+
});
258413
});

‎test/to-option.test.js

+14
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,20 @@ describe('to option', () => {
329329
.then(done)
330330
.catch(done);
331331
});
332+
333+
it('should move a file to a new directory when "to" is empty', (done) => {
334+
runEmit({
335+
expectedAssetKeys: ['file.txt'],
336+
patterns: [
337+
{
338+
from: 'file.txt',
339+
to: '',
340+
},
341+
],
342+
})
343+
.then(done)
344+
.catch(done);
345+
});
332346
});
333347

334348
describe('is a template', () => {

‎test/validate-options.test.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ describe('validate options', () => {
134134
],
135135
],
136136
failure: [
137+
// eslint-disable-next-line no-undefined
138+
undefined,
137139
true,
138140
'true',
139141
'',
@@ -276,7 +278,11 @@ describe('validate options', () => {
276278

277279
try {
278280
// eslint-disable-next-line no-new
279-
new CopyPlugin({ [key]: value });
281+
new CopyPlugin(
282+
key === 'options'
283+
? { patterns: [{ from: 'file.txt' }], [key]: value }
284+
: { [key]: value }
285+
);
280286
} catch (errorFromPlugin) {
281287
if (errorFromPlugin.name !== 'ValidationError') {
282288
throw errorFromPlugin;

0 commit comments

Comments
 (0)
Please sign in to comment.