Skip to content

Commit 6afd559

Browse files
authored
chore(utils): add getPaths helper as separate util (#674)
1 parent 9278e5c commit 6afd559

File tree

7 files changed

+310
-20
lines changed

7 files changed

+310
-20
lines changed

src/utils/getFilenameFromUrl.js

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,13 @@ import querystring from 'querystring';
44

55
import mem from 'mem';
66

7-
function getPaths(stats, options) {
8-
const childStats = stats.stats ? stats.stats : [stats];
9-
const publicPaths = [];
10-
11-
for (const { compilation } of childStats) {
12-
// The `output.path` is always present and always absolute
13-
const outputPath = compilation.getPath(compilation.outputOptions.path);
14-
const publicPath = options.publicPath
15-
? compilation.getPath(options.publicPath)
16-
: compilation.outputOptions.publicPath
17-
? compilation.getPath(compilation.outputOptions.publicPath)
18-
: '';
19-
20-
publicPaths.push({ outputPath, publicPath });
21-
}
22-
23-
return publicPaths;
24-
}
7+
import getPaths from './getPaths';
258

269
const memoizedParse = mem(parse);
2710

2811
export default function getFilenameFromUrl(context, url) {
2912
const { options } = context;
30-
const paths = getPaths(context.stats, options);
13+
const paths = getPaths(context);
3114

3215
let filename;
3316
let urlObject;

src/utils/getPaths.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export default function getPaths(context) {
2+
const { stats, options } = context;
3+
const childStats = stats.stats ? stats.stats : [stats];
4+
const publicPaths = [];
5+
6+
for (const { compilation } of childStats) {
7+
// The `output.path` is always present and always absolute
8+
const outputPath = compilation.getPath(compilation.outputOptions.path);
9+
const publicPath = options.publicPath
10+
? compilation.getPath(options.publicPath)
11+
: compilation.outputOptions.publicPath
12+
? compilation.getPath(compilation.outputOptions.publicPath)
13+
: '';
14+
15+
publicPaths.push({ outputPath, publicPath });
16+
}
17+
18+
return publicPaths;
19+
}

test/api.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,18 @@ describe('API', () => {
198198
});
199199

200200
describe('context property', () => {
201-
it('should contain public properties', () => {
201+
it('should contain public properties', (done) => {
202202
expect(instance.context.state).toBeDefined();
203203
expect(instance.context.options).toBeDefined();
204204
expect(instance.context.compiler).toBeDefined();
205205
expect(instance.context.watching).toBeDefined();
206206
expect(instance.context.outputFileSystem).toBeDefined();
207+
208+
// the compilation needs to finish, as it will still be running
209+
// after the test is done if not finished, potentially impacting other tests
210+
compiler.hooks.done.tap('wdm-test', () => {
211+
done();
212+
});
207213
});
208214
});
209215
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
5+
module.exports = {
6+
mode: 'development',
7+
context: path.resolve(__dirname),
8+
entry: './simple.js',
9+
output: {
10+
filename: 'bundle.js',
11+
path: path.resolve(__dirname, '../outputs/public-path'),
12+
publicPath: '/public/path/',
13+
},
14+
infrastructureLogging: {
15+
level: 'none'
16+
},
17+
stats: 'errors-warnings'
18+
};

test/helpers/listenAndCompile.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default (app, compiler, done) => {
2+
let complete = 0;
3+
// wait until the app is listening and the done hook is called
4+
const progress = () => {
5+
complete += 1;
6+
if (complete === 2) {
7+
done();
8+
}
9+
};
10+
11+
const listen = app.listen((error) => {
12+
if (error) {
13+
// if there is an error, don't wait for the compilation to finish
14+
return done(error);
15+
}
16+
17+
return progress();
18+
});
19+
20+
compiler.hooks.done.tap('wdm-test', () => {
21+
return progress();
22+
});
23+
24+
return listen;
25+
};

test/utils/getFilenameFromUrl.test.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import path from 'path';
2+
3+
import express from 'express';
4+
5+
import middleware from '../../src';
6+
import getFilenameFromUrl from '../../src/utils/getFilenameFromUrl';
7+
8+
import getCompiler from '../helpers/getCompiler';
9+
import listenAndCompile from '../helpers/listenAndCompile';
10+
import webpackSimpleConfig from '../fixtures/webpack.simple.config';
11+
import webpackPublicPathConfig from '../fixtures/webpack.public-path.config';
12+
import webpackMultiConfig from '../fixtures/webpack.array.config';
13+
14+
describe('getFilenameFromUrl', () => {
15+
const configs = [
16+
{
17+
title: 'simple config with path /',
18+
config: webpackSimpleConfig,
19+
middlewareConfig: {},
20+
url: '/',
21+
expected: path.resolve(__dirname, '../outputs/simple/index.html'),
22+
},
23+
{
24+
title: 'simple config with path /index.html',
25+
config: webpackSimpleConfig,
26+
middlewareConfig: {},
27+
url: '/index.html',
28+
expected: path.resolve(__dirname, '../outputs/simple/index.html'),
29+
},
30+
{
31+
title: 'simple config with path /path',
32+
config: webpackSimpleConfig,
33+
middlewareConfig: {},
34+
url: '/path',
35+
expected: path.resolve(__dirname, '../outputs/simple/path'),
36+
},
37+
{
38+
title: 'simple config with path /path/file.html',
39+
config: webpackSimpleConfig,
40+
middlewareConfig: {},
41+
url: '/path/file.html',
42+
expected: path.resolve(__dirname, '../outputs/simple/path/file.html'),
43+
},
44+
{
45+
title: 'simple config with index false and path /',
46+
config: webpackSimpleConfig,
47+
middlewareConfig: {
48+
index: false,
49+
},
50+
url: '/',
51+
expected: path.resolve(__dirname, '../outputs/simple'),
52+
},
53+
{
54+
title: 'simple config with index file.html and path /',
55+
config: webpackSimpleConfig,
56+
middlewareConfig: {
57+
index: 'file.html',
58+
},
59+
url: '/',
60+
expected: path.resolve(__dirname, '../outputs/simple/file.html'),
61+
},
62+
63+
{
64+
title: 'publicPath config with path /',
65+
config: webpackPublicPathConfig,
66+
middlewareConfig: {},
67+
url: '/',
68+
expected: null,
69+
},
70+
{
71+
title: 'publicPath config with path /public/path/',
72+
config: webpackPublicPathConfig,
73+
middlewareConfig: {},
74+
url: '/public/path/',
75+
expected: path.resolve(__dirname, '../outputs/public-path/index.html'),
76+
},
77+
{
78+
title: 'publicPath config with path /public/path/more/file.html',
79+
config: webpackPublicPathConfig,
80+
middlewareConfig: {},
81+
url: '/public/path/more/file.html',
82+
expected: path.resolve(
83+
__dirname,
84+
'../outputs/public-path/more/file.html'
85+
),
86+
},
87+
88+
{
89+
title: 'multi config with path /',
90+
config: webpackMultiConfig,
91+
middlewareConfig: {},
92+
url: '/',
93+
expected: null,
94+
},
95+
{
96+
title: 'multi config with path /static-one/',
97+
config: webpackMultiConfig,
98+
middlewareConfig: {},
99+
url: '/static-one/',
100+
expected: path.resolve(__dirname, '../outputs/array/js1/index.html'),
101+
},
102+
{
103+
title: 'multi config with path /static-two/',
104+
config: webpackMultiConfig,
105+
middlewareConfig: {},
106+
url: '/static-two/',
107+
expected: path.resolve(__dirname, '../outputs/array/js2/index.html'),
108+
},
109+
];
110+
111+
configs.forEach((config) => {
112+
describe(config.title, () => {
113+
let instance;
114+
let listen;
115+
let app;
116+
let compiler;
117+
118+
beforeEach((done) => {
119+
compiler = getCompiler(config.config);
120+
121+
instance = middleware(compiler, config.middlewareConfig);
122+
123+
app = express();
124+
app.use(instance);
125+
126+
listen = listenAndCompile(app, compiler, done);
127+
});
128+
129+
afterEach((done) => {
130+
if (instance) {
131+
instance.close();
132+
}
133+
134+
if (listen) {
135+
listen.close(done);
136+
} else {
137+
done();
138+
}
139+
});
140+
141+
it('should return correct filename from url', () => {
142+
const filename = getFilenameFromUrl(instance.context, config.url);
143+
const { expected } = config;
144+
if (expected) {
145+
expect(filename).toEqual(expected);
146+
} else {
147+
expect(filename).toBeUndefined();
148+
}
149+
});
150+
});
151+
});
152+
});

test/utils/getPaths.test.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import path from 'path';
2+
3+
import express from 'express';
4+
5+
import middleware from '../../src';
6+
import getPaths from '../../src/utils/getPaths';
7+
8+
import getCompiler from '../helpers/getCompiler';
9+
import listenAndCompile from '../helpers/listenAndCompile';
10+
import webpackSimpleConfig from '../fixtures/webpack.simple.config';
11+
import webpackPublicPathConfig from '../fixtures/webpack.public-path.config';
12+
import webpackMultiConfig from '../fixtures/webpack.array.config';
13+
14+
describe('getPaths', () => {
15+
const configs = [
16+
{
17+
title: 'simple config',
18+
config: webpackSimpleConfig,
19+
expected: [
20+
{
21+
outputPath: path.resolve(__dirname, '../outputs/simple'),
22+
publicPath: '',
23+
},
24+
],
25+
},
26+
{
27+
title: 'publicPath config',
28+
config: webpackPublicPathConfig,
29+
expected: [
30+
{
31+
outputPath: path.resolve(__dirname, '../outputs/public-path'),
32+
publicPath: '/public/path/',
33+
},
34+
],
35+
},
36+
{
37+
title: 'multi config',
38+
config: webpackMultiConfig,
39+
expected: [
40+
{
41+
outputPath: path.resolve(__dirname, '../outputs/array/js1'),
42+
publicPath: '/static-one/',
43+
},
44+
{
45+
outputPath: path.resolve(__dirname, '../outputs/array/js2'),
46+
publicPath: '/static-two/',
47+
},
48+
],
49+
},
50+
];
51+
52+
configs.forEach((config) => {
53+
describe(config.title, () => {
54+
let instance;
55+
let listen;
56+
let app;
57+
let compiler;
58+
59+
beforeEach((done) => {
60+
compiler = getCompiler(config.config);
61+
62+
instance = middleware(compiler);
63+
64+
app = express();
65+
app.use(instance);
66+
67+
listen = listenAndCompile(app, compiler, done);
68+
});
69+
70+
afterEach((done) => {
71+
if (instance) {
72+
instance.close();
73+
}
74+
75+
if (listen) {
76+
listen.close(done);
77+
} else {
78+
done();
79+
}
80+
});
81+
82+
it('should return correct paths', () => {
83+
expect(getPaths(instance.context)).toEqual(config.expected);
84+
});
85+
});
86+
});
87+
});

0 commit comments

Comments
 (0)