Skip to content

Commit 53431ef

Browse files
author
Mateusz Krzeszowiak
committed
Add tests
1 parent 46cdf25 commit 53431ef

11 files changed

+3285
-458
lines changed

lib/bundle.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,20 @@ module.exports = async (bundlingConfigPath) => {
5959
encoding: 'utf8',
6060
});
6161

62-
if (!modulePath.endsWith('.js')) {
62+
if (moduleWrapper.isText(modulePath)) {
6363
moduleContents = moduleWrapper.wrapText(
6464
moduleName,
6565
moduleContents
6666
);
67-
} else if (!moduleContents.match(/define\s*\(/m)) {
67+
} else if (moduleWrapper.isNonAmd(moduleContents)) {
6868
moduleContents = moduleWrapper.wrapNonAmd(
6969
moduleName,
7070
moduleContents
7171
);
72-
} else if (!moduleContents.match(/define\s*\(\s*['"]/m)) {
73-
moduleContents = moduleContents.replace(
74-
/define\s*\(/m,
75-
`define('${moduleName}', `
72+
} else if (moduleWrapper.isAnonymousAmd(moduleContents)) {
73+
moduleContents = moduleWrapper.wrapAnonymousAmd(
74+
moduleName,
75+
moduleContents
7676
);
7777
}
7878

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`moduleWrapper module wrapAnonymousAmd output matches snapshot 1`] = `"define('foo', [], function() {});"`;
4+
5+
exports[`moduleWrapper module wrapNonAmd output matches snapshot 1`] = `
6+
"define('name', (require.s.contexts._.config.shim['name'] && require.s.contexts._.config.shim['name'].deps || []), function() {
7+
8+
true;
9+
10+
return (require.s.contexts._.config.shim['name'] && require.s.contexts._.config.shim['name'].exportsFn && require.s.contexts._.config.shim['name'].exportsFn());
11+
}.bind(window));"
12+
`;
13+
14+
exports[`moduleWrapper module wrapText output matches snapshot 1`] = `
15+
"define('name', function() {
16+
return 'true;';
17+
});"
18+
`;
19+
20+
exports[`moduleWrapper module wrapText output matches snapshot for escaped content 1`] = `
21+
"define('name', function() {
22+
return '<div>\\"Hello\\"</div>';
23+
});"
24+
`;

lib/bundle/checkMinifyOn.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ const path = require('path');
55
* Tells if minification is enabled in Magento.
66
*
77
* @param {string[]} localesPaths List of paths to locales.
8-
* @returns {bool}
8+
* @returns {boolean}
99
*/
1010
const checkMinifyOn = (localesPaths) =>
11-
localesPaths[0] &&
11+
Boolean(localesPaths[0]) &&
1212
fs.existsSync(path.join(localesPaths[0], 'requirejs-config.min.js'));
1313

1414
module.exports = checkMinifyOn;

lib/bundle/checkMinifyOn.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
jest.mock('fs');
2+
3+
const fs = require('fs');
4+
const checkMinifyOn = require('./checkMinifyOn');
5+
6+
describe('checkMinifyOn utility', () => {
7+
test('is a function', () => {
8+
expect(typeof checkMinifyOn).toEqual('function');
9+
});
10+
11+
test('returns true when minified configuration file exists', () => {
12+
fs.existsSync.mockReturnValue(true);
13+
14+
expect(checkMinifyOn(['pub/static/frontend/Magento/luma'])).toEqual(
15+
true
16+
);
17+
});
18+
19+
test('returns false when minified configuration file does not exist', () => {
20+
fs.existsSync.mockReturnValue(false);
21+
22+
expect(checkMinifyOn(['pub/static/frontend/Magento/luma'])).toEqual(
23+
false
24+
);
25+
});
26+
27+
test('returns false no locales were provided', () => {
28+
fs.existsSync.mockReturnValue(false);
29+
30+
expect(checkMinifyOn([])).toEqual(false);
31+
});
32+
});

lib/bundle/getLocales.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
jest.mock('glob');
2+
jest.mock('fs');
3+
4+
const glob = require('glob');
5+
const fs = require('fs');
6+
const getLocales = require('./getLocales');
7+
8+
describe('getLocales utility', () => {
9+
test('is a function', () => {
10+
expect(typeof getLocales).toEqual('function');
11+
});
12+
13+
test('returns found locales', () => {
14+
glob.sync.mockReturnValue(['pub/static/frontend/Magento/luma']);
15+
fs.existsSync.mockReturnValue(true);
16+
17+
expect(getLocales()).toEqual(['pub/static/frontend/Magento/luma']);
18+
});
19+
20+
test('returns found locales excluding blank theme', () => {
21+
glob.sync.mockReturnValue([
22+
'pub/static/frontend/Magento/luma',
23+
'pub/static/frontend/Magento/blank',
24+
]);
25+
fs.existsSync.mockReturnValue(true);
26+
27+
expect(getLocales()).toEqual(['pub/static/frontend/Magento/luma']);
28+
});
29+
30+
test('throws error when locales are found but have no requirejs-config.js file', () => {
31+
glob.sync.mockReturnValue([]);
32+
fs.existsSync.mockReturnValue(false);
33+
34+
expect(() => getLocales()).toThrow();
35+
});
36+
37+
test('throws error when no locales are found', () => {
38+
glob.sync.mockReturnValue([]);
39+
40+
expect(() => getLocales()).toThrow();
41+
});
42+
});

lib/bundle/moduleWrapper.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
const jsesc = require('jsesc');
22

3+
/**
4+
* Tells if given module is a non-AMD JavaScript code.
5+
*
6+
* @param {string} moduleContents Contents of the module.
7+
*/
8+
const isNonAmd = (moduleContents) => !moduleContents.match(/define\s*\(/m);
9+
310
/**
411
* Wraps non-AMD module so it can be safely inlined into the bundle.
512
*
@@ -17,7 +24,14 @@ const wrapNonAmd = (moduleName, content) => {
1724
};
1825

1926
/**
20-
* Wraps a text module (HTML, JSON, etc.) so it can be safely inline into the bundle.
27+
* Tells if given module is a text type.
28+
*
29+
* @param {string} modulePath Module path.
30+
*/
31+
const isText = (modulePath) => !modulePath.endsWith('.js');
32+
33+
/**
34+
* Wraps a text module (HTML, JSON, etc.) so it can be safely inlined into the bundle.
2135
*
2236
* @param {string} moduleName Name of the AMD module.
2337
* @param {string} content Contents of the module to wrap.
@@ -30,4 +44,28 @@ const wrapText = (moduleName, content) => {
3044
});`;
3145
};
3246

33-
module.exports = { wrapNonAmd, wrapText };
47+
/**
48+
* Tells if given module contains anonymous AMD module definition.
49+
*
50+
* @param {string} moduleContents Contents of the module to wrap.
51+
*/
52+
const isAnonymousAmd = (moduleContents) =>
53+
!moduleContents.match(/define\s*\(\s*['"]/m);
54+
55+
/**
56+
* Changes anonymous AMD module into the named one to be able to bundle it.
57+
*
58+
* @param {string} moduleName Name of the module.
59+
* @param {string} moduleContents Contents of the module to wrap.
60+
*/
61+
const wrapAnonymousAmd = (moduleName, moduleContents) =>
62+
moduleContents.replace(/define\s*\(/m, `define('${moduleName}', `);
63+
64+
module.exports = {
65+
isNonAmd,
66+
wrapNonAmd,
67+
isText,
68+
wrapText,
69+
isAnonymousAmd,
70+
wrapAnonymousAmd,
71+
};

lib/bundle/moduleWrapper.test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
const moduleWrapper = require('./moduleWrapper');
2+
3+
describe('moduleWrapper module', () => {
4+
describe('isNonAmd', () => {
5+
test('is a function', () => {
6+
expect(typeof moduleWrapper.isNonAmd).toEqual('function');
7+
});
8+
9+
test('returns true when module is a non-AMD JavaScript module', () => {
10+
expect(moduleWrapper.isNonAmd('(function() {}());')).toBe(true);
11+
});
12+
13+
test('returns false when module is an AMD JavaScript module', () => {
14+
expect(moduleWrapper.isNonAmd('define([], function() {})')).toBe(
15+
false
16+
);
17+
});
18+
});
19+
20+
describe('wrapNonAmd', () => {
21+
test('is a function', () => {
22+
expect(typeof moduleWrapper.wrapNonAmd).toEqual('function');
23+
});
24+
25+
test('output matches snapshot', () => {
26+
expect(moduleWrapper.wrapNonAmd('name', 'true;')).toMatchSnapshot();
27+
});
28+
});
29+
30+
describe('isText', () => {
31+
test('is a function', () => {
32+
expect(typeof moduleWrapper.isText).toEqual('function');
33+
});
34+
35+
test('returns true when module is a text module', () => {
36+
expect(moduleWrapper.isText('test.html')).toBe(true);
37+
});
38+
39+
test('returns false when module is a JavaScript module', () => {
40+
expect(moduleWrapper.isText('test.js')).toBe(false);
41+
});
42+
});
43+
44+
describe('wrapText', () => {
45+
test('is a function', () => {
46+
expect(typeof moduleWrapper.wrapText).toEqual('function');
47+
});
48+
49+
test('output matches snapshot', () => {
50+
expect(moduleWrapper.wrapText('name', 'true;')).toMatchSnapshot();
51+
});
52+
53+
test('output matches snapshot for escaped content', () => {
54+
expect(
55+
moduleWrapper.wrapText('name', '<div>"Hello"</div>')
56+
).toMatchSnapshot();
57+
});
58+
});
59+
60+
describe('isAnonymousAmd', () => {
61+
test('is a function', () => {
62+
expect(typeof moduleWrapper.isAnonymousAmd).toEqual('function');
63+
});
64+
65+
test('returns true when module is an anonymous AMD module', () => {
66+
expect(
67+
moduleWrapper.isAnonymousAmd('define([], function() {});')
68+
).toBe(true);
69+
});
70+
71+
test('returns false when module is a named AMD module', () => {
72+
expect(
73+
moduleWrapper.isAnonymousAmd(
74+
'define("foo", [], function() {});'
75+
)
76+
).toBe(false);
77+
});
78+
});
79+
80+
describe('wrapAnonymousAmd', () => {
81+
test('is a function', () => {
82+
expect(typeof moduleWrapper.wrapAnonymousAmd).toEqual('function');
83+
});
84+
85+
test('output matches snapshot', () => {
86+
expect(
87+
moduleWrapper.wrapAnonymousAmd(
88+
'foo',
89+
'define([], function() {});'
90+
)
91+
).toMatchSnapshot();
92+
});
93+
});
94+
});

lib/bundle/pathResolver.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const pathResolver = require('./pathResolver');
2+
3+
describe('pathResolver module', () => {
4+
describe('getBundlePath', () => {
5+
test('is a function', () => {
6+
expect(typeof pathResolver.getBundlePath).toEqual('function');
7+
});
8+
9+
test('returns proper path when minification is turned off', () => {
10+
expect(pathResolver.getBundlePath('', 'foo', false)).toBe(
11+
'magepack/bundle-foo.js'
12+
);
13+
});
14+
15+
test('returns proper path when minification is turned on', () => {
16+
expect(pathResolver.getBundlePath('', 'foo', true)).toBe(
17+
'magepack/bundle-foo.min.js'
18+
);
19+
});
20+
});
21+
});

lib/utils/stripPlugin.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const stripPlugin = require('./stripPlugin');
2+
3+
describe('stripPlugin utility', () => {
4+
test('is a function', () => {
5+
expect(typeof stripPlugin).toEqual('function');
6+
});
7+
8+
test('removes plugin prefix from given module name', () => {
9+
expect(stripPlugin('plugin!module')).toEqual('module');
10+
});
11+
12+
test('does nothing for modules without plugins', () => {
13+
expect(stripPlugin('module')).toEqual('module');
14+
});
15+
});

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"author": "creativestyle",
77
"license": "OSL-2.0",
88
"main": "index.js",
9+
"scripts": {
10+
"test": "jest"
11+
},
912
"engines": {
1013
"node": ">=10"
1114
},
@@ -37,8 +40,8 @@
3740
"eslintConfig": {
3841
"env": {
3942
"node": true,
40-
"jasmine": true,
41-
"es6": true
43+
"es6": true,
44+
"jest": true
4245
},
4346
"extends": [
4447
"eslint:recommended",
@@ -59,6 +62,7 @@
5962
"eslint-config-prettier": "^6.10.1",
6063
"eslint-plugin-prettier": "^3.1.2",
6164
"husky": "^4.2.3",
65+
"jest": "^26.1.0",
6266
"lint-staged": "^10.1.0",
6367
"prettier": "^2.0.2"
6468
},

0 commit comments

Comments
 (0)