Skip to content

Commit

Permalink
Merge pull request #4 from shlomimatichin/unittest
Browse files Browse the repository at this point in the history
Added good flow unit tests
  • Loading branch information
roni-frantchi authored Jan 3, 2021
2 parents 93f3208 + 43b5559 commit 3b4fd7b
Show file tree
Hide file tree
Showing 11 changed files with 321 additions and 77 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on: [push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
with:
node-version: '12'
- name: Install dependencies
run: |
npm i
- name: Style check
run: |
npx prettier --check "*.ts" "lib/*.ts"
- name: Unit test
run: |
npm run test
11 changes: 11 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"semi": true,
"singleQuote": true,
"printWidth": 120,
"trailingComma": "none",
"parser": "typescript",
"proseWrap": "preserve",
"quoteProps": "as-needed",
"jsxBracketSameLine": true,
"arrowParens": "avoid"
}
11 changes: 11 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"recommendations": [
"christian-kohler.npm-intellisense",
"dbaeumer.vscode-eslint",
"eg2.vscode-npm-script",
"esbenp.prettier-vscode",
"lannonbr.vscode-js-annotations",
"ms-vscode.vscode-typescript-tslint-plugin",
"orta.vscode-jest"
]
}
9 changes: 9 additions & 0 deletions __mocks__/@actions/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const self = {
error: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
warn: jest.fn(),
getInput: jest.fn(),
addPath: jest.fn(),
}
export default self;
5 changes: 5 additions & 0 deletions __mocks__/@actions/tool-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const self = {
downloadTool: jest.fn(),
extractTar: jest.fn(),
}
export default self;
10 changes: 5 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8735,7 +8735,7 @@ function latestVersion() {
const regex = new RegExp('href="/env0/terratag/releases/tag/v(.{1,15})"');
const found = response.data.match(regex);
if (!found) {
throw new Error("Unable to determine latest terratag version");
throw new Error('Unable to determine latest terratag version');
}
return found[1];
});
Expand All @@ -8749,7 +8749,7 @@ function cliArgsFromActionInputs() {
const boolFlag = (flagName) => {
const value = core_1.default.getInput(flagName);
if (value) {
if (value !== "true" && value !== "false") {
if (value !== 'true' && value !== 'false') {
throw new Error(`${flagName} can only accept 'true' or 'false'`);
}
cliArgs.push(`-${flagName}=${value}`);
Expand All @@ -8763,7 +8763,7 @@ function cliArgsFromActionInputs() {
function terratagVersionFromActionInputs() {
return __awaiter(this, void 0, void 0, function* () {
const version = core_1.default.getInput('terratagVersion');
if (version === "latest") {
if (version === 'latest') {
return yield latestVersion();
}
return version;
Expand All @@ -8773,7 +8773,7 @@ function terratagVersionDownloadURL(version) {
const osPlatform = os_1.default.platform();
const osArch = os_1.default.arch();
if (osArch !== 'x64') {
throw new Error("Terratag action currently only supports x64/amd64");
throw new Error('Terratag action currently only supports x64/amd64');
}
const platform = mapOS(osPlatform);
const arch = mapArch(osArch);
Expand All @@ -8795,7 +8795,7 @@ function run() {
core_1.default.info(`Successfully installed terratag ${version}`);
// Add to path
core_1.default.addPath(pathToCLI);
console.info("Terratag installed, invoking");
console.info('Terratag installed, invoking');
yield new Promise((resolve, reject) => {
const child = child_process_1.default.spawn(`${pathToCLI}/terratag`, cliArgs);
child.stdout.on('data', data => {
Expand Down
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: [
"<rootDir>/dist/",
"<rootDir>/node_modules/"
],
resetMocks: true,
};
88 changes: 88 additions & 0 deletions lib/terratag-action.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import axios from 'axios';
import childProcess from 'child_process';
import core from '@actions/core';
import tc from '@actions/tool-cache';
jest.mock('axios');
jest.mock('child_process');
const mockedAxios = axios as jest.Mocked<typeof axios>;
const mockedChildProcess = childProcess as jest.Mocked<typeof childProcess>;
const mockedCore = core as jest.Mocked<typeof core>;
const mockedTC = tc as jest.Mocked<typeof tc>;

import run from './terratag-action';

describe('terratag action', () => {
beforeEach(() => {
mockedTC.downloadTool.mockResolvedValue('FAKE PATH FOR DOWNLOADED TOOL TAR');
mockedTC.extractTar.mockResolvedValue('FAKE PATH FOR EXTRACTED');
const spawn = {
stdout: { on: jest.fn() },
stderr: { on: jest.fn() },
on: jest.fn()
};
spawn.on.mockImplementation((eventName: string, callback: (code: number) => void) => {
expect(eventName).toBe('close');
callback(0);
});
mockedChildProcess.spawn.mockReturnValue(spawn as any);
});

describe('simple end to end, latest terratag', () => {
beforeEach(async () => {
mockedCore.getInput.mockImplementation((name: string) => {
const inputs: { [key: string]: string } = { terratagVersion: 'latest', tags: JSON.stringify({ a: 'b' }) };
return inputs[name];
});
mockedAxios.get.mockResolvedValue({
status: 200,
data: `href="/env0/terratag/releases/tag/v1.2.3"`
});
await run();
});
it('shoud query which version of terratag is latest', () => {
expect(mockedAxios.get.mock.calls).toEqual([['https://github.com/env0/terratag/releases']]);
});
it('should download terratag from expected url', () => {
expect(mockedTC.downloadTool.mock.calls).toEqual([
['https://github.com/env0/terratag/releases/download/v1.2.3/terratag_1.2.3_linux_amd64.tar.gz']
]);
});
it('should extract downloaded terratag', () => {
expect(mockedCore.addPath.mock.calls).toEqual([['FAKE PATH FOR EXTRACTED']]);
});
it('should extract downloaded terratag', () => {
expect(mockedTC.extractTar.mock.calls).toEqual([['FAKE PATH FOR DOWNLOADED TOOL TAR']]);
});
it('should execute terratag with the correct cli arguments', () => {
expect(mockedChildProcess.spawn.mock.calls).toEqual([['FAKE PATH FOR EXTRACTED/terratag', ['-tags={"a":"b"}']]]);
});
});

describe('simple end to end, specific terratag', () => {
beforeEach(async () => {
mockedCore.getInput.mockImplementation((name: string) => {
const inputs: { [key: string]: string } = { terratagVersion: '5.6.7', tags: JSON.stringify({ a: 'b' }) };
return inputs[name];
});
mockedAxios.get.mockRejectedValue('Should not be called');
await run();
});
it('shoud NOT query which terratag versions', () => {
expect(mockedAxios.get.mock.calls).toEqual([]);
});
it('should download terratag from expected url', () => {
expect(mockedTC.downloadTool.mock.calls).toEqual([
['https://github.com/env0/terratag/releases/download/v5.6.7/terratag_5.6.7_linux_amd64.tar.gz']
]);
});
it('should extract downloaded terratag', () => {
expect(mockedCore.addPath.mock.calls).toEqual([['FAKE PATH FOR EXTRACTED']]);
});
it('should extract downloaded terratag', () => {
expect(mockedTC.extractTar.mock.calls).toEqual([['FAKE PATH FOR DOWNLOADED TOOL TAR']]);
});
it('should execute terratag with the correct cli arguments', () => {
expect(mockedChildProcess.spawn.mock.calls).toEqual([['FAKE PATH FOR EXTRACTED/terratag', ['-tags={"a":"b"}']]]);
});
});
});
26 changes: 13 additions & 13 deletions lib/terratag-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import tc from '@actions/tool-cache';
// arch in [arm, x32, x64...] (https://nodejs.org/api/os.html#os_os_arch)
// return value in [amd64, 386, arm]
function mapArch(arch: string): string {
const mappings: {[key: string]: string} = {
const mappings: { [key: string]: string } = {
x32: '386',
x64: 'amd64'
};
Expand All @@ -17,7 +17,7 @@ function mapArch(arch: string): string {
// os in [darwin, linux, win32...] (https://nodejs.org/api/os.html#os_os_platform)
// return value in [darwin, linux, windows]
function mapOS(os: string): string {
const mappings: {[key: string]: string} = {
const mappings: { [key: string]: string } = {
win32: 'windows'
};
return mappings[os] || os;
Expand Down Expand Up @@ -46,7 +46,7 @@ async function latestVersion(): Promise<string> {
const regex = new RegExp('href="/env0/terratag/releases/tag/v(.{1,15})"');
const found = response.data.match(regex);
if (!found) {
throw new Error("Unable to determine latest terratag version");
throw new Error('Unable to determine latest terratag version');
}
return found[1];
}
Expand All @@ -57,15 +57,15 @@ function cliArgsFromActionInputs(): string[] {
if (dir) {
cliArgs.push(`-dir=${dir}`);
}
const boolFlag = (flagName:string) => {
const boolFlag = (flagName: string) => {
const value = core.getInput(flagName);
if (value) {
if (value !== "true" && value !== "false") {
if (value !== 'true' && value !== 'false') {
throw new Error(`${flagName} can only accept 'true' or 'false'`);
}
cliArgs.push(`-${flagName}=${value}`);
}
}
};
boolFlag('skipTerratagFiles');
boolFlag('verbose');
boolFlag('rename');
Expand All @@ -74,7 +74,7 @@ function cliArgsFromActionInputs(): string[] {

async function terratagVersionFromActionInputs(): Promise<string> {
const version = core.getInput('terratagVersion');
if (version === "latest") {
if (version === 'latest') {
return await latestVersion();
}
return version;
Expand All @@ -84,7 +84,7 @@ function terratagVersionDownloadURL(version: string): string {
const osPlatform = os.platform();
const osArch = os.arch();
if (osArch !== 'x64') {
throw new Error("Terratag action currently only supports x64/amd64");
throw new Error('Terratag action currently only supports x64/amd64');
}

const platform = mapOS(osPlatform);
Expand All @@ -107,19 +107,19 @@ export default async function run(): Promise<void> {
core.info(`Successfully installed terratag ${version}`);
// Add to path
core.addPath(pathToCLI);
console.info("Terratag installed, invoking");
console.info('Terratag installed, invoking');

await new Promise<void>((resolve, reject)=>{
await new Promise<void>((resolve, reject) => {
const child = childProcess.spawn(`${pathToCLI}/terratag`, cliArgs);
child.stdout.on('data', data=>{
child.stdout.on('data', data => {
console.info(data);
core.info(data);
});
child.stderr.on('data', data=>{
child.stderr.on('data', data => {
console.error(data);
core.error(data);
});
child.on('close', code=>{
child.on('close', code => {
if (code === 0) {
resolve();
} else {
Expand Down
Loading

0 comments on commit 3b4fd7b

Please sign in to comment.