Skip to content

Commit

Permalink
added compact format and e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dbale-altoros committed Jul 24, 2023
1 parent af1c996 commit 3321154
Show file tree
Hide file tree
Showing 11 changed files with 321 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Linter for Solidity programming language
Options:
-V, --version output the version number
-f, --formatter [name] report formatter name (stylish, table, tap, unix, json)
-f, --formatter [name] report formatter name (stylish, table, tap, unix, json, compact)
-w, --max-warnings [maxWarningsNumber] number of allowed warnings
-c, --config [file_name] file to use as your .solhint.json
-q, --quiet report errors only - default: false
Expand Down
3 changes: 3 additions & 0 deletions e2e/06-formatters/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "solhint:all"
}
11 changes: 11 additions & 0 deletions e2e/06-formatters/contracts/Foo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

contract Foo {
uint256 public constant test1 = 1;
uint256 TEST2;

constructor() {

}
}
10 changes: 10 additions & 0 deletions e2e/06-formatters/contracts/Foo2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.8;

contract Foo {
uint256 public constant test1 = 1;

constructor() {

}
}
126 changes: 126 additions & 0 deletions e2e/06-formatters/helpers/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const getFormatter = (formatter) => {
try {
return require(`../../../lib/formatters/${formatter}`)
} catch (ex) {
ex.message = `\nThere was a problem loading formatter option: ${formatter} \nError: ${ex.message}`
throw ex
}
}
/*
const foo1Messages = [
{
line: 2,
column: 1,
severity: 2,
message: 'Compiler version >=0.6.0 does not satisfy the ^0.5.8 semver requirement',
ruleId: 'compiler-version',
fix: null,
},
{
line: 5,
column: 5,
severity: 3,
message: 'Constant name must be in capitalized SNAKE_CASE',
ruleId: 'const-name-snakecase',
fix: null,
},
{
line: 6,
column: 5,
severity: 3,
message: 'Explicitly mark visibility of state',
ruleId: 'state-visibility',
fix: null,
},
{
line: 6,
column: 5,
severity: 3,
message: "'TEST2' should start with _",
ruleId: 'private-vars-leading-underscore',
fix: null,
},
{
line: 6,
column: 5,
severity: 3,
message: 'Variable name must be in mixedCase',
ruleId: 'var-name-mixedcase',
fix: null,
},
{
line: 8,
column: 5,
severity: 3,
message:
'Explicitly mark visibility in function (Set ignoreConstructors to true if using solidity >=0.7.0)',
ruleId: 'func-visibility',
fix: null,
},
{
line: 8,
column: 19,
severity: 3,
message: 'Code contains empty blocks',
ruleId: 'no-empty-blocks',
fix: null,
},
]
const foo1ExpectedOutput = [
{
messages: foo1Messages,
filePath: 'e2e/06-formatters/contracts/Foo.sol',
},
]
const foo2Messages = [
{
line: 5,
column: 5,
severity: 3,
message: 'Constant name must be in capitalized SNAKE_CASE',
ruleId: 'const-name-snakecase',
fix: null,
},
{
line: 7,
column: 5,
severity: 3,
message:
'Explicitly mark visibility in function (Set ignoreConstructors to true if using solidity >=0.7.0)',
ruleId: 'func-visibility',
fix: null,
},
{
line: 7,
column: 19,
severity: 3,
message: 'Code contains empty blocks',
ruleId: 'no-empty-blocks',
fix: null,
},
]
const foo2Output = [
{
messages: foo2Messages,
filePath: 'e2e/06-formatters/contracts/Foo2.sol',
},
]
*/

const foo1UnixExpectedOutput = `contracts/Foo2.sol:5:5: Constant name must be in capitalized SNAKE_CASE [Warning/const-name-snakecase]
contracts/Foo2.sol:7:5: Explicitly mark visibility in function (Set ignoreConstructors to true if using solidity >=0.7.0) [Warning/func-visibility]
contracts/Foo2.sol:7:19: Code contains empty blocks [Warning/no-empty-blocks]
3 problems`

const foo1JsonExpectedOutput = `contracts/Foo2.sol:5:5: Constant name must be in capitalized SNAKE_CASE [Warning/const-name-snakecase]
contracts/Foo2.sol:7:5: Explicitly mark visibility in function (Set ignoreConstructors to true if using solidity >=0.7.0) [Warning/func-visibility]
contracts/Foo2.sol:7:19: Code contains empty blocks [Warning/no-empty-blocks]
3 problems`


module.exports = { getFormatter, foo1UnixExpectedOutput, foo1JsonExpectedOutput }
1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"license": "MIT",
"devDependencies": {
"chai": "^4.3.7",
"chai-spies": "^1.0.0",
"fs-extra": "^11.1.0",
"get-stream": "^6.0.0",
"mocha": "^10.2.0",
Expand Down
99 changes: 95 additions & 4 deletions e2e/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { expect } = require('chai')
const chai = require('chai')
const { expect } = chai
const cp = require('child_process')
const fs = require('fs-extra')
const getStream = require('get-stream')
Expand Down Expand Up @@ -113,7 +114,7 @@ describe('e2e', function () {
})
})

