Skip to content

Commit

Permalink
(fix/test): resolve reproducibility issues w/ execWithCache
Browse files Browse the repository at this point in the history
- had removed some duplicate execs in the previous commit in order to
  speed up tests so that exec wouldn't need to be re-run
  - but this caused reproducibility issues, as if you change a test
    to `it.only` temporarily, it would fail hard as nothing would be
    exec'd if it weren't the first test
    - this uses an `execWithCache` function to instead naive "cache"
      the output and not re-run the same command twice-in-a-row
      - only works with sequential tests, but good enough for now
      - similar to a beforeAll() for a group of the same test, but no
        nesting or confusing variables in describe scope

- N.B. no need for stageName in cache function or something more
  complex because each stage is parallelized as multi-process
  • Loading branch information
agilgur5 committed Mar 25, 2020
1 parent 05e5b64 commit d234dff
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
13 changes: 11 additions & 2 deletions test/tests/tsdx-build-default.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const shell = require('shelljs');
const util = require('../fixtures/util');
const { execWithCache } = require('../utils/shell');

shell.config.silent = false;

Expand All @@ -13,7 +14,7 @@ describe('tsdx build :: zero-config defaults', () => {
});

it('should compile files into a dist directory', () => {
const output = shell.exec('node ../dist/index.js build');
const output = execWithCache('node ../dist/index.js build');

expect(shell.test('-f', 'dist/index.js')).toBeTruthy();
expect(
Expand All @@ -30,16 +31,24 @@ describe('tsdx build :: zero-config defaults', () => {
});

it('should create the library correctly', () => {
const output = execWithCache('node ../dist/index.js build');

const lib = require(`../../${stageName}/dist`);
expect(lib.foo()).toBe('bar');
expect(lib.__esModule).toBe(true);

expect(output.code).toBe(0);
});

it('should clean the dist directory before rebuilding', () => {
let output = execWithCache('node ../dist/index.js build');
expect(output.code).toBe(0);

shell.mv('package.json', 'package-og.json');
shell.mv('package2.json', 'package.json');

const output = shell.exec('node ../dist/index.js build');
// cache bust because we want to re-run this command with new package.json
output = execWithCache('node ../dist/index.js build', { noCache: true });
expect(shell.test('-f', 'dist/index.js')).toBeTruthy();

// build-default files have been cleaned out
Expand Down
9 changes: 5 additions & 4 deletions test/tests/tsdx-build-invalid.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const shell = require('shelljs');
const util = require('../fixtures/util');
const { execWithCache } = require('../utils/shell');

shell.config.silent = false;

Expand All @@ -13,12 +14,12 @@ describe('tsdx build :: invalid build', () => {
});

it('should fail gracefully with exit code 1 when build failed', () => {
const code = shell.exec('node ../dist/index.js build').code;
expect(code).toBe(1);
const output = execWithCache('node ../dist/index.js build');
expect(output.code).toBe(1);
});

it('should only transpile and not type check', () => {
const code = shell.exec('node ../dist/index.js build --transpileOnly').code;
const output = execWithCache('node ../dist/index.js build --transpileOnly');

expect(shell.test('-f', 'dist/index.js')).toBeTruthy();
expect(
Expand All @@ -31,7 +32,7 @@ describe('tsdx build :: invalid build', () => {

expect(shell.test('-f', 'dist/index.d.ts')).toBeTruthy();

expect(code).toBe(0);
expect(output.code).toBe(0);
});

afterAll(() => {
Expand Down
9 changes: 7 additions & 2 deletions test/tests/tsdx-build-withTsconfig.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const shell = require('shelljs');
const util = require('../fixtures/util');
const { execWithCache } = require('../utils/shell');

shell.config.silent = false;

Expand All @@ -13,7 +14,7 @@ describe('tsdx build :: build with custom tsconfig.json options', () => {
});

it('should use the declarationDir when set', () => {
const output = shell.exec('node ../dist/index.js build');
const output = execWithCache('node ../dist/index.js build');

expect(shell.test('-f', 'dist/index.js')).toBeTruthy();
expect(
Expand All @@ -32,13 +33,17 @@ describe('tsdx build :: build with custom tsconfig.json options', () => {
});

it('should set __esModule according to esModuleInterop', () => {
const output = execWithCache('node ../dist/index.js build');

const lib = require(`../../${stageName}/dist/build-withtsconfig.cjs.production.min.js`);
// if esModuleInterop: false, no __esModule is added, therefore undefined
expect(lib.__esModule).toBe(undefined);

expect(output.code).toBe(0);
});

it('should read custom --tsconfig path', () => {
const output = shell.exec(
const output = execWithCache(
'node ../dist/index.js build --format cjs --tsconfig ./src/tsconfig.json'
);

Expand Down
29 changes: 29 additions & 0 deletions test/utils/shell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// this file contains helper utils for working with shell.js functions
const shell = require('shelljs');

shell.config.silent = true;

// simple shell.exec "cache" that doesn't re-run the same command twice in a row
let prevCommand = '';
let prevCommandOutput = {};
function execWithCache(command, { noCache = false } = {}) {
// return the old output
if (!noCache && prevCommand === command) return prevCommandOutput;

const output = shell.exec(command);

// reset if command is not to be cached
if (noCache) {
prevCommand = '';
prevCommandOutput = {};
} else {
prevCommand = command;
prevCommandOutput = output;
}

return output;
}

module.exports = {
execWithCache,
};

0 comments on commit d234dff

Please sign in to comment.