diff --git a/src/Microdown-Rules/MicMethodStructureChecker.class.st b/src/Microdown-Rules/MicMethodStructureChecker.class.st new file mode 100644 index 00000000..94db3803 --- /dev/null +++ b/src/Microdown-Rules/MicMethodStructureChecker.class.st @@ -0,0 +1,50 @@ +" +I check that methods in code blocks have an empty line after the selector when there is no comment. + +Example of incorrect method (no comment, no empty line): + goodWordFor: aString + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value + +Example of correct method (no comment, empty line after selector): + goodWordFor: aString + + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value + +Example of correct method (with comment, no empty line needed): + goodWordFor: aString + ""there is a comment"" + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value +" +Class { + #name : 'MicMethodStructureChecker', + #superclass : 'MicChecker', + #category : 'Microdown-Rules-MethodStructure', + #package : 'Microdown-Rules', + #tag : 'MethodStructure' +} + +{ #category : 'visiting' } +MicMethodStructureChecker >> visitCode: aMicCode [ + | lines firstLine secondLine | + lines := aMicCode body lines. + lines size < 2 ifTrue: [ ^ self ]. + firstLine := lines first. + secondLine := lines second. + "If the second line begins with a comment, that's correct." + (secondLine trimLeft beginsWith: '"') ifTrue: [ ^ self ]. + "If the second line is empty, it's correct." + secondLine trimLeft isEmpty ifTrue: [ ^ self ]. + "ifelse, theres's a blank line missing after the selector" + results add: (MicMethodStructureResult new + micElement: aMicCode; + inFile: aMicCode; + detail: firstLine; + yourself + ) +] diff --git a/src/Microdown-Rules/MicMethodStructureCheckerTest.class.st b/src/Microdown-Rules/MicMethodStructureCheckerTest.class.st new file mode 100644 index 00000000..f95f0376 --- /dev/null +++ b/src/Microdown-Rules/MicMethodStructureCheckerTest.class.st @@ -0,0 +1,77 @@ +Class { + #name : 'MicMethodStructureCheckerTest', + #superclass : 'TestCase', + #instVars : [ + 'fileSystem', + 'checker' + ], + #category : 'Microdown-Rules-MethodStructure', + #package : 'Microdown-Rules', + #tag : 'MethodStructure' +} + +{ #category : 'running' } +MicMethodStructureCheckerTest >> generateFilesystemExample [ + | file | + file := fileSystem workingDirectory / 'methodWrong.md'. + file writeStreamDo: [ :stream | + stream nextPutAll: '``` + goodWordFor: aString + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value + + `````' + ]. + file := fileSystem workingDirectory / 'methodCorrect.md'. + file writeStreamDo: [ :stream | + stream nextPutAll: '``` + goodWordFor: aString + + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value + + `````' + ]. + file := fileSystem workingDirectory / 'methodWithComment.md'. + file writeStreamDo: [ :stream | + stream nextPutAll: '``` + goodWordFor: aString + "there is a comment" + | pair | + pair := pairs detect: [ :each | each key = aString ]. + ^ pair value + + `````' + ]. +] + +{ #category : 'running' } +MicMethodStructureCheckerTest >> setUp [ + super setUp. + + fileSystem := FileSystem memory. + self generateFilesystemExample. + checker := MicMethodStructureChecker new. +] + +{ #category : 'tests' } +MicMethodStructureCheckerTest >> testMethodCorrect [ + checker checkProject: fileSystem / 'methodCorrect.md'. + self assert: checker isOkay. +] + +{ #category : 'tests' } +MicMethodStructureCheckerTest >> testMethodWithCommentCorrect [ + checker checkProject: fileSystem / 'methodWithComment.md'. + self assert: checker isOkay. +] + +{ #category : 'tests' } +MicMethodStructureCheckerTest >> testMethodWrongDetected [ + checker checkProject: fileSystem / 'methodWrong.md'. + self deny: checker isOkay. + self assert: checker results size equals: 1. + self assert: checker results first detail equals: 'goodWordFor: aString'. +] diff --git a/src/Microdown-Rules/MicMethodStructureResult.class.st b/src/Microdown-Rules/MicMethodStructureResult.class.st new file mode 100644 index 00000000..9ffbb614 --- /dev/null +++ b/src/Microdown-Rules/MicMethodStructureResult.class.st @@ -0,0 +1,31 @@ +Class { + #name : 'MicMethodStructureResult', + #superclass : 'MicAbstractResult', + #instVars : [ + 'detail' + ], + #category : 'Microdown-Rules-MethodStructure', + #package : 'Microdown-Rules', + #tag : 'MethodStructure' +} + +{ #category : 'accessing' } +MicMethodStructureResult >> detail [ + + ^ detail +] + +{ #category : 'accessing' } +MicMethodStructureResult >> detail: aString [ + + detail := aString +] + +{ #category : 'accessing' } +MicMethodStructureResult >> explanation [ + ^ 'Text: "' , micElement body + , '" in file' , fileReference fullName + , ' contains a mistake: method [' + , detail + , '] should have an empty line after the selector when is no comment.' +]