Skip to content

Commit 7b86a50

Browse files
committed
More tests for serveStatic
1 parent da49431 commit 7b86a50

2 files changed

Lines changed: 204 additions & 74 deletions

File tree

lib/server/utils.js

Lines changed: 119 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var Immutable = require("immutable");
77
var http = require("http");
88
var https = require("https");
99
var Map = require("immutable").Map;
10+
var fromJS = require("immutable").fromJS;
11+
var List = require("immutable").List;
1012
var snippet = require("./../snippet").utils;
1113
var _ = require("./../../lodash.custom");
1214
var serveStatic = require("serve-static");
@@ -86,18 +88,18 @@ var utils = {
8688
if (options.get("serveStatic")) {
8789

8890
var ssMiddlewares = utils.getServeStaticMiddlewares(options.get("serveStatic"), options.get("serveStaticOptions", Immutable.Map({})).toJS());
89-
var withErrors = ssMiddlewares.filter(function(x) { return x.errors.length > 0 });
90-
var withoutErrors = ssMiddlewares.filter(function(x) { return x.errors.length === 0 });
91+
var withErrors = ssMiddlewares.filter(function(x) { return x.get("errors").size > 0 });
92+
var withoutErrors = ssMiddlewares.filter(function(x) { return x.get("errors").size === 0 });
9193

9294
if (withErrors.size) {
9395
withErrors.forEach(function (item) {
94-
logger.logger.error("{red:Warning!} %s", item.errors[0].data.message);
96+
logger.logger.error("{red:Warning!} %s", item.getIn(["errors", 0, "data", "message"]));
9597
});
9698
}
9799

98100
if (withoutErrors.size) {
99101
withoutErrors.forEach(function (item) {
100-
defaultMiddlewares.push.apply(defaultMiddlewares, item.items);
102+
defaultMiddlewares.push.apply(defaultMiddlewares, item.get("items").toJS());
101103
});
102104
}
103105
}
@@ -174,82 +176,134 @@ var utils = {
174176

175177
return ssOption.map(function (dir, i) {
176178

177-
if (Immutable.Map.isMap(dir)) {
178-
179-
var ssOptions = (function () {
180-
if (dir.get("options")) {
181-
return dir.get("options").toJS();
182-
}
183-
return {}
184-
})();
185-
186-
var route = dir.get("route");
187-
var _dir = dir.get("dir");
188-
189-
if (!isValidOption(route) || !isValidOption(_dir)) {
190-
return {
191-
items: [],
192-
errors: [{
193-
type: "Invalid Object",
194-
data: {
195-
message: "Serve Static requires both 'route' and 'dir' options when using an Object"
196-
}
197-
}]
198-
}
199-
}
200-
201-
var ssItems = (function () {
202-
if (_.isString(route)) {
203-
return [{
204-
id: "Serve static " + i,
205-
route: getRoute(route),
206-
handle: serveStatic(_dir, ssOptions)
207-
}]
208-
}
209-
return route.map(function (item, j) {
210-
return {
211-
id: "Serve static " + i + "." + j,
212-
route: getRoute(item),
213-
handle: serveStatic(_dir, ssOptions)
214-
}
215-
}).toJS()
216-
})();
217-
return {
218-
items: ssItems,
219-
errors: []
220-
};
179+
/**
180+
* When a user gives a plain string only, eg:
181+
* serveStatic: ['./temp']
182+
* ->
183+
* This means a middleware will be created with
184+
* route: ''
185+
* handle: serveStatic('./temp', options)
186+
*/
187+
if (_.isString(dir)) {
188+
return getFromString(dir)
221189
}
222190

223-
if (_.isString(dir)) {
224-
return {
225-
items: [
226-
{
227-
id: "Serve static " + i,
228-
route: "",
229-
handle: serveStatic(dir, serveStaticOptions)
230-
}
231-
],
232-
errors: []
233-
}
191+
/**
192+
* If a user gave an object eg:
193+
* serveStatic: [{route: "", dir: ["test", "./tmp"]}]
194+
* ->
195+
* This means we need to create a middle for each route + dir combo
196+
*/
197+
if (Immutable.Map.isMap(dir)) {
198+
return getFromMap(dir, i);
234199
}
235200

236-
return {
201+
/**
202+
* At this point, an item in the serveStatic array was not a string
203+
* or an object so we return an error that can be logged
204+
*/
205+
return fromJS({
237206
items: [],
238207
errors: [{
239208
type: "Invalid Type",
240209
data: {
241210
message: "Only strings and Objects (with route+dir) are supported for the ServeStatic option"
242211
}
243212
}]
244-
}
213+
})
245214
});
246-
function isValidOption (x) {
247-
return _.isString(x) || (_.isArray(x) && x.length > 0) || (Immutable.List.isList(x) && x.size > 0);
248-
}
249215
function getRoute (x) {
250-
if (x === '') return '';
216+
if (x === "") return "";
251217
return x[0] === "/" ? x : "/" + x;
252218
}
219+
function getFromString(dir) {
220+
return fromJS({
221+
items: [
222+
{
223+
route: "",
224+
handle: serveStatic(dir, serveStaticOptions)
225+
}
226+
],
227+
errors: []
228+
})
229+
}
230+
function getFromMap(dir) {
231+
232+
var ssOptions = (function () {
233+
if (dir.get("options")) {
234+
return dir.get("options").toJS();
235+
}
236+
return {}
237+
})();
238+
239+
var route = Immutable.List([]).concat(dir.get("route")).filter(_.isString);
240+
var _dir = Immutable.List([]).concat(dir.get("dir")).filter(_.isString);
241+
242+
if (_dir.size === 0) {
243+
244+
return fromJS({
245+
items: [],
246+
errors: [{
247+
type: "Invalid Object",
248+
data: {
249+
message: "Serve Static requires a 'dir' property when using an Object"
250+
}
251+
}]
252+
})
253+
}
254+
255+
var ssItems = (function () {
256+
257+
/**
258+
* iterate over every 'route' item
259+
* @type {Immutable.List<any>|Immutable.List<*>|Immutable.List<any>|*}
260+
*/
261+
var routeItems = (function () {
262+
263+
/**
264+
* If no 'route' was given, assume we want to match all
265+
* paths
266+
*/
267+
if (route.size === 0) {
268+
return _dir.map(function (dirString) {
269+
return Map({
270+
route: "",
271+
dir: dirString
272+
});
273+
});
274+
}
275+
276+
return route.reduce(function (acc, routeString) {
277+
/**
278+
* For each 'route' item, also iterate through 'dirs'
279+
* @type {Immutable.Iterable<K, M>}
280+
*/
281+
var perDir = _dir.map(function (dirString) {
282+
return Map({
283+
route: getRoute(routeString),
284+
dir: dirString
285+
})
286+
});
287+
return acc.concat(perDir);
288+
289+
}, List([]));
290+
})();
291+
292+
/**
293+
* Now create a serverStatic Middleware for each item
294+
*/
295+
return routeItems.map(function (routeItem) {
296+
return routeItem.merge({
297+
handle: serveStatic(routeItem.get("dir"), ssOptions)
298+
});
299+
});
300+
})();
301+
302+
return fromJS({
303+
items: ssItems,
304+
errors: []
305+
});
306+
}
253307
}
254308
};
255309

test/specs/e2e/e2e.options.serveStatic.js

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var browserSync = require("../../../index");
55
var request = require("supertest");
66
var page = require("fs").readFileSync("test/fixtures/index.html", "utf-8");
77
var css = require("fs").readFileSync("test/fixtures/assets/style.css", "utf-8");
8-
var Rx = require('rx');
8+
var Rx = require("rx");
99

1010
function getRequests (reqs, server) {
1111
return reqs.map(function (req) {
@@ -37,7 +37,6 @@ describe("E2E `serveStatic` option", function () {
3737
online: false,
3838
serveStatic: ["test/fixtures"]
3939
};
40-
4140
browserSync(config, function (err, bs) {
4241
request(bs.server)
4342
.get("/index.html")
@@ -57,7 +56,10 @@ describe("E2E `serveStatic` option", function () {
5756
browserSync(config, function (err, bs) {
5857
var reqs = getRequests([["/index.html", page], ["/style.css", css]], bs.server);
5958
var obs = Rx.Observable.merge(reqs);
60-
obs.subscribeOnCompleted(done);
59+
obs.subscribeOnCompleted(function () {
60+
bs.cleanup();
61+
done();
62+
});
6163
});
6264
});
6365
it("can serve static files with multiple objects", function (done) {
@@ -71,9 +73,12 @@ describe("E2E `serveStatic` option", function () {
7173
]
7274
};
7375
browserSync(config, function (err, bs) {
74-
var reqs = getRequests([['/index.html', page], ['/style.css', css]], bs.server);
76+
var reqs = getRequests([["/index.html", page], ["/style.css", css]], bs.server);
7577
var obs = Rx.Observable.merge(reqs);
76-
obs.subscribeOnCompleted(done);
78+
obs.subscribeOnCompleted(function () {
79+
bs.cleanup();
80+
done();
81+
});
7782
});
7883
});
7984
it("can serve static files with multiple roots", function (done) {
@@ -89,12 +94,83 @@ describe("E2E `serveStatic` option", function () {
8994
};
9095
browserSync(config, function (err, bs) {
9196
var reqs = getRequests([
92-
['/index.html', page],
93-
['/shane/style.css', css],
94-
['/kittie/style.css', css]
97+
["/index.html", page],
98+
["/shane/style.css", css],
99+
["/kittie/style.css", css]
100+
], bs.server);
101+
var obs = Rx.Observable.merge(reqs);
102+
obs.subscribeOnCompleted(function () {
103+
bs.cleanup();
104+
done();
105+
});
106+
});
107+
});
108+
it("can serve static files with multiple dirs", function (done) {
109+
browserSync.reset();
110+
var config = {
111+
logLevel: "silent",
112+
online: false,
113+
serveStatic: [
114+
{route: "", dir: ["test/fixtures", "test/fixtures/assets"]}
115+
]
116+
};
117+
browserSync(config, function (err, bs) {
118+
var reqs = getRequests([
119+
["/index.html", page],
120+
["/style.css", css]
121+
], bs.server);
122+
var obs = Rx.Observable.merge(reqs);
123+
obs.subscribeOnCompleted(function () {
124+
bs.cleanup();
125+
done();
126+
});
127+
});
128+
});
129+
it("can serve static files with dir + NO route", function (done) {
130+
browserSync.reset();
131+
var config = {
132+
logLevel: "silent",
133+
online: false,
134+
serveStatic: [
135+
{dir: ["test/fixtures", "test/fixtures/assets"]}
136+
]
137+
};
138+
browserSync(config, function (err, bs) {
139+
var reqs = getRequests([
140+
["/index.html", page],
141+
["/style.css", css]
142+
], bs.server);
143+
var obs = Rx.Observable.merge(reqs);
144+
obs.subscribeOnCompleted(function () {
145+
bs.cleanup();
146+
done();
147+
});
148+
});
149+
});
150+
it("can serve static files with mix of inputs", function (done) {
151+
browserSync.reset();
152+
var config = {
153+
logLevel: "silent",
154+
online: false,
155+
serveStatic: [
156+
"test/fixtures",
157+
{dir: ["test/fixtures/assets"]},
158+
{route: "shane", dir: ["test/fixtures"]},
159+
{route: ["shane", "kittie"], dir: ["test/fixtures"]}
160+
]
161+
};
162+
browserSync(config, function (err, bs) {
163+
var reqs = getRequests([
164+
["/index.html", page],
165+
["/style.css", css],
166+
["/shane/index.html", page],
167+
["/kittie/assets/style.css", css]
95168
], bs.server);
96169
var obs = Rx.Observable.merge(reqs);
97-
obs.subscribeOnCompleted(done);
170+
obs.subscribeOnCompleted(function () {
171+
bs.cleanup();
172+
done();
173+
});
98174
});
99175
});
100176
});

0 commit comments

Comments
 (0)