Skip to content

Commit

Permalink
Merge pull request #2 from betrybe/feature/adiciona-comentario-pr
Browse files Browse the repository at this point in the history
Feature/adiciona comentario pr
  • Loading branch information
inaC authored Aug 26, 2020
2 parents d71f3b4 + 83a0a60 commit 810b5c8
Show file tree
Hide file tree
Showing 34 changed files with 27,584 additions and 65 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
.vscode/

coverage/

node_modules/
83 changes: 82 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,82 @@
# linter-evaluator-action
# GitHub Action: Linter evaluator action

A GitHub action that evaluates projects with [eslint](https://eslint.org/) and comments the evaluation outcome on the student's pull request.

## Inputs

This action accepts the following configuration parameters via `with:`

- `token`

**Required**

The GitHub token to use for making API requests

## Example usage

```yaml
steps:
- name: Static code analysis step
uses: betrybe/linter-evaluator-action
with:
token: ${{ secrets.GITHUB_TOKEN }}
```
## Development
Install the dependencies
```bash
$ npm install
```

Run the tests :heavy_check_mark:
```bash
$ npm test
```

## Package for distribution

GitHub Actions will run the entry point from the action.yml. Packaging assembles the code into one file that can be checked in to Git, enabling fast and reliable execution and preventing the need to check in node_modules.

Actions are run from GitHub repos. Packaging the action will create a packaged action in the dist folder.

Run package

```bash
npm run pack
```

Since the packaged index.js is run from the dist folder.

```bash
git add dist
```

## Create a release branch

Users shouldn't consume the action from master since that would be latest code and actions can break compatibility between major versions.

Checking to the v1 release branch

```bash
$ git checkout -b v1
$ git commit -a -m "v1 release"
```

```bash
$ git push origin v1
```

Your action is now published! :rocket:

See the [versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)

## Usage

You can now consume the action by referencing the v1 branch

```yaml
uses: betrybe/linter-evaluator-action@v1
```
See the [actions tab](https://github.com/betrybe/linter-evaluator-action/actions) for runs of this action! :rocket:
74 changes: 74 additions & 0 deletions __tests__/feedbackMessage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const buildFeedbackMessage = require('../feedbackMessage');
const noError = require('./fixtures/eslint-results/frontEndNoError.json');
const oneError = require('./fixtures/eslint-results/oneError.json');
const multipleErrorsOneFile = require('./fixtures/eslint-results/multipleErrorsOneFile.json');
const multipleErrorsMultipleFiles = require('./fixtures/eslint-results/multipleErrorsMultipleFiles.json');

describe('Feedback message', () => {
describe('No error is found', () => {
test('When there is no file to be evaluated, a no error encountered message is returned', () => {
expect(buildFeedbackMessage([], './')).toBe('### Nenhum erro encontrado.')
});

test('When there are files to be evaluated, a no error encountered message is returned', () => {
expect(buildFeedbackMessage(noError, './')).toBe('### Nenhum erro encontrado.')
});
});

test('When one error is found, a message showing the error is returned', () => {
expect(buildFeedbackMessage(oneError, './')).toBe(
'### Foi encontrado 1 erro.\n' +
'\n' +
'#### Arquivo `/my-project/index.js`\n' +
'\n' +
'- Linha **1**: Function \'isPentagon\' has too many parameters (5). Maximum allowed is 4.\n'
);
});

describe('Multiple errors are found', () => {
test('When all errors are contained in one file, a message listing all those errors is returned', () => {
expect(buildFeedbackMessage(multipleErrorsOneFile, './')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/my-react-project/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n' +
'- Linha **3**: `Hello, ` must be placed on a new line\n' +
'- Linha **3**: `{name}` must be placed on a new line\n' +
'- Linha **5**: Missing semicolon.\n'
);
});

test('When the errors span multiple files, a message listing all those errors is returned', () => {
expect(buildFeedbackMessage(multipleErrorsMultipleFiles, './')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/my-react-project/src/App.js`\n' +
'\n' +
'- Linha **2**: `react` import should occur before import of `./components/Greeting`\n' +
'- Linha **12**: `code` must be placed on a new line\n' +
'- Linha **24**: Expected indentation of 6 space characters but found 4.\n' +
'' +
'#### Arquivo `/my-react-project/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n'
);
});
});

test('The root directory path for the project isn\'t displayed for each file', () => {
expect(buildFeedbackMessage(multipleErrorsMultipleFiles, '/my-react-project')).toBe(
'### Foram encontrados 4 erros.\n' +
'\n' +
'#### Arquivo `/src/App.js`\n' +
'\n' +
'- Linha **2**: `react` import should occur before import of `./components/Greeting`\n' +
'- Linha **12**: `code` must be placed on a new line\n' +
'- Linha **24**: Expected indentation of 6 space characters but found 4.\n' +
'' +
'#### Arquivo `/src/components/Greeting.js`\n' +
'\n' +
'- Linha **3**: \'name\' is missing in props validation\n'
);
});
});
59 changes: 59 additions & 0 deletions __tests__/findFilesBy.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const findFilesBy = require('../findFilesBy');

describe('Find files in directory', () => {
const rootDirectory = process.cwd();

describe('Files are found', () => {
test('When one file is found, a one element list containing it is returned', () => {
const startPath = `${rootDirectory}/__tests__/fixtures/projects/back-end`;
const givenResult = findFilesBy(startPath, '.eslintrc.json');
const expectedResult = [`${startPath}/.eslintrc.json`];

expect(givenResult).toEqual(expectedResult);
});

test('When multiple files are found, a list containing them is returned', () => {
const startPath = `${rootDirectory}/__tests__/fixtures/projects/monorepo`;
const givenResult = findFilesBy(startPath, '.eslintrc.json').sort();
const expectedResult = [
`${startPath}/api/.eslintrc.json`,
`${startPath}/front-end/.eslintrc.json`,
];

expect(givenResult).toEqual(expectedResult);
});
});

describe('No files are found', () => {
test('When no file in the directory meets the search string, an empty list is returned', () => {
const startPath = `${rootDirectory}/__tests__/fixtures/projects/monorepo`;
const givenResult = findFilesBy(startPath, 'non-existent.file');

expect(givenResult).toEqual([]);
});

test('When the directory does not exist, an empty list is returned', () => {
const startPath = `${rootDirectory}/non/existent/path`;
const givenResult = findFilesBy(startPath, '.eslintrc.json');

expect(givenResult).toEqual([]);
});
});

test('Disregards files in node_modules directory', () => {
const fs = require('fs');

jest
.spyOn(fs, 'readdirSync')
.mockReturnValue(['package.json']);

jest
.spyOn(fs, 'existsSync')
.mockReturnValue(true);

const startPath = '/my-project/node_modules/my-package';
const givenResult = findFilesBy(startPath, 'package.json');

expect(givenResult).toEqual([]);
})
});
11 changes: 11 additions & 0 deletions __tests__/fixtures/eslint-results/backEndNoError.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"filePath": "/back-end/index.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0,
"usedDeprecatedRules": []
}
]
34 changes: 34 additions & 0 deletions __tests__/fixtures/eslint-results/frontEndNoError.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[
{
"filePath": "/my-react-project/src/App.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
},
{
"filePath": "/my-react-project/src/components/Greeting.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
},
{
"filePath": "/my-react-project/src/index.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
},
{
"filePath": "/my-react-project/src/setupTests.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
}
]
99 changes: 99 additions & 0 deletions __tests__/fixtures/eslint-results/multipleErrorsMultipleFiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
[
{
"filePath": "/my-react-project/src/App.js",
"messages": [
{
"ruleId": "import/order",
"severity": 2,
"message": "`react` import should occur before import of `./components/Greeting`",
"line": 2,
"column": 1,
"nodeType": "ImportDeclaration",
"endLine": 2,
"endColumn": 27,
"fix": {
"range": [
0,
73
],
"text": "import React from 'react';\nimport Greeting from './components/Greeting';\n"
}
},
{
"ruleId": "react/jsx-one-expression-per-line",
"severity": 2,
"message": "`code` must be placed on a new line",
"line": 12,
"column": 16,
"nodeType": "JSXElement",
"endLine": 12,
"endColumn": 39,
"fix": {
"range": [
303,
326
],
"text": "\n{' '}\n<code>src/App.js</code>"
}
},
{
"ruleId": "react/jsx-indent",
"severity": 2,
"message": "Expected indentation of 6 space characters but found 4.",
"line": 24,
"column": 5,
"nodeType": "JSXOpeningElement",
"endLine": 24,
"endColumn": 29,
"fix": {
"range": [
572,
576
],
"text": " "
}
}
],
"errorCount": 3,
"warningCount": 0,
"fixableErrorCount": 3,
"fixableWarningCount": 0,
"source": "import Greeting from './components/Greeting';\nimport React from 'react';\nimport logo from './logo.svg';\nimport './App.css';\n\nfunction App() {\n return (\n <div className=\"App\">\n <header className=\"App-header\">\n <img src={logo} className=\"App-logo\" alt=\"logo\" />\n <p>\n Edit <code>src/App.js</code>\n and save to reload.\n </p>\n <a\n className=\"App-link\"\n href=\"https://reactjs.org\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Learn React\n </a>\n </header>\n <Greeting name=\"Alex\" />\n </div>\n );\n}\n\nexport default App;\n"
},
{
"filePath": "/my-react-project/src/components/Greeting.js",
"messages": [
{
"ruleId": "react/prop-types",
"severity": 2,
"message": "'name' is missing in props validation",
"line": 3,
"column": 21,
"nodeType": "Property",
"endLine": 3,
"endColumn": 25
}
],
"errorCount": 1,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0,
"source": "import React from 'react';\n\nconst Greeting = ({ name }) => <h1>{`Hello, ${name}`}</h1>;\n\nexport default Greeting;\n"
},
{
"filePath": "/my-react-project/src/index.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
},
{
"filePath": "/my-react-project/src/setupTests.js",
"messages": [],
"errorCount": 0,
"warningCount": 0,
"fixableErrorCount": 0,
"fixableWarningCount": 0
}
]
Loading

0 comments on commit 810b5c8

Please sign in to comment.