From 97e3490a8d7b164ab61a139b9c1301c5ffeaf231 Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Tue, 27 Dec 2022 23:22:40 +0500 Subject: [PATCH 1/8] fix: add few more gremlins --- src/rules/line/noGremlins.ts | 71 +------- src/utils/grimlinCharacters.ts | 314 +++++++++++++++++++++++++++++++++ src/utils/index.ts | 1 + 3 files changed, 316 insertions(+), 70 deletions(-) create mode 100644 src/utils/grimlinCharacters.ts diff --git a/src/rules/line/noGremlins.ts b/src/rules/line/noGremlins.ts index f52d3f9..ee1e4bc 100644 --- a/src/rules/line/noGremlins.ts +++ b/src/rules/line/noGremlins.ts @@ -2,6 +2,7 @@ import { Diagnostic, LintConfig } from '../../types' import { LineLintRule } from '../../types/LintRule' import { LintRuleType } from '../../types/LintRuleType' import { Severity } from '../../types/Severity' +import { gremlinCharacters } from '../../utils' const name = 'noGremlins' const description = 'Disallow characters specified in gremlins array' @@ -56,73 +57,3 @@ export const noGremlins: LineLintRule = { } const charFromHex = (hexCode: string) => String.fromCodePoint(parseInt(hexCode)) - -const gremlinCharacters = { - '0x2013': { - description: 'en dash' - }, - '0x2018': { - description: 'left single quotation mark' - }, - '0x2019': { - description: 'right single quotation mark' - }, - '0x2029': { - zeroWidth: true, - description: 'paragraph separator' - }, - '0x2066': { - zeroWidth: true, - description: 'Left to right' - }, - '0x2069': { - zeroWidth: true, - description: 'Pop directional' - }, - '0x0003': { - description: 'end of text' - }, - '0x000b': { - description: 'line tabulation' - }, - '0x00a0': { - description: 'non breaking space' - }, - '0x00ad': { - description: 'soft hyphen' - }, - '0x200b': { - zeroWidth: true, - description: 'zero width space' - }, - '0x200c': { - zeroWidth: true, - description: 'zero width non-joiner' - }, - '0x200e': { - zeroWidth: true, - description: 'left-to-right mark' - }, - '0x201c': { - description: 'left double quotation mark' - }, - '0x201d': { - description: 'right double quotation mark' - }, - '0x202c': { - zeroWidth: true, - description: 'pop directional formatting' - }, - '0x202d': { - zeroWidth: true, - description: 'left-to-right override' - }, - '0x202e': { - zeroWidth: true, - description: 'right-to-left override' - }, - '0xfffc': { - zeroWidth: true, - description: 'object replacement character' - } -} diff --git a/src/utils/grimlinCharacters.ts b/src/utils/grimlinCharacters.ts new file mode 100644 index 0000000..3a5f0f2 --- /dev/null +++ b/src/utils/grimlinCharacters.ts @@ -0,0 +1,314 @@ +// Used https://compart.com/en/unicode to find the to find the description of each gremlin +// List of gremlins was deduced from https://github.com/redoPop/SublimeGremlins/blob/main/Gremlins.py#L13 + +export const gremlinCharacters = { + '0x0003': { + description: 'End of Text' + }, + '0x000b': { + description: 'Line Tabulation' + }, + '0x007f': { + description: 'Delete' + }, + '0x0080': { + description: 'Padding' + }, + '0x0081': { + description: 'High Octet Preset' + }, + '0x0082': { + description: 'Break Permitted Here' + }, + '0x0083': { + description: 'No Break Here' + }, + '0x0084': { + description: 'Index' + }, + '0x0085': { + description: 'Next Line' + }, + '0x0086': { + description: 'Start of Selected Area' + }, + '0x0087': { + description: 'End of Selected Area' + }, + '0x0088': { + description: 'Character Tabulation Set' + }, + '0x0089': { + description: 'Character Tabulation with Justification' + }, + '0x008a': { + description: 'Line Tabulation Set' + }, + '0x008b': { + description: 'Partial Line Down' + }, + '0x008c': { + description: 'Partial Line Backward' + }, + '0x008d': { + description: 'Reverse Index' + }, + '0x008e': { + description: 'Single Shift Two' + }, + '0x008f': { + description: 'Single Shift Three' + }, + '0x0090': { + description: 'Device Control String' + }, + '0x0091': { + description: 'Private Use One' + }, + '0x0092': { + description: 'Private Use Two' + }, + '0x0093': { + description: 'Set Transmit State' + }, + '0x0094': { + description: 'Cancel Character' + }, + '0x0095': { + description: 'Message Waiting' + }, + '0x0096': { + description: 'Start of Guarded Area' + }, + '0x0097': { + description: 'End of Guarded Area' + }, + '0x0098': { + description: 'Start of String' + }, + '0x0099': { + description: 'Single Graphic Character Introducer' + }, + '0x009a': { + description: 'Single Character Introducer' + }, + '0x009b': { + description: 'Control Sequence Introducer' + }, + '0x009c': { + description: 'String Terminator' + }, + '0x009d': { + description: 'Operating System Command' + }, + '0x009e': { + description: 'Privacy Message' + }, + '0x009f': { + description: 'Application Program Command' + }, + '0x00a0': { + description: 'non breaking space' + }, + '0x00ad': { + description: 'Soft Hyphen' + }, + '0x2000': { + description: 'En Quad' + }, + '0x2001': { + description: 'Em Quad' + }, + '0x2002': { + description: 'En Space' + }, + '0x2003': { + description: 'Em Space' + }, + '0x2004': { + description: 'Three-Per-Em Space' + }, + '0x2005': { + description: 'Four-Per-Em Space' + }, + '0x2006': { + description: 'Six-Per-Em Space' + }, + '0x2007': { + description: 'Figure Space' + }, + '0x2008': { + description: 'Punctuation Space' + }, + '0x2009': { + description: 'Thin Space' + }, + '0x200a': { + description: 'Hair Space' + }, + '0x200b': { + description: 'Zero Width Space' + }, + '0x200c': { + description: 'Zero Width Non-Joiner' + }, + '0x200d': { + description: 'Zero Width Joiner' + }, + '0x200e': { + description: 'Left-to-Right Mark' + }, + '0x200f': { + description: 'Right-to-Left Mark' + }, + '0x2013': { + description: 'En Dash' + }, + '0x2018': { + description: 'Left Single Quotation Mark' + }, + '0x2019': { + description: 'Right Single Quotation Mark' + }, + '0x201c': { + description: 'Left Double Quotation Mark' + }, + '0x201d': { + description: 'Right Double Quotation Mark' + }, + '0x2028': { + description: 'Line Separator' + }, + '0x2029': { + description: 'Paragraph Separator' + }, + '0x202a': { + description: 'Left-to-Right Embedding' + }, + '0x202b': { + description: 'Right-to-Left Embedding' + }, + '0x202c': { + description: 'Pop Directional Formatting' + }, + '0x202d': { + description: 'Left-to-Right Override' + }, + '0x202e': { + description: 'Right-to-Left Override' + }, + '0x202f': { + description: 'Narrow No-Break Space' + }, + '0x205f': { + description: 'Medium Mathematical Space' + }, + '0x2060': { + description: 'Word Joiner' + }, + '0x2061': { + description: 'Function Application' + }, + '0x2062': { + description: 'Invisible Times' + }, + '0x2063': { + description: 'Invisible Separator' + }, + '0x2064': { + description: 'Invisible Plus' + }, + '0x2066': { + description: 'Left-to-Right Isolate' + }, + '0x2067': { + description: 'Right-to-Left Isolate' + }, + '0x2068': { + description: 'First Strong Isolate ' + }, + '0x2069': { + description: 'Pop Directional Isolate' + }, + '0x206a': { + description: 'Inhibit Symmetric Swapping' + }, + '0x206b': { + description: 'Activate Symmetric Swapping' + }, + '0x206c': { + description: 'Inhibit Arabic Form Shaping' + }, + '0x206d': { + description: 'Activate Arabic Form Shaping' + }, + '0x206e': { + description: 'National Digit Shapes' + }, + '0x206f': { + description: 'Nominal Digit Shapes' + }, + '0x2800': { + description: 'Braille Pattern Blank' + }, + '0x3000': { + description: 'Ideographic Space' + }, + '0x3164': { + description: 'Hangul Filler' + }, + '0xfe00': { + description: 'Variation Selector-1' + }, + '0xfe01': { + description: 'Variation Selector-2' + }, + '0xfe02': { + description: 'Variation Selector-3' + }, + '0xfe03': { + description: 'Variation Selector-4' + }, + '0xfe04': { + description: 'Variation Selector-5' + }, + '0xfe05': { + description: 'Variation Selector-6' + }, + '0xfe06': { + description: 'Variation Selector-7' + }, + '0xfe07': { + description: 'Variation Selector-8' + }, + '0xfe08': { + description: 'Variation Selector-9' + }, + '0xfe09': { + description: 'Variation Selector-10' + }, + '0xfe0a': { + description: 'Variation Selector-11' + }, + '0xfe0b': { + description: 'Variation Selector-12 ' + }, + '0xfe0c': { + description: 'Variation Selector-13' + }, + '0xfe0d': { + description: 'Variation Selector-14' + }, + '0xfe0e': { + description: 'Variation Selector-15' + }, + '0xfe0f': { + description: 'Variation Selector-16' + }, + '0xfeff': { + description: 'Zero Width No-Break Space' + }, + '0xfffc': { + description: 'Object Replacement Character' + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 5dec0de..f6adbf3 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,7 @@ export * from './asyncForEach' export * from './getLintConfig' export * from './getProjectRoot' +export * from './grimlinCharacters' export * from './isIgnored' export * from './listSasFiles' export * from './splitText' From 8cf4f34e302d10e304d4f4bca5c6fc20ae991039 Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Tue, 27 Dec 2022 23:29:55 +0500 Subject: [PATCH 2/8] fix: noGremlins should be true by default even though if its not defined in .sasjslint --- src/types/LintConfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/LintConfig.ts b/src/types/LintConfig.ts index b532d00..557e398 100644 --- a/src/types/LintConfig.ts +++ b/src/types/LintConfig.ts @@ -120,7 +120,7 @@ export class LintConfig { this.fileLintRules.push(strictMacroDefinition) } - if (json?.noGremlins) { + if (json?.noGremlins === undefined || json?.noGremlins) { this.lineLintRules.push(noGremlins) } From 4b16e0c52a916d8509b11c7d89e0db4985c5052a Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Tue, 27 Dec 2022 23:55:36 +0500 Subject: [PATCH 3/8] chore: typo fix --- src/utils/{grimlinCharacters.ts => gremlinCharacters.ts} | 0 src/utils/index.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/utils/{grimlinCharacters.ts => gremlinCharacters.ts} (100%) diff --git a/src/utils/grimlinCharacters.ts b/src/utils/gremlinCharacters.ts similarity index 100% rename from src/utils/grimlinCharacters.ts rename to src/utils/gremlinCharacters.ts diff --git a/src/utils/index.ts b/src/utils/index.ts index f6adbf3..958b2c7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,7 +1,7 @@ export * from './asyncForEach' export * from './getLintConfig' export * from './getProjectRoot' -export * from './grimlinCharacters' +export * from './gremlinCharacters' export * from './isIgnored' export * from './listSasFiles' export * from './splitText' From c0fdfc6ac99eb83f104de5d4e1edc9136f72e07c Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 29 Dec 2022 00:46:50 +0500 Subject: [PATCH 4/8] fix: pass lint config to lintFile calling from formatFile --- src/format/formatFile.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/format/formatFile.ts b/src/format/formatFile.ts index 87bd36f..d81fbf2 100644 --- a/src/format/formatFile.ts +++ b/src/format/formatFile.ts @@ -16,7 +16,7 @@ export const formatFile = async ( configuration?: LintConfig ): Promise => { const config = configuration || (await getLintConfig()) - const diagnosticsBeforeFormat = await lintFile(filePath) + const diagnosticsBeforeFormat = await lintFile(filePath, config) const diagnosticsCountBeforeFormat = diagnosticsBeforeFormat.length const text = await readFile(filePath) @@ -25,7 +25,7 @@ export const formatFile = async ( await createFile(filePath, formattedText) - const diagnosticsAfterFormat = await lintFile(filePath) + const diagnosticsAfterFormat = await lintFile(filePath, config) const diagnosticsCountAfterFormat = diagnosticsAfterFormat.length const fixedDiagnosticsCount = From 5c44ec400de963a04bcd02750028f2d55070819a Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 29 Dec 2022 00:47:54 +0500 Subject: [PATCH 5/8] chore: quick fix --- src/format/shared.ts | 2 +- src/utils/getLintConfig.ts | 1 + src/utils/splitText.ts | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/format/shared.ts b/src/format/shared.ts index 76702f1..54dcfb2 100644 --- a/src/format/shared.ts +++ b/src/format/shared.ts @@ -30,7 +30,7 @@ export const processLine = (config: LintConfig, line: string): string => { config.lineLintRules .filter((r) => !!r.fix) .forEach((rule) => { - processedLine = rule.fix!(line, config) + processedLine = rule.fix!(processedLine, config) }) return processedLine diff --git a/src/utils/getLintConfig.ts b/src/utils/getLintConfig.ts index 1175a53..8914dc3 100644 --- a/src/utils/getLintConfig.ts +++ b/src/utils/getLintConfig.ts @@ -22,6 +22,7 @@ export const DefaultLintConfiguration = { noNestedMacros: true, hasMacroParentheses: true, strictMacroDefinition: true, + noGremlins: true, defaultHeader: getDefaultHeader() } diff --git a/src/utils/splitText.ts b/src/utils/splitText.ts index 498230e..786cac8 100644 --- a/src/utils/splitText.ts +++ b/src/utils/splitText.ts @@ -8,10 +8,19 @@ import { LineEndings } from '../types/LineEndings' */ export const splitText = (text: string, config: LintConfig): string[] => { if (!text) return [] + const expectedLineEndings = config.lineEndings === LineEndings.LF ? '\n' : '\r\n' + const incorrectLineEndings = expectedLineEndings === '\n' ? '\r\n' : '\n' - return text - .replace(new RegExp(incorrectLineEndings, 'g'), expectedLineEndings) - .split(expectedLineEndings) + + text = text.replace( + new RegExp(incorrectLineEndings, 'g'), + expectedLineEndings + ) + + // splitting text on '\r\n' was causing some problem + // as it was retaining carriage return at the end of each line + // so, removed the carriage returns from text and splitted on line feed (lf) + return text.replace(/\r/g, '').split(/\n/) } From 24fba7867c113a8e8df5cc848d05578251ce858d Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 29 Dec 2022 00:49:13 +0500 Subject: [PATCH 6/8] fix: update the logic for default values of rules --- src/types/LintConfig.ts | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/types/LintConfig.ts b/src/types/LintConfig.ts index 557e398..4f0eb74 100644 --- a/src/types/LintConfig.ts +++ b/src/types/LintConfig.ts @@ -53,23 +53,25 @@ export class LintConfig { } } - if (json?.noTrailingSpaces) { + if (json?.noTrailingSpaces !== false) { this.lineLintRules.push(noTrailingSpaces) } - if (json?.noEncodedPasswords) { + if (json?.noEncodedPasswords !== false) { this.lineLintRules.push(noEncodedPasswords) } - if (json?.noTabs || json?.noTabIndentation) { - this.lineLintRules.push(noTabs) + this.lineLintRules.push(noTabs) + if (json?.noTabs === false || json?.noTabIndentation === false) { + this.lineLintRules.pop() } - if (json?.maxLineLength) { + this.lineLintRules.push(maxLineLength) + if (!isNaN(json?.maxLineLength)) { this.maxLineLength = json.maxLineLength - this.lineLintRules.push(maxLineLength) } + this.fileLintRules.push(lineEndings) if (json?.lineEndings) { if ( json.lineEndings !== LineEndings.LF && @@ -80,15 +82,14 @@ export class LintConfig { ) } this.lineEndings = json.lineEndings - this.fileLintRules.push(lineEndings) } + this.lineLintRules.push(indentationMultiple) if (!isNaN(json?.indentationMultiple)) { this.indentationMultiple = json.indentationMultiple as number - this.lineLintRules.push(indentationMultiple) } - if (json?.hasDoxygenHeader) { + if (json?.hasDoxygenHeader !== false) { this.fileLintRules.push(hasDoxygenHeader) } @@ -96,11 +97,11 @@ export class LintConfig { this.defaultHeader = json.defaultHeader } - if (json?.noSpacesInFileNames) { + if (json?.noSpacesInFileNames !== false) { this.pathLintRules.push(noSpacesInFileNames) } - if (json?.lowerCaseFileNames) { + if (json?.lowerCaseFileNames !== false) { this.pathLintRules.push(lowerCaseFileNames) } @@ -108,19 +109,19 @@ export class LintConfig { this.fileLintRules.push(hasMacroNameInMend) } - if (json?.noNestedMacros) { + if (json?.noNestedMacros !== false) { this.fileLintRules.push(noNestedMacros) } - if (json?.hasMacroParentheses) { + if (json?.hasMacroParentheses !== false) { this.fileLintRules.push(hasMacroParentheses) } - if (json?.strictMacroDefinition) { + if (json?.strictMacroDefinition !== false) { this.fileLintRules.push(strictMacroDefinition) } - if (json?.noGremlins === undefined || json?.noGremlins) { + if (json?.noGremlins !== false) { this.lineLintRules.push(noGremlins) } From 636703b326fc28f814a1e2870e3e9571ce5ad974 Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 29 Dec 2022 00:49:40 +0500 Subject: [PATCH 7/8] chore: specs fix --- src/format/formatFile.spec.ts | 12 ++---------- src/utils/getLintConfig.spec.ts | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/format/formatFile.spec.ts b/src/format/formatFile.spec.ts index 02cf58c..284c61a 100644 --- a/src/format/formatFile.spec.ts +++ b/src/format/formatFile.spec.ts @@ -32,16 +32,8 @@ describe('formatFile', () => { const expectedContent = `/**\r\n @file\r\n @brief \r\n

