Skip to content

Commit 254b4d5

Browse files
committed
Initial commit
0 parents  commit 254b4d5

38 files changed

+7263
-0
lines changed

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: "Test typescript-action"
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
- 'releases/*'
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v1
14+
15+
- run: npm ci
16+
- run: npm run build
17+
- run: npm test
18+
- uses: ./
19+
with:
20+
schema: ''
21+
jsons: ''
22+

.gitignore

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
__tests__/runner/*
2+
3+
# comment out in distribution branches
4+
node_modules/
5+
6+
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
7+
# Logs
8+
logs
9+
*.log
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
lerna-debug.log*
14+
15+
# Diagnostic reports (https://nodejs.org/api/report.html)
16+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
17+
18+
# Runtime data
19+
pids
20+
*.pid
21+
*.seed
22+
*.pid.lock
23+
24+
# Directory for instrumented libs generated by jscoverage/JSCover
25+
lib-cov
26+
27+
# Coverage directory used by tools like istanbul
28+
coverage
29+
*.lcov
30+
31+
# nyc test coverage
32+
.nyc_output
33+
34+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
35+
.grunt
36+
37+
# Bower dependency directory (https://bower.io/)
38+
bower_components
39+
40+
# node-waf configuration
41+
.lock-wscript
42+
43+
# Compiled binary addons (https://nodejs.org/api/addons.html)
44+
build/Release
45+
46+
# Dependency directories
47+
jspm_packages/
48+
49+
# TypeScript v1 declaration files
50+
typings/
51+
52+
# TypeScript cache
53+
*.tsbuildinfo
54+
55+
# Optional npm cache directory
56+
.npm
57+
58+
# Optional eslint cache
59+
.eslintcache
60+
61+
# Optional REPL history
62+
.node_repl_history
63+
64+
# Output of 'npm pack'
65+
*.tgz
66+
67+
# Yarn Integrity file
68+
.yarn-integrity
69+
70+
# dotenv environment variables file
71+
.env
72+
.env.test
73+
74+
# parcel-bundler cache (https://parceljs.org/)
75+
.cache
76+
77+
# next.js build output
78+
.next
79+
80+
# nuxt.js build output
81+
.nuxt
82+
83+
# vuepress build output
84+
.vuepress/dist
85+
86+
# Serverless directories
87+
.serverless/
88+
89+
# FuseBox cache
90+
.fusebox/
91+
92+
# DynamoDB Local files
93+
.dynamodb/
94+
95+
# IDE
96+
.vscode

.huskyrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"hooks": {
3+
"pre-commit": "lint-staged"
4+
}
5+
}

.lintstagedrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"**/*.{ts,js,json}": [
3+
"prettier --write",
4+
"git add"
5+
]
6+
}

.prettierignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package.json
2+
package-lock.json
3+
tsconfig.json
4+
node_modules
5+
dist
6+
lib

.prettierrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
trailingComma: es5
2+
singleQuote: true
3+
printWidth: 120
4+
tabWidth: 4
5+
bracketSpacing: true

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2018 GitHub, Inc. and contributors
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Github Action: Validate JSON
2+
// TODO://

__tests__/json-file-reader.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { getJson } from '../src/json-file-reader';
2+
import excepted from './mocks/tested-data/valid.json';
3+
import { InvalidJsonFileError } from '../src/errors';
4+
5+
const mocks_dir = './__tests__/mocks';
6+
7+
describe('Process a JSON file', () => {
8+
test('should return a valid JSON when procesings valid JSON file', async () => {
9+
const validJsonFile = 'tested-data/valid.json';
10+
11+
const result = await getJson(mocks_dir, validJsonFile);
12+
expect(typeof result).toBe('object');
13+
14+
Object.keys(excepted).forEach(key => {
15+
expect(result).toHaveProperty(key);
16+
expect(result[key]).toEqual(excepted[key]);
17+
});
18+
});
19+
20+
test('should throw an error when procesing invalid JSON file', async () => {
21+
const invalidJsonFile = 'tested-data/invalid_by_format.json';
22+
23+
const task = getJson(mocks_dir, invalidJsonFile);
24+
25+
try {
26+
expect(await task).toThrowError(InvalidJsonFileError);
27+
} catch (e) {
28+
const err = e as InvalidJsonFileError;
29+
expect(err.fileName).toEqual('invalid_by_format.json');
30+
}
31+
});
32+
33+
test("should throw an error when file or directory don't exist", async () => {
34+
const notExistingFile = 'no_such_file.json';
35+
36+
const task = getJson(mocks_dir, notExistingFile);
37+
try {
38+
expect(await task).toThrowError(InvalidJsonFileError);
39+
} catch (e) {
40+
const err = e as InvalidJsonFileError;
41+
expect(err.fileName).toEqual('no_such_file.json');
42+
expect(typeof err.innerError).not.toBeUndefined();
43+
expect((<object>err.innerError)['code']).toBe('ENOENT');
44+
}
45+
});
46+
});