describe.only('--max-warnings parameter tests', function () {
describe('--max-warnings parameter tests', function () {
// Foo contract has 6 warnings
// Foo2 contract has 1 error and 14 warnings
useFixture('05-max-warnings')
Expand All @@ -128,13 +129,13 @@ describe('e2e', function () {
})

it('should display [warnings exceeded] for max 3 warnings and exit error 1', function () {
const { code, stdout, } = shell.exec('solhint contracts/Foo.sol --max-warnings 3')
const { code, stdout } = shell.exec('solhint contracts/Foo.sol --max-warnings 3')
expect(code).to.equal(1)
expect(stdout.trim()).to.contain(warningExceededMsg)
})

it('should return error for Compiler version rule, ignoring 3 --max-warnings', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol --max-warnings 3')
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol --max-warnings 3')
expect(code).to.equal(1)
expect(stdout.trim()).to.contain(errorFound)
})
Expand All @@ -145,4 +146,94 @@ describe('e2e', function () {
expect(stdout.trim()).to.not.contain(errorFound)
})
})

describe('formatters tests', function () {
// Foo contract has 1 error and 6 warnings
// Foo2 contract has 3 warnings
useFixture('06-formatters')

it('should display COMPACT format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo.sol -f compact')
expect(code).to.equal(0)
expect(stdout.trim()).to.not.contain(warningExceededMsg)
})

it('should display JSON format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo.sol -f json')
expect(code).to.equal(0)
expect(stdout.trim()).to.contain(warningExceededMsg)
})

it('should display STYLISH format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol -f stylish')
expect(code).to.equal(0)
expect(stdout.trim()).to.contain(errorFound)
})

it('should display TABLE format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol -f table')
expect(code).to.equal(0)
expect(stdout.trim()).to.not.contain(errorFound)
})

it('should display TAP format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol -f tap')
expect(code).to.equal(0)
expect(stdout.trim()).to.not.contain(errorFound)
})

it('should display UNIX format', function () {
const { code, stdout } = shell.exec('solhint contracts/Foo2.sol -f unix')
expect(code).to.equal(0)
expect(stdout.trim()).to.not.contain(errorFound)
})
})

describe.only('formatter tests', () => {
// const { getFormatter, foo1Output, foo2Output } = require('./06-formatters/outputs/helpers.js')
const {
getFormatter,
foo1UnixExpectedOutput,
foo1JsonExpectedOutput,
} = require('./06-formatters/helpers/helpers.js')

// Foo contract has 1 error and 6 warnings
// Foo2 contract has 3 warnings
useFixture('06-formatters')

it('should fail when wrong formatter is specify', () => {
const formatterType = 'wrongOne'
const { code } = shell.exec(`solhint contracts/Foo2.sol -f ${formatterType}`)
expect(code).to.equal(1)
})

it('should make the output report with unix formatter', () => {
const formatterType = 'unix'
const { code, stdout } = shell.exec(`solhint contracts/Foo2.sol -f ${formatterType}`)

const formatter = getFormatter(formatterType)
console.log('-------------------------------------------------------------')
console.log('code :>> ', code)
console.log('formatter :>> ', formatter)
console.log('stdout :>> ', stdout)
console.log('=============================================================')

expect(code).to.equal(0)
expect(stdout).to.equal(foo1UnixExpectedOutput)
})
it('json', () => {
const formatterType = 'json'
const { code, stdout } = shell.exec(`solhint contracts/Foo2.sol -f ${formatterType}`)

const formatter = getFormatter(formatterType)
console.log('-------------------------------------------------------------')
console.log('code :>> ', code)
console.log('formatter :>> ', formatter)
console.log('stdout :>> ', stdout)
console.log('=============================================================')

expect(code).to.equal(0)
expect(stdout).to.equal(foo1JsonExpectedOutput)
})
})
})
12 changes: 7 additions & 5 deletions lib/formatters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

files in this directory are pulled from eslint repository:

- table.js: eslint v5.6.0 Gajus Kuizinas <[email protected]>
- unix.js: eslint v8.32.0 oshi-shinobu
- tap.js: eslint v8.32.0 Jonathan Kingston
- stylish.js: eslint v8.32.0 by Sindre Sorhus
- json.js: eslint v8.32.0 by Artur Lukianov & Diego Bale
- table.js: eslint - Gajus Kuizinas
- unix.js: eslint - oshi-shinobu
- tap.js: eslint - Jonathan Kingston
- stylish.js: eslint - Sindre Sorhus
- json.js: eslint - Artur Lukianov & Diego Bale
- compact.js: eslint - Nicholas C. Zakas

53 changes: 53 additions & 0 deletions lib/formatters/compact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @fileoverview Compact reporter
* @author Nicholas C. Zakas
*/

//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------

/**
* Returns the severity of warning or error
* @param {Object} message message object to examine
* @returns {string} severity level
* @private
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return 'Error'
}
return 'Warning'
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

// eslint-disable-next-line func-names
module.exports = function (results) {
let output = ''
let total = 0

results.forEach((result) => {
const messages = result.messages

total += messages.length

messages.forEach((message) => {
output += `${result.filePath}: `
output += `line ${message.line || 0}`
output += `, col ${message.column || 0}`
output += `, ${getMessageType(message)}`
output += ` - ${message.message}`
output += message.ruleId ? ` (${message.ruleId})` : ''
output += '\n'
})
})

if (total > 0) {
output += `\n${total} problem${total !== 1 ? 's' : ''}`
}

return output
}
10 changes: 10 additions & 0 deletions lib/formatters/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,26 @@ function getMessageType(message) {
// eslint-disable-next-line func-names
module.exports = function (results) {
const allMessages = []
let errors = 0
let warnings = 0

results.forEach((result) => {
const messages = result.messages

messages.forEach((message) => {
const fullObject = { ...message, filePath: result.filePath }
fullObject.severity = getMessageType(fullObject)
if (fullObject.severity === 'Error') errors += 1
else warnings += 1
allMessages.push(fullObject)
})
})

const finalMessage = {
conclusion: `${errors + warnings} problems (${errors} errors, ${warnings} warnings)`,
}

allMessages.push(finalMessage)

return JSON.parse(JSON.stringify(allMessages))
}
Loading

0 comments on commit 3321154

Please sign in to comment.