Skip to content

Commit 69f8f3c

Browse files
yanneveslgandecki
authored andcommitted
fix: addressed cases where options passed to preprocessor would result in a TypeError
fixes #345
1 parent 36d6d9c commit 69f8f3c

File tree

2 files changed

+139
-14
lines changed

2 files changed

+139
-14
lines changed

lib/index.js

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,51 @@ const touch = filename => {
3737

3838
let watcher;
3939

40-
const preprocessor = (options = browserify.defaultOptions) => async file => {
41-
if (options.browserifyOptions.transform.indexOf(transform) === -1) {
42-
options.browserifyOptions.transform.unshift(transform);
40+
// Include our transform in Browserify options
41+
const wrapOptions = options => {
42+
let wrappedTransform;
43+
if (
44+
!options.browserifyOptions ||
45+
!Array.isArray(options.browserifyOptions.transform)
46+
) {
47+
wrappedTransform = [transform];
48+
} else if (!options.browserifyOptions.transform.includes(transform)) {
49+
wrappedTransform = [transform, ...options.browserifyOptions.transform];
50+
} else {
51+
wrappedTransform = options.browserifyOptions.transform;
4352
}
4453

45-
if (file.shouldWatch) {
46-
if (watcher) {
47-
watcher.close();
54+
return {
55+
...options,
56+
browserifyOptions: {
57+
...(options.browserifyOptions || {}),
58+
transform: wrappedTransform
4859
}
49-
watcher = chokidar
50-
.watch([`${stepDefinitionPath()}*.js`, `${stepDefinitionPath()}*.ts`], {
51-
ignoreInitial: true
52-
})
53-
.on("all", () => {
54-
touch(file.filePath);
55-
});
60+
};
61+
};
62+
63+
const preprocessor = (options = browserify.defaultOptions) => {
64+
if (typeof options !== "object") {
65+
throw new Error("Preprocessor options must be an object");
5666
}
57-
return browserify(options)(file);
67+
68+
const wrappedOptions = wrapOptions(options);
69+
70+
return async file => {
71+
if (file.shouldWatch) {
72+
if (watcher) {
73+
watcher.close();
74+
}
75+
watcher = chokidar
76+
.watch([`${stepDefinitionPath()}*.js`, `${stepDefinitionPath()}*.ts`], {
77+
ignoreInitial: true
78+
})
79+
.on("all", () => {
80+
touch(file.filePath);
81+
});
82+
}
83+
return browserify(wrappedOptions)(file);
84+
};
5885
};
5986

6087
module.exports = {

lib/index.test.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
const browserify = require("@cypress/browserify-preprocessor");
2+
const { default: preprocessor, transform } = require(".");
3+
4+
jest.mock("@cypress/browserify-preprocessor");
5+
const { defaultOptions } = jest.requireActual(
6+
"@cypress/browserify-preprocessor"
7+
);
8+
9+
describe("Preprocessor", () => {
10+
beforeEach(() => {
11+
browserify.defaultOptions = defaultOptions;
12+
browserify.mockReturnValue(() => {});
13+
});
14+
15+
afterEach(() => {
16+
browserify.mockClear();
17+
});
18+
19+
it("should use Cypress browserify options by default", async () => {
20+
await preprocessor()({ shouldWatch: false });
21+
22+
global.jestExpect(browserify).toHaveBeenCalledWith({
23+
...defaultOptions,
24+
browserifyOptions: {
25+
...defaultOptions.browserifyOptions,
26+
transform: [transform, ...defaultOptions.browserifyOptions.transform]
27+
}
28+
});
29+
});
30+
31+
it("should add transform when other transforms are defined in options", async () => {
32+
await preprocessor({
33+
browserifyOptions: {
34+
transform: ["babelify"]
35+
}
36+
})({ shouldWatch: false });
37+
38+
global.jestExpect(browserify).toHaveBeenCalledWith({
39+
browserifyOptions: {
40+
transform: [transform, "babelify"]
41+
}
42+
});
43+
});
44+
45+
it("should preserve transforms in options when our transform is already included", async () => {
46+
const options = {
47+
browserifyOptions: {
48+
extensions: ["js", "ts"],
49+
plugins: [["tsify"]],
50+
transform: ["aliasify", transform, "babelify"]
51+
}
52+
};
53+
54+
await preprocessor(options)({ shouldWatch: false });
55+
56+
global.jestExpect(browserify).toHaveBeenCalledWith(options);
57+
});
58+
59+
it("should add our transform when no other transforms are defined in options", async () => {
60+
const options = {
61+
browserifyOptions: {
62+
extensions: ["js", "ts"],
63+
plugins: [["tsify"]]
64+
}
65+
};
66+
67+
await preprocessor(options)({ shouldWatch: false });
68+
69+
global.jestExpect(browserify).toHaveBeenCalledWith({
70+
...options,
71+
browserifyOptions: {
72+
...options.browserifyOptions,
73+
transform: [transform]
74+
}
75+
});
76+
});
77+
78+
it("should add our transform when browserifyOptions property is not passed to options", async () => {
79+
const options = { unsupported: true };
80+
81+
await preprocessor(options)({ shouldWatch: false });
82+
83+
global.jestExpect(browserify).toHaveBeenCalledWith({
84+
...options,
85+
browserifyOptions: {
86+
transform: [transform]
87+
}
88+
});
89+
});
90+
91+
it("should fail gracefully when options is not an object", () => {
92+
const err = new Error("Preprocessor options must be an object");
93+
94+
global.jestExpect(() => preprocessor("options")).toThrow(err);
95+
global.jestExpect(() => preprocessor(1)).toThrow(err);
96+
global.jestExpect(() => preprocessor(false)).toThrow(err);
97+
});
98+
});

0 commit comments

Comments
 (0)