1
0
mirror of https://github.com/sasjs/lint.git synced 2026-01-16 16:50:05 +00:00

fix(strictMacroDefinition): moved from lineRules to fileRules

This commit is contained in:
Saad Jutt
2021-05-21 17:29:23 +05:00
parent af2d2c12c1
commit f793eb3a76
8 changed files with 351 additions and 232 deletions

View File

@@ -3,4 +3,3 @@ export { maxLineLength } from './maxLineLength'
export { noEncodedPasswords } from './noEncodedPasswords'
export { noTabIndentation } from './noTabIndentation'
export { noTrailingSpaces } from './noTrailingSpaces'
export { strictMacroDefinition } from './strictMacroDefinition'

View File

@@ -1,115 +0,0 @@
import { LintConfig, Severity } from '../../types'
import { strictMacroDefinition } from './strictMacroDefinition'
describe('strictMacroDefinition', () => {
it('should return an empty array when the line has correct macro definition syntax', () => {
const line = '%macro somemacro;'
expect(strictMacroDefinition.test(line, 1)).toEqual([])
const line2 = '%macro somemacro();'
expect(strictMacroDefinition.test(line2, 1)).toEqual([])
const line3 = '%macro somemacro(var1);'
expect(strictMacroDefinition.test(line3, 1)).toEqual([])
const line4 = '%macro somemacro/minoperator;'
expect(strictMacroDefinition.test(line4, 1)).toEqual([])
const line5 = '%macro somemacro /minoperator;'
expect(strictMacroDefinition.test(line5, 1)).toEqual([])
const line6 = '%macro somemacro(var1, var2)/minoperator;'
expect(strictMacroDefinition.test(line6, 1)).toEqual([])
const line7 =
' /* Some Comment */ %macro somemacro(var1, var2) /minoperator ; /* Some Comment */'
expect(strictMacroDefinition.test(line7, 1)).toEqual([])
const line8 =
'%macro macroName( arr, arr/* / store source */3 ) /* / store source */;/* / store source */'
expect(strictMacroDefinition.test(line8, 1)).toEqual([])
const line9 = '%macro macroName(var1, var2=with space, var3=);'
expect(strictMacroDefinition.test(line9, 1)).toEqual([])
const line10 = '%macro macroName()/ /* some comment */ store source;'
expect(strictMacroDefinition.test(line10, 1)).toEqual([])
const line11 = '`%macro macroName() /* / store source */;'
expect(strictMacroDefinition.test(line11, 1)).toEqual([])
})
it('should return an array with a single diagnostic when Macro definition has space in param', () => {
const line = '%macro somemacro(va r1);'
expect(strictMacroDefinition.test(line, 1)).toEqual([
{
message: `Param 'va r1' cannot have space`,
lineNumber: 1,
startColumnNumber: 18,
endColumnNumber: 22,
severity: Severity.Warning
}
])
})
it('should return an array with a two diagnostics when Macro definition has space in params', () => {
const line = '%macro somemacro(var1, var 2, v ar3, var4);'
expect(strictMacroDefinition.test(line, 1)).toEqual([
{
message: `Param 'var 2' cannot have space`,
lineNumber: 1,
startColumnNumber: 24,
endColumnNumber: 28,
severity: Severity.Warning
},
{
message: `Param 'v ar3' cannot have space`,
lineNumber: 1,
startColumnNumber: 31,
endColumnNumber: 35,
severity: Severity.Warning
}
])
})
it('should return an array with a two diagnostics when Macro definition has space in params - special case', () => {
const line =
'%macro macroName( arr, ar r/* / store source */ 3 ) /* / store source */;/* / store source */'
expect(strictMacroDefinition.test(line, 1)).toEqual([
{
message: `Param 'ar r 3' cannot have space`,
lineNumber: 1,
startColumnNumber: 24,
endColumnNumber: 49,
severity: Severity.Warning
}
])
})
it('should return an array with a single diagnostic when Macro definition has invalid option', () => {
const line = '%macro somemacro(var1, var2)/minXoperator;'
expect(strictMacroDefinition.test(line, 1)).toEqual([
{
message: `Option 'minXoperator' is not valid`,
lineNumber: 1,
startColumnNumber: 30,
endColumnNumber: 41,
severity: Severity.Warning
}
])
})
it('should return an array with a two diagnostics when Macro definition has invalid options', () => {
const line =
'%macro somemacro(var1, var2)/ store invalidoption secure ;'
expect(strictMacroDefinition.test(line, 1)).toEqual([
{
message: `Option 'invalidoption' is not valid`,
lineNumber: 1,
startColumnNumber: 39,
endColumnNumber: 51,
severity: Severity.Warning
}
])
})
})

