From 819b4bd28c2d95807dab0eb7046b2ed668211e73 Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Fri, 1 Nov 2019 20:55:09 +0100 Subject: [PATCH 1/3] added ignoreEmptyLines to FileLength and MethodLength checks *breaking* removed countEmpty from MethodLength (use ignoreEmptyLines) using token count for threshold in CodeSimilarity --- CHANGELOG.md | 4 + checkstyle.json | 3 - resources/checkstyle-schema.json | 19 ++-- resources/default-config.json | 9 +- .../checks/coding/CodeSimilarityCheck.hx | 41 ++++---- src/checkstyle/checks/size/FileLengthCheck.hx | 21 +++- .../checks/size/MethodLengthCheck.hx | 96 +++++++------------ .../whitespace/ExtendedEmptyLinesCheck.hx | 10 +- .../checks/whitespace/ListOfEmptyLines.hx | 36 ++++++- .../checks/coding/CodeSimilarityCheckTest.hx | 8 ++ .../coding/NestedControlFlowCheckTest.hx | 2 +- .../checks/size/FileLengthCheckTest.hx | 18 +++- .../checks/size/MethodLengthCheckTest.hx | 9 +- .../detect/DetectCodingStyleTest.hx | 6 +- 14 files changed, 166 insertions(+), 116 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 411ba565..81f82026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,16 @@ ## dev branch / next version (2.x.x) +- **Breaking Change** changed `MethodLength.countEmpty` into `ignoreEmptyLines` - New check `CodeSimilarity` to check for similar or identical code blocks ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479) + [#480](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/480) + [#484](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/484)) - New check `EnforceVarTypeHint` to enforce type hints for all variables and finals, fixes [#464](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/464) ([#481](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/481) + [#482](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/482)) - New check `AvoidIdentifier` marks identifiers to avoid ([#483](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/483)) - New check `ArrowFunction` to check for curlies, nested functions and returns in arrow functions ([#484](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/484)) - New check `NestedControlFlow` to check for nested control flow expressions (e.g. `if`, `for`, `while`, `do/while`, `switch` and `try`) ([#485](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/485)) - Added coverage upload to codeclimate ([#478](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/478)) +- Added `ignoreEmptyLines` in FileLengthCheck to ignore empty lines (default = true) +- Changed default value for `max` in `FileLengthCheck` to 1000 +- Changed `MethodLength` check to use tokentree - Fixed allow excluding construtor (`new`) via range exclusion ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479)) - Refactored build system to use lix ([#478](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/478)) - Refactored / renamed AvoidInlineConditionals to AvoidTernaryOperator ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479)) diff --git a/checkstyle.json b/checkstyle.json index 84c25d9a..5030ecfa 100644 --- a/checkstyle.json +++ b/checkstyle.json @@ -134,9 +134,6 @@ } }, { - "props": { - "max": 2000 - }, "type": "FileLength" }, { diff --git a/resources/checkstyle-schema.json b/resources/checkstyle-schema.json index cf86fac1..9b2abb63 100644 --- a/resources/checkstyle-schema.json +++ b/resources/checkstyle-schema.json @@ -910,6 +910,11 @@ "ERROR", "IGNORE" ], + "propertyOrder": 2 + }, + "ignoreEmptyLines": { + "description": "ignores or includes empty lines when counting total file length", + "type": "boolean", "propertyOrder": 1 } }, @@ -3513,12 +3518,12 @@ "additionalProperties": false, "properties": { "thresholdSimilar": { - "description": "threshold for similar code blocks", + "description": "maximum number of tokens allowed before detecting similar code blocks", "type": "integer", "propertyOrder": 2 }, "thresholdIdentical": { - "description": "threshold for identical code blocks", + "description": "maximum number of tokens allowed before detecting identical code blocks", "type": "integer", "propertyOrder": 1 }, @@ -3927,11 +3932,6 @@ "description": "Checks for long methods. If a method becomes very long it is hard to understand. Therefore long methods should usually be refactored into several individual methods that focus on a specific task.", "additionalProperties": false, "properties": { - "countEmpty": { - "description": "maximum includes empty lines / should ignore empty lines", - "type": "boolean", - "propertyOrder": 1 - }, "max": { "description": "maximum number of lines per method (default: 50)", "type": "integer", @@ -3947,6 +3947,11 @@ "IGNORE" ], "propertyOrder": 2 + }, + "ignoreEmptyLines": { + "description": "ignores or includes empty lines when counting method length", + "type": "boolean", + "propertyOrder": 1 } }, "type": "object" diff --git a/resources/default-config.json b/resources/default-config.json index 01cb4f54..6e04ac9c 100644 --- a/resources/default-config.json +++ b/resources/default-config.json @@ -57,8 +57,8 @@ "type": "CodeSimilarity", "props": { "severityIdentical": "WARNING", - "thresholdIdentical": 8, - "thresholdSimilar": 12 + "thresholdIdentical": 60, + "thresholdSimilar": 120 } }, { @@ -192,7 +192,8 @@ { "type": "FileLength", "props": { - "max": 2000 + "max": 1000, + "ignoreEmptyLines": true } }, { @@ -323,7 +324,7 @@ "type": "MethodLength", "props": { "max": 50, - "countEmpty": false + "ignoreEmptyLines": true } }, { diff --git a/src/checkstyle/checks/coding/CodeSimilarityCheck.hx b/src/checkstyle/checks/coding/CodeSimilarityCheck.hx index 77a33745..f2b2c642 100644 --- a/src/checkstyle/checks/coding/CodeSimilarityCheck.hx +++ b/src/checkstyle/checks/coding/CodeSimilarityCheck.hx @@ -28,20 +28,20 @@ class CodeSimilarityCheck extends Check { public var severityIdentical:SeverityLevel; /** - threshold for identical code blocks + maximum number of tokens allowed before detecting identical code blocks **/ public var thresholdIdentical:Int; /** - threshold for similar code blocks + maximum number of tokens allowed before detecting similar code blocks **/ public var thresholdSimilar:Int; public function new() { super(TOKEN); severityIdentical = WARNING; - thresholdIdentical = 8; - thresholdSimilar = 12; + thresholdIdentical = 60; + thresholdSimilar = 120; categories = [STYLE, DUPLICATION]; } @@ -82,10 +82,9 @@ class CodeSimilarityCheck extends Check { var lineStart:LinePos = checker.getLinePos(pos.min); var lineEnd:LinePos = checker.getLinePos(pos.max); - var lines:Int = lineEnd.line - lineStart.line; - if (lines <= Math.min(thresholdIdentical, thresholdSimilar)) return false; var hashes:CodeHashes = makeCodeHashes(token); + if (hashes.tokenCount <= Math.min(thresholdIdentical, thresholdSimilar)) return false; var codeBlock:HashedCodeBlock = { fileName: token.pos.file, lineStart: lineStart, @@ -94,15 +93,15 @@ class CodeSimilarityCheck extends Check { endColumn: offsetToColumn(lineEnd) } - if (lines > thresholdIdentical) { + if (hashes.tokenCount > thresholdIdentical) { var existing:Null = checkOrAddHash(hashes.identicalHash, codeBlock, IDENTICAL_HASHES); if (existing != null) { - logRange("Found identical code block - " + formatFirstFound(existing), pos.min, pos.max, SIMILAR_BLOCK, ERROR); + logRange("Found identical code block - " + formatFirstFound(existing), pos.min, pos.max, SIMILAR_BLOCK, severityIdentical); return true; } } - if (lines > thresholdSimilar) { + if (hashes.tokenCount > thresholdSimilar) { var existing:Null = checkOrAddHash(hashes.similarHash, codeBlock, SIMILAR_HASHES); if (existing == null) return false; logRange("Found similar code block - " + formatFirstFound(existing), pos.min, pos.max, SIMILAR_BLOCK); @@ -126,19 +125,26 @@ class CodeSimilarityCheck extends Check { function makeCodeHashes(token:TokenTree):CodeHashes { var similar:StringBuf = new StringBuf(); var identical:StringBuf = new StringBuf(); - makeCodeHashesRecursive(token, similar, identical); + var tokenCount:Int = makeCodeHashesRecursive(token, similar, identical); return { identicalHash: identical.toString(), - similarHash: similar.toString() + similarHash: similar.toString(), + tokenCount: tokenCount }; } - function makeCodeHashesRecursive(token:TokenTree, similar:StringBuf, identical:StringBuf) { + function makeCodeHashesRecursive(token:TokenTree, similar:StringBuf, identical:StringBuf):Int { similar.add(similarTokenText(token)); - identical.add(identicalTokenText(token)); + var count:Int = 0; + var identicalText:Null = identicalTokenText(token); + if (identicalText != null) { + count++; + identical.add(identicalText); + } if (token.children != null) { - for (child in token.children) makeCodeHashesRecursive(child, similar, identical); + for (child in token.children) count += makeCodeHashesRecursive(child, similar, identical); } + return count; } function similarTokenText(token:TokenTree):String { @@ -184,7 +190,7 @@ class CodeSimilarityCheck extends Check { } } - function identicalTokenText(token:TokenTree):String { + function identicalTokenText(token:TokenTree):Null { switch (token.tok) { case Const(CFloat(f)): return '$f'; @@ -203,9 +209,9 @@ class CodeSimilarityCheck extends Check { case Binop(op): return '$op'; case Comment(_): - return ""; + return null; case CommentLine(_): - return ""; + return null; case IntInterval(i): return '...$i'; default: @@ -241,4 +247,5 @@ typedef HashedCodeBlock = { typedef CodeHashes = { var identicalHash:String; var similarHash:String; + var tokenCount:Int; } \ No newline at end of file diff --git a/src/checkstyle/checks/size/FileLengthCheck.hx b/src/checkstyle/checks/size/FileLengthCheck.hx index 0fa47874..f13318c3 100644 --- a/src/checkstyle/checks/size/FileLengthCheck.hx +++ b/src/checkstyle/checks/size/FileLengthCheck.hx @@ -1,5 +1,7 @@ package checkstyle.checks.size; +import checkstyle.checks.whitespace.ListOfEmptyLines; + /** Checks for long source files. If a source file becomes very long it is hard to understand. Therefore long classes should usually be refactored into several individual classes that focus on a specific task. @@ -7,22 +9,29 @@ package checkstyle.checks.size; @name("FileLength") @desc("Checks for long source files. If a source file becomes very long it is hard to understand. Therefore long classes should usually be refactored into several individual classes that focus on a specific task.") class FileLengthCheck extends Check { - static var DEFAULT_MAX_LENGTH:Int = 2000; + static var DEFAULT_MAX_LENGTH:Int = 1000; /** maximum number of lines permitted per file (default: 2000) **/ public var max:Int; + /** + ignores or includes empty lines when counting total file length + **/ + public var ignoreEmptyLines:Bool; + public function new() { super(LINE); max = DEFAULT_MAX_LENGTH; + ignoreEmptyLines = true; categories = [Category.COMPLEXITY, Category.CLARITY]; points = 21; } override function actualRun() { if (checker.ast == null) return; + for (td in checker.ast.decls) { switch (td.decl) { case EClass(d): @@ -30,7 +39,13 @@ class FileLengthCheck extends Check { default: } } - if (checker.lines.length > max) { + + var count = checker.lines.length; + if (ignoreEmptyLines) { + var emptyLines:ListOfEmptyLines = ListOfEmptyLines.detectEmptyLines(checker); + count -= emptyLines.lines.length; + } + if (count > max) { log('File length is ${checker.lines.length} lines (max allowed is ${max})', checker.lines.length, 0, checker.lines.length, 0); } } @@ -40,7 +55,7 @@ class FileLengthCheck extends Check { fixed: [], properties: [{ propertyName: "max", - values: [for (i in 0...10) 400 + i * 200] + values: [for (i in 0...10) 400 + i * 100] }] }]; } diff --git a/src/checkstyle/checks/size/MethodLengthCheck.hx b/src/checkstyle/checks/size/MethodLengthCheck.hx index b70a32b4..c2369925 100755 --- a/src/checkstyle/checks/size/MethodLengthCheck.hx +++ b/src/checkstyle/checks/size/MethodLengthCheck.hx @@ -1,5 +1,7 @@ package checkstyle.checks.size; +import checkstyle.checks.whitespace.ListOfEmptyLines; + /** Checks for long methods. If a method becomes very long it is hard to understand. Therefore long methods should usually be refactored into several individual methods that focus on a specific task. @@ -15,84 +17,54 @@ class MethodLengthCheck extends Check { public var max:Int; /** - maximum includes empty lines / should ignore empty lines + ignores or includes empty lines when counting method length **/ - public var countEmpty:Bool; + public var ignoreEmptyLines:Bool; public function new() { - super(AST); + super(TOKEN); max = DEFAULT_MAX_LENGTH; - countEmpty = false; + ignoreEmptyLines = true; categories = [Category.COMPLEXITY, Category.CLARITY]; points = 8; } override public function actualRun() { - forEachField(searchField); - } + var root:TokenTree = checker.getTokenTree(); + var functions:Array = root.filter([Kwd(KwdFunction)], FIRST); - function searchField(f:Field, _) { - switch (f.kind) { - case FFun(ff): - checkMethod(f); - default: + var emptyLines:ListOfEmptyLines = ListOfEmptyLines.detectEmptyLines(checker); + for (func in functions) { + if (isPosSuppressed(func.pos)) continue; + checkMethod(func, emptyLines); } - - f.walkField(function(e) { - switch (e.expr) { - case EFunction(name, ff): - checkFunction(e); - default: - } - }); - } - - function checkMethod(f:Field) { - var lp = checker.getLinePos(f.pos.min); - var lmin = lp.line; - var lmax = checker.getLinePos(f.pos.max).line; - - var len = getLineCount(lmin, lmax); - if (len > max) warnFunctionLength(len, f.name, f.pos); } - function checkFunction(f:Expr) { - var lp = checker.getLinePos(f.pos.min); - var lmin = lp.line; - var lmax = checker.getLinePos(f.pos.max).line; - var fname = "(anonymous)"; - switch (f.expr) { - #if (haxe_ver < 4.0) - case EFunction(name, ff): - if (name != null) fname = name; - #else - case EFunction(kind, ff): - switch (kind) { - case null: - case FAnonymous: - var fname = "(anonymous)"; - case FNamed(name, inlined): - fname = name; - case FArrow: - var fname = "(anonymous arrow)"; - } - #end - default: - throw "EFunction only"; + function checkMethod(token:TokenTree, emptyLines:ListOfEmptyLines) { + var pos:Position = token.getPos(); + var lmin:Int = checker.getLinePos(pos.min).line; + var lmax:Int = checker.getLinePos(pos.max).line; + var len:Int = getLineCount(lmin, lmax, emptyLines); + var name:String = "(anonymous)"; + var nameTok:Null = token.access().firstChild().token; + if (nameTok != null) { + switch (nameTok.tok) { + case Const(CIdent(text)): + name = text; + case Kwd(KwdNew): + name = "new"; + case _: + } } - - var len = getLineCount(lmin, lmax); - if (len > max) warnFunctionLength(len, fname, f.pos); + if (len > max) warnFunctionLength(len, name, pos); } - function getLineCount(lmin:Int, lmax:Int):Int { - var emptyLines = 0; - if (countEmpty) { - for (i in lmin...lmax) { - if (~/^\s*$/.match(checker.lines[i]) || ~/^\s*\/\/.*/.match(checker.lines[i])) emptyLines++; - } + function getLineCount(lmin:Int, lmax:Int, emptyLines:ListOfEmptyLines):Int { + var emptyLineCount = 0; + if (ignoreEmptyLines) { + emptyLineCount = emptyLines.countEmptylinesBetween(lmin, lmax); } - return lmax - lmin - emptyLines; + return lmax - lmin - emptyLineCount; } function warnFunctionLength(len:Int, name:String, pos:Position) { @@ -106,7 +78,7 @@ class MethodLengthCheck extends Check { propertyName: "max", values: [for (i in 0...17) 20 + i * 5] }, { - propertyName: "countEmpty", + propertyName: "ignoreEmptyLines", values: [true, false] }] }]; diff --git a/src/checkstyle/checks/whitespace/ExtendedEmptyLinesCheck.hx b/src/checkstyle/checks/whitespace/ExtendedEmptyLinesCheck.hx index 13bab968..b3386e8a 100644 --- a/src/checkstyle/checks/whitespace/ExtendedEmptyLinesCheck.hx +++ b/src/checkstyle/checks/whitespace/ExtendedEmptyLinesCheck.hx @@ -88,7 +88,7 @@ class ExtendedEmptyLinesCheck extends Check { override function actualRun() { buildPolicyMap(); - var emptyLines:ListOfEmptyLines = detectEmptyLines(); + var emptyLines:ListOfEmptyLines = ListOfEmptyLines.detectEmptyLines(checker); if (max <= 0) max = 1; checkPackages(emptyLines); checkImports(emptyLines); @@ -99,14 +99,6 @@ class ExtendedEmptyLinesCheck extends Check { checkComments(emptyLines); } - function detectEmptyLines():ListOfEmptyLines { - var emptyLines:ListOfEmptyLines = new ListOfEmptyLines(); - for (index in 0...checker.lines.length) { - if (~/^\s*$/.match(checker.lines[index])) emptyLines.add(index); - } - return emptyLines; - } - function checkPackages(emptyLines:ListOfEmptyLines) { if (isIgnored([BEFORE_PACKAGE, AFTER_PACKAGE])) return; diff --git a/src/checkstyle/checks/whitespace/ListOfEmptyLines.hx b/src/checkstyle/checks/whitespace/ListOfEmptyLines.hx index 58e22781..4263ae47 100644 --- a/src/checkstyle/checks/whitespace/ListOfEmptyLines.hx +++ b/src/checkstyle/checks/whitespace/ListOfEmptyLines.hx @@ -7,14 +7,32 @@ import checkstyle.checks.whitespace.ExtendedEmptyLinesCheck.EmptyLinesPolicy; line numbers start at 0 **/ class ListOfEmptyLines { - var lines:Array; var lineRanges:Array; + /** + list of empty line indexes + **/ + public var lines:Array; + public function new() { lines = []; lineRanges = null; } + /** + detects empty lines and constructs a ListOfEmptyLines object + + @param checker - checker holding lines of current file + @return populated ListOfEmptyLines instance + **/ + public static function detectEmptyLines(checker:Checker):ListOfEmptyLines { + var emptyLines:ListOfEmptyLines = new ListOfEmptyLines(); + for (index in 0...checker.lines.length) { + if (~/^\s*$/.match(checker.lines[index])) emptyLines.add(index); + } + return emptyLines; + } + /** adds a new empty line number @param line - line number of empty line @@ -169,6 +187,22 @@ class ListOfEmptyLines { return results; } + /** + counts empty lines between starting and ending line + @param startLine first line of range + @param endLine last line of range + @return Int number of empty lines inbetween start and end line + **/ + public function countEmptylinesBetween(startLine:Int, endLine:Int):Int { + var count:Int = 0; + for (line in lines) { + if (line < startLine) continue; + if (line > endLine) continue; + count++; + } + return count; + } + public function toString():String { return lineRanges.toString(); } diff --git a/test/checkstyle/checks/coding/CodeSimilarityCheckTest.hx b/test/checkstyle/checks/coding/CodeSimilarityCheckTest.hx index 2dc1e2bb..b030f49b 100644 --- a/test/checkstyle/checks/coding/CodeSimilarityCheckTest.hx +++ b/test/checkstyle/checks/coding/CodeSimilarityCheckTest.hx @@ -8,30 +8,38 @@ class CodeSimilarityCheckTest extends CheckTestCase { var check = newCheck(); assertNoMsg(check, NOT_SIMILAR_CODE); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE, "Found similar code block - first seen in Test.hx:3"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_IF, "Found similar code block - first seen in Test.hx:4"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_WHILE, "Found similar code block - first seen in Test.hx:4"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_DO_WHILE, "Found similar code block - first seen in Test.hx:4"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_FOR, "Found similar code block - first seen in Test.hx:4"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_TRY, "Found similar code block - first seen in Test.hx:4"); check = newCheck(); + check.thresholdSimilar = 30; assertMsg(check, SIMILAR_CODE_BROPEN, "Found similar code block - first seen in Test.hx:4"); } @Test public function testIdenticalCodeBlocks() { var check = newCheck(); + check.thresholdIdentical = 30; assertMsg(check, IDENTICAL_CODE, "Found identical code block - first seen in Test.hx:4"); } diff --git a/test/checkstyle/checks/coding/NestedControlFlowCheckTest.hx b/test/checkstyle/checks/coding/NestedControlFlowCheckTest.hx index db3e35d6..5dc992af 100644 --- a/test/checkstyle/checks/coding/NestedControlFlowCheckTest.hx +++ b/test/checkstyle/checks/coding/NestedControlFlowCheckTest.hx @@ -67,7 +67,7 @@ abstract NestedControlFlowCheckTests(String) to String { for (outerParam in params) { // level 1 for (middleParam in params) { // level 2 for (innerParam in params) { // level 3 - if (innerParam == null) { // level 4 + if (innerParam == null) { // level 4 } } } diff --git a/test/checkstyle/checks/size/FileLengthCheckTest.hx b/test/checkstyle/checks/size/FileLengthCheckTest.hx index 5e68204d..4c229dfe 100644 --- a/test/checkstyle/checks/size/FileLengthCheckTest.hx +++ b/test/checkstyle/checks/size/FileLengthCheckTest.hx @@ -3,19 +3,31 @@ package checkstyle.checks.size; class FileLengthCheckTest extends CheckTestCase { @Test public function testCorrectLineCount() { - assertNoMsg(new FileLengthCheck(), TEST2000); - assertNoMsg(new FileLengthCheck(), TEST41); + var check = new FileLengthCheck(); + check.ignoreEmptyLines = false; + assertNoMsg(check, TEST41); + + check.ignoreEmptyLines = true; + assertNoMsg(check, TEST2000); + assertNoMsg(check, TEST2001); + + check.ignoreEmptyLines = false; + check.max = 2000; + assertNoMsg(check, TEST2000); } @Test public function testDefaultFileLength() { - assertMsg(new FileLengthCheck(), TEST2001, "File length is 2001 lines (max allowed is 2000)"); + var check = new FileLengthCheck(); + check.ignoreEmptyLines = false; + assertMsg(check, TEST2001, "File length is 2001 lines (max allowed is 1000)"); } @Test public function testConfigurableFileLength() { var check = new FileLengthCheck(); check.max = 40; + check.ignoreEmptyLines = false; assertMsg(check, TEST41, "File length is 42 lines (max allowed is 40)"); } diff --git a/test/checkstyle/checks/size/MethodLengthCheckTest.hx b/test/checkstyle/checks/size/MethodLengthCheckTest.hx index c2a4d575..a9b31b7a 100755 --- a/test/checkstyle/checks/size/MethodLengthCheckTest.hx +++ b/test/checkstyle/checks/size/MethodLengthCheckTest.hx @@ -3,7 +3,9 @@ package checkstyle.checks.size; class MethodLengthCheckTest extends CheckTestCase { @Test public function testWrongMethodLength() { - assertMsg(new MethodLengthCheck(), TEST1, "Method `test` length is 354 lines (max allowed is 50)"); + var check = new MethodLengthCheck(); + check.ignoreEmptyLines = false; + assertMsg(check, TEST1, "Method `test` length is 354 lines (max allowed is 50)"); } @Test @@ -15,6 +17,7 @@ class MethodLengthCheckTest extends CheckTestCase { public function testConfigurableMethodLength() { var check = new MethodLengthCheck(); check.max = 10; + check.ignoreEmptyLines = false; assertMsg(check, TEST3, "Method `test` length is 14 lines (max allowed is 10)"); } @@ -23,11 +26,11 @@ class MethodLengthCheckTest extends CheckTestCase { public function testIgnoreEmptyLines() { var check = new MethodLengthCheck(); check.max = 10; - check.countEmpty = true; + check.ignoreEmptyLines = true; assertNoMsg(check, TEST3); - check.countEmpty = false; + check.ignoreEmptyLines = false; assertMsg(check, TEST3, "Method `test` length is 14 lines (max allowed is 10)"); } diff --git a/test/checkstyle/detect/DetectCodingStyleTest.hx b/test/checkstyle/detect/DetectCodingStyleTest.hx index 77d8c77f..5a0318b4 100644 --- a/test/checkstyle/detect/DetectCodingStyleTest.hx +++ b/test/checkstyle/detect/DetectCodingStyleTest.hx @@ -129,8 +129,8 @@ class DetectCodingStyleTest { Assert.areEqual(1, detectedChecks.length); Assert.areEqual("CodeSimilarity", detectedChecks[0].type); var props = cast detectedChecks[0].props; - Assert.areEqual(8, props.thresholdIdentical); - Assert.areEqual(12, props.thresholdSimilar); + Assert.areEqual(60, props.thresholdIdentical); + Assert.areEqual(120, props.thresholdSimilar); } @Test @@ -410,7 +410,7 @@ class DetectCodingStyleTest { Assert.areEqual("MethodLength", detectedChecks[0].type); var props = cast detectedChecks[0].props; Assert.areEqual(35, props.max); - Assert.isFalse(props.countEmpty); + Assert.isFalse(props.ignoreEmptyLines); } @Test From dfb155aac4fe320b0ca5d2d24a9a9a5b91083dd2 Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Fri, 1 Nov 2019 21:03:19 +0100 Subject: [PATCH 2/3] updated CHANGELOG --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81f82026..cdc18c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,15 @@ ## dev branch / next version (2.x.x) - **Breaking Change** changed `MethodLength.countEmpty` into `ignoreEmptyLines` -- New check `CodeSimilarity` to check for similar or identical code blocks ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479) + [#480](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/480) + [#484](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/484)) +- New check `CodeSimilarity` to check for similar or identical code blocks ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479) + [#480](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/480) + [#484](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/484) + [#486](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/486)) - New check `EnforceVarTypeHint` to enforce type hints for all variables and finals, fixes [#464](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/464) ([#481](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/481) + [#482](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/482)) - New check `AvoidIdentifier` marks identifiers to avoid ([#483](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/483)) - New check `ArrowFunction` to check for curlies, nested functions and returns in arrow functions ([#484](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/484)) - New check `NestedControlFlow` to check for nested control flow expressions (e.g. `if`, `for`, `while`, `do/while`, `switch` and `try`) ([#485](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/485)) - Added coverage upload to codeclimate ([#478](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/478)) -- Added `ignoreEmptyLines` in FileLengthCheck to ignore empty lines (default = true) -- Changed default value for `max` in `FileLengthCheck` to 1000 -- Changed `MethodLength` check to use tokentree +- Added `ignoreEmptyLines` in FileLengthCheck to ignore empty lines (default = true) ([#486](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/486)) +- Changed default value for `max` in `FileLengthCheck` to 1000 ([#486](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/486)) +- Changed `MethodLength` check to use tokentree ([#486](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/486)) - Fixed allow excluding construtor (`new`) via range exclusion ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479)) - Refactored build system to use lix ([#478](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/478)) - Refactored / renamed AvoidInlineConditionals to AvoidTernaryOperator ([#479](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/479)) From f925a226bf602311ad2b6f5f31cec66d2c764407 Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Fri, 1 Nov 2019 21:19:24 +0100 Subject: [PATCH 3/3] report codecov only for Haxe 4.0.0 builds --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 40bfe931..92028949 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,4 +41,4 @@ after_script: - if [[ "$HAXE_VERSION" == "haxe4" ]]; then (cd src; ../cc-test-reporter upload-coverage); fi after_success: - - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports" + - if [[ "$HAXE_VERSION" == "haxe4" ]]; bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"