1 | const pify = require('pify');
|
2 | const childProcess = require('child_process');
|
3 | const {exec} = pify(childProcess);
|
4 | const path = require('path');
|
5 | const tempy = require('tempy');
|
6 | const invert = require('invert-promise');
|
7 |
|
8 | jest.mock('../index');
|
9 |
|
10 | const BINARY_PATH = path.resolve(__dirname, 'carmi');
|
11 | const MOCKED_BINARY_PATH = path.resolve(__dirname, '__mocks__/carmi');
|
12 | const CARMI_MODEL = path.resolve(
|
13 | __dirname,
|
14 | '..',
|
15 | 'src',
|
16 | 'babelPlugin',
|
17 | 'test.carmi.js'
|
18 | );
|
19 |
|
20 | const runBinary = args => exec(`${BINARY_PATH} ${args}`);
|
21 | const getCompileCalls = (args, {cacheDir, withRandomGitHash, errorStage}) =>
|
22 | new Promise((resolve, reject) => {
|
23 | const child = childProcess.fork(MOCKED_BINARY_PATH, args.split(' '), {
|
24 | env: {
|
25 | CACHE_DIR: cacheDir,
|
26 | ERROR_STAGE: errorStage,
|
27 | RANDOM_GIT_HASH: withRandomGitHash
|
28 | }
|
29 | });
|
30 | let compileCalls = 0;
|
31 | child.on('message', name => name === 'carmi:compile' && compileCalls++);
|
32 | child.on('error', error => reject(error));
|
33 | child.on('exit', () => resolve(compileCalls));
|
34 | });
|
35 |
|
36 | describe('carmi binary', () => {
|
37 | it('has a help menu', async () => {
|
38 | const helpMessage = await runBinary('--help');
|
39 | expect(helpMessage).toMatch(/shows this very help message/);
|
40 | });
|
41 |
|
42 | it('compiles a carmi file', async () => {
|
43 | const file = await runBinary(`--source ${CARMI_MODEL}`)
|
44 |
|
45 | const model = new Function(`${file}; return model`)()
|
46 | expect(typeof model).toBe('function');
|
47 | });
|
48 |
|
49 | it('saves the file', async () => {
|
50 | const filepath = tempy.file({extension: 'js'})
|
51 | const file = await runBinary(
|
52 | `--source ${CARMI_MODEL} --output ${filepath} --format cjs --no-cache`
|
53 | );
|
54 | const model = require(filepath);
|
55 |
|
56 | expect(typeof model).toBe('function');
|
57 | });
|
58 |
|
59 | it('exits with exit code 1 in case carmi fails', async () => {
|
60 | const error = await invert(runBinary(
|
61 | '--source dummy.js --output irrelevant --format cjs'
|
62 | ));
|
63 |
|
64 | expect(error.code).toBe(1);
|
65 | });
|
66 |
|
67 | describe('caching', () => {
|
68 | let carmiCompileCalls;
|
69 | let cacheDir;
|
70 | beforeEach(() => {
|
71 | carmiCompileCalls = 0;
|
72 | cacheDir = tempy.directory();
|
73 | })
|
74 |
|
75 | it('gets result from cache for same options', async () => {
|
76 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug`, {cacheDir});
|
77 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug`, {cacheDir});
|
78 |
|
79 | expect(carmiCompileCalls).toBe(1);
|
80 | });
|
81 |
|
82 | it('works with `cache-scenario=mtime` param result from cache for same options', async () => {
|
83 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=mtime`, {cacheDir});
|
84 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=mtime`, {cacheDir});
|
85 |
|
86 | expect(carmiCompileCalls).toBe(1);
|
87 | });
|
88 |
|
89 | it('works with `cache-scenario=git-hash` result from cache if file has the same git hash', async () => {
|
90 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir});
|
91 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir});
|
92 |
|
93 | expect(carmiCompileCalls).toBe(1);
|
94 | });
|
95 |
|
96 | it('works with `cache-scenario=git-hash` result from cache if file has different git hashes', async () => {
|
97 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir});
|
98 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir, withRandomGitHash: true});
|
99 |
|
100 | expect(carmiCompileCalls).toBe(2);
|
101 | });
|
102 |
|
103 | it('uses fallback tos `cache-scenario=mtime` if `git ls-tree` command failed', async () => {
|
104 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir, errorStage: 'git-hash'});
|
105 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs --debug --cache-scenario=git-hash`, {cacheDir, errorStage: 'git-hash'});
|
106 |
|
107 | expect(carmiCompileCalls).toBe(1);
|
108 | });
|
109 |
|
110 | it('doesn\'t get result from cache if debug argument was changed', async () => {
|
111 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --debug`, {cacheDir});
|
112 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL}`, {cacheDir});
|
113 |
|
114 | expect(carmiCompileCalls).toBe(2);
|
115 | });
|
116 |
|
117 | it('doesn\'t override cache for different options', async () => {
|
118 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs`, {cacheDir});
|
119 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format iife`, {cacheDir});
|
120 | carmiCompileCalls += await getCompileCalls(`--source ${CARMI_MODEL} --format cjs`, {cacheDir});
|
121 |
|
122 | expect(carmiCompileCalls).toBe(2);
|
123 | });
|
124 | });
|
125 | });
|