From 028c2af36104876303c2082c111bdcf2188b031e Mon Sep 17 00:00:00 2001 From: Nick Cipollo Date: Mon, 26 Aug 2019 20:35:39 -0400 Subject: [PATCH] Add mocks to tests --- __tests__/Action.test.ts | 36 ++++++++++++++++++++++++++++++++ __tests__/Inputs.test.ts | 33 +++++++++++++++++++---------- action.yml | 12 +++++------ src/Action.ts | 19 +++++++++++++++++ src/Inputs.ts | 45 +++++++++++++++++++++++++++------------- src/Main.ts | 8 +++---- src/Releases.ts | 20 +++++++++++++++++- 7 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 __tests__/Action.test.ts diff --git a/__tests__/Action.test.ts b/__tests__/Action.test.ts new file mode 100644 index 0000000..f3a3f4f --- /dev/null +++ b/__tests__/Action.test.ts @@ -0,0 +1,36 @@ +import { Action } from "../src/Action"; +import { Inputs } from "../src/Inputs"; +import { Releases } from "../src/Releases"; + + +describe("Action", () => { + + it('verifies my sanity', () => { + + }) +}) + +function createAction(): Action { + const MockReleases = jest.fn(() => { + return { + create: jest.fn(), + uploadArtifact: jest.fn() + } + }) + const MockInputs = jest.fn(() => { + return { + artifact: "foo", + artifactContentType: "foo", + artifactContentLength: 22, + body: "bar", + commit: "foo", + name: "name", + tag: "foo", + token: "foo" + } + }) + const inputs = new MockInputs() + const releases = new MockReleases() + + return new Action(inputs, releases) +} \ No newline at end of file diff --git a/__tests__/Inputs.test.ts b/__tests__/Inputs.test.ts index 4b8cd54..1e7dd68 100644 --- a/__tests__/Inputs.test.ts +++ b/__tests__/Inputs.test.ts @@ -2,20 +2,20 @@ const mockGetInput = jest.fn(); const mockReadFileSync = jest.fn(); const mockStatSync = jest.fn(); -import { Inputs } from "../src/Inputs"; +import { Inputs, CoreInputs } from "../src/Inputs"; import { Context } from "@actions/github/lib/context"; jest.mock('@actions/core', () => { return { getInput: mockGetInput }; -}); +}) jest.mock('fs', () => { return { readFileSync: mockReadFileSync, statSync: mockStatSync }; -}); +}) describe('Inputs', () => { let context: Context; @@ -23,7 +23,7 @@ describe('Inputs', () => { beforeEach(() => { mockGetInput.mockReturnValue(null) context = new Context() - inputs = new Inputs(context) + inputs = new CoreInputs(context) }) it('returns artifact', () => { @@ -58,21 +58,32 @@ describe('Inputs', () => { }) }) - describe('description', () => { - it('returns input description', () => { - mockGetInput.mockReturnValue("description") - expect(inputs.description).toBe("description") + describe('body', () => { + it('returns input body', () => { + mockGetInput.mockReturnValue("body") + expect(inputs.body).toBe("body") }) - it('returns description file contents', () => { + it('returns body file contents', () => { mockGetInput.mockReturnValueOnce("").mockReturnValueOnce("a/path") mockReadFileSync.mockReturnValue("file") - expect(inputs.description).toBe("file") + expect(inputs.body).toBe("file") }) it('returns empty', () => { - expect(inputs.description).toBe("") + expect(inputs.body).toBe("") + }) + }) + + describe('draft', () => { + it('returns false', () => { + expect(inputs.draft).toBe(false) + }) + + it('returns true', () => { + mockGetInput.mockReturnValue("true") + expect(inputs.draft).toBe(true) }) }) diff --git a/action.yml b/action.yml index 3c08666..5663a97 100644 --- a/action.yml +++ b/action.yml @@ -8,15 +8,15 @@ inputs: artifactContentType: description: 'The content type of the artifact. Defaults to raw' default: '' + body: + description: 'An optional body for the release.' + default: '' + bodyFile: + description: 'An optional body file for the release. This should be the path to the file' + default: '' commit: description: 'An optional commit reference. This will be used to create the tag if it doesn't exist.' default: '' - description: - description: 'An optional description for the release.' - default: '' - descriptionFile: - description: 'An optional description file for the release. This should be the path to the file' - default: '' name: description: 'An optional name for the release. If this is omitted the tag will be used.' default: '' diff --git a/src/Action.ts b/src/Action.ts index 6406efc..8fa47de 100644 --- a/src/Action.ts +++ b/src/Action.ts @@ -1,5 +1,6 @@ import { Inputs } from "./Inputs"; import { Releases } from "./Releases"; +import { basename } from "path"; export class Action { private inputs: Inputs @@ -9,4 +10,22 @@ export class Action { this.inputs = inputs this.releases = releases } + + async perform() { + const createResult = await this.releases.create( + this.inputs.tag, + this.inputs.body, + this.inputs.commit, + this.inputs.draft, + this.inputs.name) + + if (this.inputs.artifact) { + await this.releases.uploadArtifact( + createResult.data.assets_url, + this.inputs.artifactContentLength, + this.inputs.artifactContentType, + this.inputs.artifact, + basename(this.inputs.artifact)) + } + } } \ No newline at end of file diff --git a/src/Inputs.ts b/src/Inputs.ts index 695b02b..c7a2d29 100644 --- a/src/Inputs.ts +++ b/src/Inputs.ts @@ -2,7 +2,19 @@ import * as core from '@actions/core'; import { Context } from "@actions/github/lib/context"; import { readFileSync, statSync } from 'fs'; -export class Inputs { +export interface Inputs { + readonly artifact: string + readonly artifactContentType: string + readonly artifactContentLength: number + readonly body: string + readonly commit: string + readonly draft: boolean + readonly name: string + readonly tag: string + readonly token: string +} + +export class CoreInputs implements Inputs { private context: Context constructor(context: Context) { @@ -26,22 +38,27 @@ export class Inputs { return statSync(this.artifact).size } + get body(): string { + const body = core.getInput('body') + if (body) { + return body + } + + const bodyFile = core.getInput('bodyFile') + if (bodyFile) { + return this.stringFromFile(bodyFile) + } + + return '' + } + get commit(): string { return core.getInput('commit') } - get description(): string { - const description = core.getInput('description') - if (description) { - return description - } - - const descriptionFile = core.getInput('descriptionFile') - if (descriptionFile) { - return this.stringFromFile(descriptionFile) - } - - return '' + get draft(): boolean { + const draft = core.getInput('draft') + return draft == 'true' } get name(): string { @@ -72,7 +89,7 @@ export class Inputs { return core.getInput('token', { required: true }) } - private stringFromFile(path: string): string { + stringFromFile(path: string): string { return readFileSync(path, 'utf-8') } } \ No newline at end of file diff --git a/src/Main.ts b/src/Main.ts index 1dba5b4..d2013ce 100644 --- a/src/Main.ts +++ b/src/Main.ts @@ -1,15 +1,15 @@ import * as github from '@actions/github'; import * as core from '@actions/core'; -import { Inputs } from './Inputs'; -import { Releases } from './Releases'; +import { Inputs, CoreInputs } from './Inputs'; +import { Releases, GithubReleases } from './Releases'; async function run() { try { const token = core.getInput('token'); const context = github.context const git = new github.GitHub(token); - const releases = new Releases(context, git) - const inputs = new Inputs(context) + const releases = new GithubReleases(context, git) + const inputs = new CoreInputs(context) await releases.create(inputs.tag) .catch(error => { core.warning(error) diff --git a/src/Releases.ts b/src/Releases.ts index a2c47c5..193ac57 100644 --- a/src/Releases.ts +++ b/src/Releases.ts @@ -2,7 +2,25 @@ import { Context } from "@actions/github/lib/context"; import { GitHub } from "@actions/github"; import { AnyResponse, Response, ReposCreateReleaseResponse } from "@octokit/rest"; -export class Releases { +export interface Releases { + create( + tag: string, + body?: string, + commitHash?: string, + draft?: boolean, + name?: string + ): Promise> + + uploadArtifact( + assetUrl: string, + contentLength: number, + contentType: string, + file: string, + name: string + ): Promise> +} + +export class GithubReleases implements Releases{ context: Context git: GitHub