chore: testing

This commit is contained in:
Justin McCormick
2022-08-16 01:59:04 -04:00
parent a28ec64800
commit 23f9be033a
10 changed files with 17404 additions and 55 deletions
+79
View File
@@ -0,0 +1,79 @@
name: Push Runner
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Test Action
runs-on: ${{ matrix.os }}
strategy:
matrix:
version: [ 16 ]
os: [ ubuntu-latest, windows-latest ]
env:
EXPECTED_CONTENT: "<span style=color:#0AA>Sample Text</span>"
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
cache: npm
node-version: '16'
- name: Install dependencies
run: npm install
- name: Lint
run: npm run lint
- name: Unit Tests
run: npm run test
- name: Generate String
run: echo -en "\e[36mSample Text\e[0m" | tee output.log
- name: Read test file from disk
id: raw
uses: juliangruber/read-file-action@v1
with:
path: ./output.log
- name: Run action on file path
id: parsed-path
uses: ./
with:
path: ./output.log
- name: Run action on input
id: parsed-input
uses: ./
with:
input: ${{ steps.raw.outputs.content }}
- name: "Path smoke test"
if: runner.os == 'Linux'
run: |
if [[ "${{ steps.parsed-path.outputs.contents }}" != "${{ env.EXPECTED_CONTENT }}" ]]; then
echo "'${{ steps.parsed-path.outputs.contents }}' != '${{ env.EXPECTED_CONTENT }}'"
exit 1
fi
- name: "Input smoke test"
if: runner.os == 'Linux'
run: |
if [[ "${{ steps.parsed-input.outputs.contents }}" != "${{ env.EXPECTED_CONTENT }}" ]]; then
echo "'${{ steps.parsed-input.outputs.contents }}' != '${{ env.EXPECTED_CONTENT }}'"
exit 1
fi
release:
name: Release Action
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/heads/master')
needs:
- test
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
cache: npm
node-version: '16'
- run: npm install
- run: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+6
View File
@@ -25,6 +25,12 @@ A Github Action that converts ANSI color sequences to HTML friendly HEX codes.
Read a file from disk that contains ANSI color escape sequences, escape its contents and post its contents to an active pull request. Read a file from disk that contains ANSI color escape sequences, escape its contents and post its contents to an active pull request.
```yaml ```yaml
jobs:
build:
permissions:
contents: read
pull-requests: write
steps:
- run: ./doSomething.sh | tee output.log - run: ./doSomething.sh | tee output.log
- id: output-log - id: output-log
uses: justinm/ansi-to-html-action@v0 uses: justinm/ansi-to-html-action@v0
+34
View File
@@ -0,0 +1,34 @@
import Converter from "ansi-to-html";
import * as core from "@actions/core";
import fs from "fs";
export function main() {
const converter = new Converter();
const input = core.getInput("input", { required: false });
const encoding = core.getInput("encoding", {
required: true,
});
const path = core.getInput("path", { required: false });
if (!input && !path) {
return core.setFailed("You must provide either an input or path.");
}
if (input && path) {
return core.setFailed(
"You must provide either an input or path, not both."
);
}
if (input && input !== "") {
core.setOutput("contents", converter.toHtml(input));
} else if (path && path !== "") {
if (!fs.existsSync(path)) {
return core.setFailed(`Path ${path} does not exist.`);
}
const rawContents = fs.readFileSync(path).toString(encoding);
core.setOutput("contents", converter.toHtml(rawContents));
}
}
+8 -1
View File
@@ -7,10 +7,17 @@ branding:
inputs: inputs:
input: input:
description: "The raw input containing ANSI color codes" description: "The raw input containing ANSI color codes"
required: false
path:
description: "The raw input containing ANSI color codes"
required: false
encoding:
description: "The encoding for the raw input. Defaults to utf8"
default: "utf8"
required: true required: true
outputs: outputs:
contents: contents:
description: "A version of 'input' where all ANSI codes have been replaced with HTML color codes." description: "A version of 'input' where all ANSI codes have been replaced with HTML color codes."
runs: runs:
using: "node16" using: "node16"
main: "index.js" main: "./index.js"
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }]],
};
+2 -25
View File
@@ -1,26 +1,3 @@
import core from "@actions/core"; import { main } from "./action.js";
import Converter from "ansi-to-html";
import fs from "fs";
const converter = new Converter(); main();
const input = core.getInput("input", { required: false });
const encoding = core.getInput("encoding", {
required: true,
});
const path = core.getInput("path", { required: false });
if (!input && !path) {
core.setFailed("You must provide either an input or path.");
}
if (input && path) {
core.setFailed("You must provide either an input or path, not both.");
}
if (input && input !== "") {
core.setOutput("contents", converter.toHtml(input));
} else if (path && path !== "") {
const rawContents = fs.readFileSync(path).toString(encoding);
core.setOutput("contents", converter.toHtml(rawContents));
}
+17065 -1
View File
File diff suppressed because it is too large Load Diff
+103 -4
View File
@@ -1,7 +1,7 @@
{ {
"name": "ansi-to-html-action", "name": "ansi-to-html-action",
"version": "0.0.0", "version": "0.0.0",
"main": "index.js", "main": "./index.js",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"repository": "git@github.com:justinm/ansi-to-html-action.git", "repository": "git@github.com:justinm/ansi-to-html-action.git",
@@ -12,7 +12,9 @@
"url": "https://justinmccormick.com/ansi-to-html-action" "url": "https://justinmccormick.com/ansi-to-html-action"
}, },
"scripts": { "scripts": {
"lint": "eslint --ext js ." "lint": "eslint --ext js .",
"release": "npx semantic-release",
"test": "npx cross-env FORCE_COLOR=1 npx jest"
}, },
"dependencies": { "dependencies": {
"@actions/core": "^1.9.1", "@actions/core": "^1.9.1",
@@ -20,12 +22,28 @@
"ansi-to-html": "^0.7.2" "ansi-to-html": "^0.7.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/commit-analyzer": "^9.0.2",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^8.0.5",
"@semantic-release/npm": "^9.0.1",
"@semantic-release/release-notes-generator": "^10.0.3",
"@types/jest": "^28.1.7",
"@types/node": "^18.7.3", "@types/node": "^18.7.3",
"babel-jest": "^28.1.3",
"chalk": "^4.1.2",
"cross-env": "^7.0.3",
"eslint": "^8.22.0", "eslint": "^8.22.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^26.8.3",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"jest": "^28.1.3",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"prettier-eslint": "^15.0.1" "prettier-eslint": "^15.0.1",
"semantic-release": "^19.0.3",
"semantic-release-conventional-commits": "^3.0.0"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,
@@ -44,9 +62,90 @@
}, },
"rules": { "rules": {
"prettier/prettier": "error" "prettier/prettier": "error"
} },
"overrides": [
{
"files": [
"test/**"
],
"plugins": [
"jest"
],
"extends": [
"plugin:jest/recommended"
],
"rules": {
"jest/prefer-expect-assertions": "off"
}
}
]
}, },
"prettierOptions": { "prettierOptions": {
"bracketSpacing": true "bracketSpacing": true
},
"jest": {
"transform": {
"\\.[jt]sx?$": "babel-jest"
}
},
"release": {
"branches": [
"master"
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"parserOpts": {
"noteKeywords": [
"BREAKS",
"BREAKING CHANGE",
"BREAKING CHANGES",
"BACKWARDS COMPAT",
"BACKWARDS COMPATIBILITY"
]
}
}
],
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changeLogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
[
"@semantic-release/github",
{
"assets": [
{
"path": "CHANGELOG.md",
"label": "Changelog"
},
{
"path": "README.md",
"label": "Readme"
},
{
"path": "LICENSE.md",
"label": "License"
}
]
}
],
[
"@semantic-release/git",
{
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
} }
} }
+104
View File
@@ -0,0 +1,104 @@
import { main } from "../action.js";
import * as core from "@actions/core";
import chalk from "chalk";
import fs from "fs";
jest.mock("@actions/core");
describe("Action", () => {
describe("using inputs", () => {
it("returns an HTML safe string", () => {
const mockGetInput = jest.fn((key) => {
switch (key) {
case "input":
return chalk.red("test");
case "encoding":
return "utf8";
}
return undefined;
});
const mockSetOutput = jest.fn();
jest.spyOn(core, "getInput").mockImplementation(mockGetInput);
jest.spyOn(core, "setOutput").mockImplementation(mockSetOutput);
main();
expect(mockGetInput.mock.calls).toHaveLength(3);
expect(mockSetOutput.mock.calls).toHaveLength(1);
expect(mockSetOutput.mock.calls[0]).toHaveLength(2);
expect(mockSetOutput.mock.calls[0][0]).toMatch("contents");
expect(mockSetOutput.mock.calls[0][1]).toMatch(
'<span style="color:#A00">test<span style="color:#FFF"></span></span>'
);
});
});
describe("using paths", () => {
it("returns an HTML safe string", () => {
const mockGetInput = jest.fn((key) => {
switch (key) {
case "encoding":
return "utf8";
case "path":
return "./test.log";
}
return undefined;
});
const mockSetOutput = jest.fn();
const mockExistsSync = jest.fn(() => true);
const mockReadFileSync = jest.fn(() => chalk.red("test"));
jest.spyOn(core, "getInput").mockImplementation(mockGetInput);
jest.spyOn(core, "setOutput").mockImplementation(mockSetOutput);
jest.spyOn(fs, "existsSync").mockImplementation(mockExistsSync);
jest.spyOn(fs, "readFileSync").mockImplementation(mockReadFileSync);
main();
expect(mockGetInput.mock.calls).toHaveLength(3);
expect(mockSetOutput.mock.calls).toHaveLength(1);
expect(mockSetOutput.mock.calls[0]).toHaveLength(2);
expect(mockSetOutput.mock.calls[0][0]).toMatch("contents");
expect(mockSetOutput.mock.calls[0][1]).toMatch(
'<span style="color:#A00">test<span style="color:#FFF"></span></span>'
);
expect(mockExistsSync.mock.calls).toHaveLength(1);
expect(mockReadFileSync.mock.calls).toHaveLength(1);
});
it("returns an error when the path does not exists", () => {
const mockGetInput = jest.fn((key) => {
switch (key) {
case "encoding":
return "utf8";
case "path":
return "./test.log";
}
return undefined;
});
const mockSetOutput = jest.fn();
const mockSetFailed = jest.fn();
const mockExistsSync = jest.fn(() => false);
const mockReadFileSync = jest.fn(() => chalk.red("test"));
jest.spyOn(core, "getInput").mockImplementation(mockGetInput);
jest.spyOn(core, "setOutput").mockImplementation(mockSetOutput);
jest.spyOn(core, "setFailed").mockImplementation(mockSetFailed);
jest.spyOn(fs, "existsSync").mockImplementation(mockExistsSync);
jest.spyOn(fs, "readFileSync").mockImplementation(mockReadFileSync);
main();
expect(mockGetInput.mock.calls).toHaveLength(3);
expect(mockSetOutput.mock.calls).toHaveLength(0);
expect(mockExistsSync.mock.calls).toHaveLength(1);
expect(mockReadFileSync.mock.calls).toHaveLength(0);
expect(mockSetFailed.mock.calls).toHaveLength(1);
expect(mockSetFailed.mock.calls[0]).toHaveLength(1);
expect(mockSetFailed.mock.calls[0][0]).toMatch(
`Path ./test.log does not exist.`
);
});
});
});
-24
View File
@@ -1,24 +0,0 @@
{
"compilerOptions": {
"outDir": "dist",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx",
"target": "ES6",
"lib": [
"dom",
"dom.iterable",
"esnext"
]
},
}