View File

@@ -1,110 +0,0 @@
import { Diagnostic } from '../../types/Diagnostic'
import { LintConfig } from '../../types'
import { LineLintRule } from '../../types/LintRule'
import { LintRuleType } from '../../types/LintRuleType'
import { Severity } from '../../types/Severity'
import { parseMacros } from '../../utils/parseMacros'
const name = 'strictMacroDefinition'
const description = 'Enforce strictly rules of macro definition syntax.'
const message = 'Incorrent Macro Definition Syntax'
const validOptions = [
'CMD',
'DES',
'MINDELIMITER',
'MINOPERATOR',
'NOMINOPERATOR',
'PARMBUFF',
'SECURE',
'NOSECURE',
'STMT',
'SOURCE',
'SRC',
'STORE'
]
const test = (value: string, lineNumber: number) => {
const diagnostics: Diagnostic[] = []
const macros = parseMacros(value)
const declaration = macros[0]?.declaration
if (!declaration) return []
const regExpParams = new RegExp(/\((.*?)\)/)
const regExpParamsResult = regExpParams.exec(declaration)
let _declaration = declaration
if (regExpParamsResult) {
const paramsPresent = regExpParamsResult[1]
const paramsTrimmed = paramsPresent.trim()
const params = paramsTrimmed.split(',')
params.forEach((param) => {
const trimedParam = param.split('=')[0].trim()
let paramStartIndex: number = 1,
paramEndIndex: number = value.length
if (value.indexOf(trimedParam) === -1) {
const comment = '/\\*(.*?)\\*/'
for (let i = 1; i < trimedParam.length; i++) {
const paramWithComment =
trimedParam.slice(0, i) + comment + trimedParam.slice(i)
const regEx = new RegExp(paramWithComment)
const result = regEx.exec(value)
if (result) {
paramStartIndex = value.indexOf(result[0])
paramEndIndex = value.indexOf(result[0]) + result[0].length
break
}
}
} else {
paramStartIndex = value.indexOf(trimedParam)
paramEndIndex = value.indexOf(trimedParam) + trimedParam.length
}
if (trimedParam.includes(' ')) {
diagnostics.push({
message: `Param '${trimedParam}' cannot have space`,
lineNumber,
startColumnNumber: paramStartIndex + 1,
endColumnNumber: paramEndIndex,
severity: Severity.Warning
})
}
})
_declaration = declaration.split(`(${paramsPresent})`)[1]
}
const optionsPresent = _declaration.split('/')?.[1]?.trim().split(' ')
optionsPresent
?.filter((o) => !!o)
.forEach((option) => {
const trimmedOption = option.trim()
if (!validOptions.includes(trimmedOption.toUpperCase())) {
diagnostics.push({
message: `Option '${trimmedOption}' is not valid`,
lineNumber,
startColumnNumber: value.indexOf(trimmedOption) + 1,
endColumnNumber: value.indexOf(trimmedOption) + trimmedOption.length,
severity: Severity.Warning
})
}
})
return diagnostics
}
/**
* Lint rule that checks if a line has followed syntax for macro definition
*/
export const strictMacroDefinition: LineLintRule = {
type: LintRuleType.Line,
name,
description,
message,
test
}