__tests__/json-validator.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { validateJsons } from '../src/json-validator';
2+
3+
const validSchemaFile = `schema/valid.json`;
4+
const invalidSchemaFile = `schema/invalid.json`;
5+
6+
const validDataFile = `tested-data/valid.json`;
7+
const invalidDataFile = `tested-data/invalid_by_schema.json`;
8+
9+
const mocks_dir = './__tests__/mocks';
10+
11+
describe('Json validation results', () => {
12+
test('all successful when all jsons in the list are valid', async () => {
13+
const results = await validateJsons(mocks_dir, validSchemaFile, [validDataFile, validDataFile]);
14+
expect(results.every(r => r.valid)).toBeTruthy();
15+
expect(results.every(r => r.fileName === 'valid.json')).toBeTruthy();
16+
});
17+
18+
test('only one failure when one json in the list is invalid', async () => {
19+
const results = await validateJsons(mocks_dir, validSchemaFile, [validDataFile, invalidDataFile]);
20+
21+
const successes = results.filter(r => r.valid);
22+
expect(successes.length).toEqual(1);
23+
expect(successes.every(r => r.fileName === 'valid.json')).toBeTruthy();
24+
25+
const failures = results.filter(r => !r.valid);
26+
expect(failures.length).toEqual(1);
27+
expect(failures.every(r => r.fileName === 'invalid_by_schema.json')).toBeTruthy();
28+
});
29+
30+
test('all failures when all jsons in the list are invalid', async () => {
31+
const results = await validateJsons(mocks_dir, validSchemaFile, [invalidDataFile, invalidDataFile]);
32+
expect(results.every(r => !r.valid)).toBeTruthy();
33+
expect(results.every(r => r.fileName === 'invalid_by_schema.json')).toBeTruthy();
34+
});
35+
36+
test('one failures when schema file are invalid', async () => {
37+
const results = await validateJsons(mocks_dir, invalidSchemaFile, [validDataFile, validDataFile]);
38+
expect(results).toHaveLength(1);
39+
expect(results.every(r => !r.valid)).toBeTruthy();
40+
expect(results.every(r => r.fileName === 'invalid.json')).toBeTruthy();
41+
});
42+
43+
test('one failure when no schema file', async () => {
44+
const results = await validateJsons(mocks_dir, '', [validDataFile, validDataFile]);
45+
expect(results).toHaveLength(1);
46+
expect(results.every(r => !r.valid)).toBeTruthy();
47+
expect(results.every(r => r.fileName === 'schema')).toBeTruthy();
48+
});
49+
50+
test('empty when when no jsons in the list', async () => {
51+
const results = await validateJsons(mocks_dir, validSchemaFile, []);
52+
expect(results).toHaveLength(0);
53+
});
54+
});

__tests__/main.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import * as os from 'os';
2+
import * as process from 'process';
3+
import * as path from 'path';
4+
import * as cp from 'child_process';
5+
import { MockedConfig } from './mocks/mocked-config';
6+
7+
let mockedConfig: MockedConfig;
8+
let ip: string;
9+
10+
describe('Run tests', () => {
11+
beforeEach(() => {
12+
ip = path.join(__dirname, '..', 'lib', 'main.js');
13+
mockedConfig = new MockedConfig();
14+
});
15+
16+
afterEach(() => {
17+
ip = '';
18+
mockedConfig.resetAll();
19+
jest.resetAllMocks();
20+
});
21+
22+
test('All inputs are set and valid', () => {
23+
// Arrange
24+
mockedConfig.mockValue('SCHEMA', './mocks/schema/valid.json');
25+
mockedConfig.mockValue('JSONS', './mocks/tested-data/valid.json');
26+
27+
mockedConfig.set();
28+
29+
const options: cp.ExecOptions = {
30+
env: process.env,
31+
};
32+
33+
try {
34+
// Act
35+
const result = cp.execSync(`node ${ip}`, options);
36+
37+
// Assert
38+
expect(result.toString()).toContain(`::set-output name=INVALID,::${os.EOL}`);
39+
} catch (ex) {
40+
expect(ex).toBeUndefined();
41+
}
42+
});
43+
});

__tests__/mocks/mocked-config.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as path from 'path';
2+
import { ConfigKeys, ConfigKey, configMapping } from '../../src/configuration';
3+
4+
export class MockedConfig {
5+
private mockedConfig: {};
6+
7+
constructor() {
8+
this.mockedConfig = {
9+
GITHUB_WORKSPACE: path.join(__dirname, '..'),
10+
INPUT_SCHEMA: '',
11+
INPUT_JSONS: '',
12+
};
13+
}
14+
15+
public mockValue(key: ConfigKeys, value: string) {
16+
const keyMapping = configMapping.find(x => ConfigKey[x.key] === key);
17+
if (keyMapping) {
18+
this.mockedConfig[keyMapping.setup === 'INPUT' ? `${keyMapping.setup}_${key}` : key] = value;
19+
}
20+
}
21+
22+
public set(): void {
23+
for (const key in this.mockedConfig) {
24+
process.env[key] = this.mockedConfig[key];
25+
}
26+
}
27+
28+
public resetAll(): void {
29+
for (const key in this.mockedConfig) {
30+
Reflect.deleteProperty(this.mockedConfig, key);
31+
}
32+
}
33+
}

__tests__/mocks/schema/invalid.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"properties": {
3+
"foo": { "type": "no_such_type" },
4+
"bar": { "type": "number" }
5+
}
6+
}

__tests__/mocks/schema/valid.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"properties": {
3+
"foo": { "type": "string" },
4+
"bar": { "type": "number" }
5+
}
6+
}

__tests__/mocks/tested-data/invalid_by_format.json

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "foo": 2, "bar": 4 }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "foo": "abc", "bar": 2 }

0 commit comments

Comments
 (0)