aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/exec-util.ts
blob: 0fb5ca0de4ab33c2ef7ff938288450380a21b96e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import is from '@sindresorhus/is';
import traverse from 'neotraverse/legacy';
import upath from 'upath';
import { rawExec as _exec } from '../lib/util/exec/common';
import type { RawExecOptions } from '../lib/util/exec/types';
import { regEx } from '../lib/util/regex';
import { mockedFunction } from './util';

jest.mock('../lib/util/exec/common');

export type ExecResult = { stdout: string; stderr: string } | Error;

export const exec = mockedFunction(_exec);

export interface ExecSnapshot {
  cmd: string;
  options?: RawExecOptions | null | undefined;
}

export type ExecSnapshots = ExecSnapshot[];

function execSnapshot(cmd: string, options?: RawExecOptions): ExecSnapshot {
  const snapshot = {
    cmd,
    options,
  };

  const cwd = upath.toUnix(process.cwd());

  return traverse(snapshot).map(function fixup(v) {
    if (is.string(v)) {
      const val = v
        .replace(regEx(/\\(\w)/g), '/$1')
        .replace(regEx(/^[A-Z]:\//), '/') // replace windows paths
        .replace(regEx(/"[A-Z]:\//g), '"/') // replace windows paths
        .replace(cwd, '/root/project');
      this.update(val);
    }
  });
}

const defaultExecResult = { stdout: '', stderr: '' };

export function mockExecAll(
  execResult: ExecResult = defaultExecResult,
): ExecSnapshots {
  const snapshots: ExecSnapshots = [];
  exec.mockImplementation((cmd, options) => {
    snapshots.push(execSnapshot(cmd, options));
    if (execResult instanceof Error) {
      throw execResult;
    }
    return execResult as never;
  });
  return snapshots;
}

export function mockExecSequence(execResults: ExecResult[]): ExecSnapshots {
  const snapshots: ExecSnapshots = [];
  execResults.forEach((execResult) => {
    exec.mockImplementationOnce((cmd, options) => {
      snapshots.push(execSnapshot(cmd, options));
      if (execResult instanceof Error) {
        throw execResult;
      }
      return execResult as never;
    });
  });
  return snapshots;
}

const basicEnvMock = {
  HTTP_PROXY: 'http://example.com',
  HTTPS_PROXY: 'https://example.com',
  NO_PROXY: 'localhost',
  HOME: '/home/user',
  PATH: '/tmp/path',
  LANG: 'en_US.UTF-8',
  LC_ALL: 'en_US',
};

const fullEnvMock = {
  ...basicEnvMock,
  SELECTED_ENV_VAR: 'Can be selected',
  FILTERED_ENV_VAR: 'Should be filtered',
};

const filteredEnvMock = {
  ...basicEnvMock,
  SELECTED_ENV_VAR: fullEnvMock.SELECTED_ENV_VAR,
};

export const envMock = {
  basic: basicEnvMock,
  full: fullEnvMock,
  filtered: filteredEnvMock,
};

// reset exec mock, otherwise there can be some left over from previous test
beforeEach(() => {
  // maybe not mocked
  exec.mockReset?.();
});