SAS Macros

\r\n**/\r\n%macro somemacro();\r\n%put 'hello';\r\n%mend;` const expectedResult = { updatedFilePaths: [path.join(__dirname, 'format-file-config.sas')], - fixedDiagnosticsCount: 2, - unfixedDiagnostics: [ - { - endColumnNumber: 7, - lineNumber: 8, - message: '%mend statement is missing macro name - somemacro', - severity: 1, - startColumnNumber: 1 - } - ] + fixedDiagnosticsCount: 4, + unfixedDiagnostics: [] } await createFile(path.join(__dirname, 'format-file-config.sas'), content) diff --git a/src/utils/getLintConfig.spec.ts b/src/utils/getLintConfig.spec.ts index 75be58d..7843ad8 100644 --- a/src/utils/getLintConfig.spec.ts +++ b/src/utils/getLintConfig.spec.ts @@ -2,8 +2,8 @@ import * as fileModule from '@sasjs/utils/file' import { LintConfig } from '../types/LintConfig' import { getLintConfig } from './getLintConfig' -const expectedFileLintRulesCount = 5 -const expectedLineLintRulesCount = 5 +const expectedFileLintRulesCount = 6 +const expectedLineLintRulesCount = 6 const expectedPathLintRulesCount = 2 describe('getLintConfig', () => { From 5245246818c24f3d4cfc49165692063c9053abd5 Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 29 Dec 2022 18:52:21 +0500 Subject: [PATCH 8/8] chore: fix specs --- src/types/LintConfig.spec.ts | 116 +++++++++++++++-------------------- 1 file changed, 51 insertions(+), 65 deletions(-) diff --git a/src/types/LintConfig.spec.ts b/src/types/LintConfig.spec.ts index 48b6b09..c30754f 100644 --- a/src/types/LintConfig.spec.ts +++ b/src/types/LintConfig.spec.ts @@ -4,96 +4,75 @@ import { LintRuleType } from './LintRuleType' import { Severity } from './Severity' describe('LintConfig', () => { - it('should create an empty instance', () => { + it('should create an instance with default values when no configuration is provided', () => { const config = new LintConfig() - expect(config).toBeTruthy() - expect(config.fileLintRules.length).toEqual(0) - expect(config.lineLintRules.length).toEqual(0) }) - it('should create an instance with the noTrailingSpaces flag set', () => { - const config = new LintConfig({ noTrailingSpaces: true }) + it('should create an instance with the noTrailingSpaces flag off', () => { + const config = new LintConfig({ noTrailingSpaces: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(1) - expect(config.lineLintRules[0].name).toEqual('noTrailingSpaces') - expect(config.lineLintRules[0].type).toEqual(LintRuleType.Line) - expect(config.fileLintRules.length).toEqual(0) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.lineLintRules.find((rule) => rule.name === 'noTrailingSpaces') + ).toBeUndefined() }) - it('should create an instance with the noEncodedPasswords flag set', () => { - const config = new LintConfig({ noEncodedPasswords: true }) + it('should create an instance with the noEncodedPasswords flag off', () => { + const config = new LintConfig({ noEncodedPasswords: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(1) - expect(config.lineLintRules[0].name).toEqual('noEncodedPasswords') - expect(config.lineLintRules[0].type).toEqual(LintRuleType.Line) - expect(config.fileLintRules.length).toEqual(0) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.lineLintRules.find((rule) => rule.name === 'noEncodedPasswords') + ).toBeUndefined() }) - it('should create an instance with the hasDoxygenHeader flag set', () => { - const config = new LintConfig({ hasDoxygenHeader: true }) + it('should create an instance with the hasDoxygenHeader flag off', () => { + const config = new LintConfig({ hasDoxygenHeader: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(1) - expect(config.fileLintRules[0].name).toEqual('hasDoxygenHeader') - expect(config.fileLintRules[0].type).toEqual(LintRuleType.File) - }) - - it('should create an instance with the hasMacroNameInMend flag set', () => { - const config = new LintConfig({ hasMacroNameInMend: true }) - - expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(1) - expect(config.fileLintRules[0].name).toEqual('hasMacroNameInMend') - expect(config.fileLintRules[0].type).toEqual(LintRuleType.File) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.fileLintRules.find((rule) => rule.name === 'hasDoxygenHeader') + ).toBeUndefined() }) it('should create an instance with the hasMacroNameInMend flag off', () => { const config = new LintConfig({ hasMacroNameInMend: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(0) - }) - - it('should create an instance with the noNestedMacros flag set', () => { - const config = new LintConfig({ noNestedMacros: true }) - - expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(1) - expect(config.fileLintRules[0].name).toEqual('noNestedMacros') - expect(config.fileLintRules[0].type).toEqual(LintRuleType.File) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.fileLintRules.find((rule) => rule.name === 'hasMacroNameInMend') + ).toBeUndefined() }) it('should create an instance with the noNestedMacros flag off', () => { const config = new LintConfig({ noNestedMacros: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(0) - }) - - it('should create an instance with the hasMacroParentheses flag set', () => { - const config = new LintConfig({ hasMacroParentheses: true }) - - expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(1) - expect(config.fileLintRules[0].name).toEqual('hasMacroParentheses') - expect(config.fileLintRules[0].type).toEqual(LintRuleType.File) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.fileLintRules.find((rule) => rule.name === 'noNestedMacros') + ).toBeUndefined() }) it('should create an instance with the hasMacroParentheses flag off', () => { const config = new LintConfig({ hasMacroParentheses: false }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(0) - expect(config.fileLintRules.length).toEqual(0) + expect(config.lineLintRules.length).toBeGreaterThan(0) + expect(config.fileLintRules.length).toBeGreaterThan(0) + expect( + config.fileLintRules.find((rule) => rule.name === 'hasMacroParentheses') + ).toBeUndefined() }) it('should create an instance with the indentation multiple set', () => { @@ -166,11 +145,12 @@ describe('LintConfig', () => { indentationMultiple: 2, hasMacroNameInMend: true, noNestedMacros: true, - hasMacroParentheses: true + hasMacroParentheses: true, + noGremlins: true }) expect(config).toBeTruthy() - expect(config.lineLintRules.length).toEqual(5) + expect(config.lineLintRules.length).toEqual(6) expect(config.lineLintRules[0].name).toEqual('noTrailingSpaces') expect(config.lineLintRules[0].type).toEqual(LintRuleType.Line) expect(config.lineLintRules[1].name).toEqual('noEncodedPasswords') @@ -181,16 +161,22 @@ describe('LintConfig', () => { expect(config.lineLintRules[3].type).toEqual(LintRuleType.Line) expect(config.lineLintRules[4].name).toEqual('indentationMultiple') expect(config.lineLintRules[4].type).toEqual(LintRuleType.Line) + expect(config.lineLintRules[5].name).toEqual('noGremlins') + expect(config.lineLintRules[5].type).toEqual(LintRuleType.Line) - expect(config.fileLintRules.length).toEqual(4) - expect(config.fileLintRules[0].name).toEqual('hasDoxygenHeader') + expect(config.fileLintRules.length).toEqual(6) + expect(config.fileLintRules[0].name).toEqual('lineEndings') expect(config.fileLintRules[0].type).toEqual(LintRuleType.File) - expect(config.fileLintRules[1].name).toEqual('hasMacroNameInMend') + expect(config.fileLintRules[1].name).toEqual('hasDoxygenHeader') expect(config.fileLintRules[1].type).toEqual(LintRuleType.File) - expect(config.fileLintRules[2].name).toEqual('noNestedMacros') + expect(config.fileLintRules[2].name).toEqual('hasMacroNameInMend') expect(config.fileLintRules[2].type).toEqual(LintRuleType.File) - expect(config.fileLintRules[3].name).toEqual('hasMacroParentheses') + expect(config.fileLintRules[3].name).toEqual('noNestedMacros') expect(config.fileLintRules[3].type).toEqual(LintRuleType.File) + expect(config.fileLintRules[4].name).toEqual('hasMacroParentheses') + expect(config.fileLintRules[4].type).toEqual(LintRuleType.File) + expect(config.fileLintRules[5].name).toEqual('strictMacroDefinition') + expect(config.fileLintRules[5].type).toEqual(LintRuleType.File) expect(config.pathLintRules.length).toEqual(2) expect(config.pathLintRules[0].name).toEqual('noSpacesInFileNames')