From 85c8e6c31500c4666952ed078d4927d4877cde09 Mon Sep 17 00:00:00 2001 From: CyrilFerlicot Date: Wed, 15 Apr 2020 16:45:57 +0200 Subject: [PATCH] Add tests about cleanings happening on class sides + fix bugs around this issue. Fixes #30 --- ...lConditionalSimplifierCleanerTest.class.st | 36 +++++++++++++++++++ ...licatedMethodFromTraitCleanerTest.class.st | 24 +++++++++++++ ...nelEnsureSuperIsCalledCleanerTest.class.st | 36 +++++++++++++++++++ ...ethodsOnlyCallingSuperCleanerTest.class.st | 12 +++++++ ...ssignationInInitializeCleanerTest.class.st | 13 +++++++ .../ChanelProtocolsCleanerTest.class.st | 18 ++++++++++ .../ChanelTestEqualityCleanerTest.class.st | 36 +++++++++++++++++++ .../ChanelUnreadTemporaryCleanerTest.class.st | 21 +++++++++++ src/Chanel/ChanelAbstractCleaner.class.st | 10 ++---- src/Chanel/ClassDescription.extension.st | 5 ++- 10 files changed, 202 insertions(+), 9 deletions(-) diff --git a/src/Chanel-Tests/ChanelConditionalSimplifierCleanerTest.class.st b/src/Chanel-Tests/ChanelConditionalSimplifierCleanerTest.class.st index 6e5febb..4c304b3 100644 --- a/src/Chanel-Tests/ChanelConditionalSimplifierCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelConditionalSimplifierCleanerTest.class.st @@ -52,3 +52,39 @@ ChanelConditionalSimplifierCleanerTest >> testIsNotNilIfTrue [ ChanelConditionalSimplifierCleanerTest >> testIsNotNilIfTrueIfFalse [ self assert: '10 isNotNil ifTrue: [ false ] ifFalse: [ true ]' isRewrittenAs: '10 ifNil: [ true ] ifNotNil: [ false ]' ] + +{ #category : #tests } +ChanelConditionalSimplifierCleanerTest >> testReplacementOnClassSide [ + class class + compile: + ('{1} + {2}' format: {self selector . '10 isNil ifFalse: [ false ]'}). + + self runCleaner. + + self + assert: (class class >> self selector) sourceCode + equals: + ('{1} + {2}' format: {self selector . '10 ifNotNil: [ false ]'}) +] + +{ #category : #tests } +ChanelConditionalSimplifierCleanerTest >> testWithNothingToReplace [ + | oldMethod | + class + compile: + ('{1} + {2}' format: {self selector . '10 ifNotNil: [ false ]'}). + + oldMethod := class >> self selector. + self runCleaner. + + self + assert: (class >> self selector) sourceCode + equals: + ('{1} + {2}' format: {self selector . '10 ifNotNil: [ false ]'}). + + self assert: class >> self selector identicalTo: oldMethod +] diff --git a/src/Chanel-Tests/ChanelDuplicatedMethodFromTraitCleanerTest.class.st b/src/Chanel-Tests/ChanelDuplicatedMethodFromTraitCleanerTest.class.st index d979908..3b329f3 100644 --- a/src/Chanel-Tests/ChanelDuplicatedMethodFromTraitCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelDuplicatedMethodFromTraitCleanerTest.class.st @@ -153,3 +153,27 @@ ChanelDuplicatedMethodFromTraitCleanerTest >> testRemoveDuplicatedMethodFromTrai self assert: (trait localSelectors includes: #one). self deny: (class localSelectors includes: #one) ] + +{ #category : #tests } +ChanelDuplicatedMethodFromTraitCleanerTest >> testRemoveDuplicatedMethodFromTraitOnClassSide [ + | trait | + class := self createClassNamed: #ChanelDuplicatedMethodFromTraitFake. + trait := self createTraitNamed: #TChanelDuplicatedMethodFromTraitFake. + + class addToComposition: trait. + + trait class + compile: + 'one + ^ #one'. + + class class + compile: + 'one + ^ #one'. + + self runCleaner. + + self assert: (trait class localSelectors includes: #one). + self deny: (class class localSelectors includes: #one) +] diff --git a/src/Chanel-Tests/ChanelEnsureSuperIsCalledCleanerTest.class.st b/src/Chanel-Tests/ChanelEnsureSuperIsCalledCleanerTest.class.st index 767d7e7..e797bf8 100644 --- a/src/Chanel-Tests/ChanelEnsureSuperIsCalledCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelEnsureSuperIsCalledCleanerTest.class.st @@ -158,6 +158,24 @@ ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperSetUpIfEmptyMethod [ self assert: oldMethod identicalTo: class >> #setUp ] +{ #category : #'tests - setup' } +ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperSetUpOnClassSide [ + class class compile: 'setUp + self assert: true'. + + oldMethod := class class>> #setUp. + + self runCleaner. + + self + assert: (class class>> #setUp) sourceCode + equals: 'setUp + self assert: true'. + + "In case there is nothing to change, we should *not* recompile the method, thus it should be identical." + self assert: oldMethod identicalTo: class class>> #setUp +] + { #category : #'tests - setup' } ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperSetUpWhenAlreadyThere [ class := self createTestCaseNamed: #ChanelTestClass. @@ -222,6 +240,24 @@ ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperTearDownIfEmptyMethod self assert: oldMethod identicalTo: class >> #tearDown ] +{ #category : #'tests - teardown' } +ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperTearDownOnClassSide [ + class class compile: 'tearDown + self assert: true'. + + oldMethod := class class>> #tearDown. + + self runCleaner. + + self + assert: (class class>> #tearDown) sourceCode + equals: 'tearDown + self assert: true'. + + "In case there is nothing to change, we should *not* recompile the method, thus it should be identical." + self assert: oldMethod identicalTo: class class>> #tearDown +] + { #category : #'tests - teardown' } ChanelEnsureSuperIsCalledCleanerTest >> testDoesNotAddSuperTearDownWhenAlreadyThere [ class := self createTestCaseNamed: #ChanelTestClass. diff --git a/src/Chanel-Tests/ChanelMethodsOnlyCallingSuperCleanerTest.class.st b/src/Chanel-Tests/ChanelMethodsOnlyCallingSuperCleanerTest.class.st index 5470cc6..9039a27 100644 --- a/src/Chanel-Tests/ChanelMethodsOnlyCallingSuperCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelMethodsOnlyCallingSuperCleanerTest.class.st @@ -140,3 +140,15 @@ ChanelMethodsOnlyCallingSuperCleanerTest >> testRemoveMethodOnlyCollingSuperEven self deny: (class localSelectors includes: #initialize) ] + +{ #category : #tests } +ChanelMethodsOnlyCallingSuperCleanerTest >> testRemoveMethodOnlyCollingSuperOnClassSide [ + class class + compile: + 'initialize + super initialize'. + + self runCleaner. + + self deny: (class class localSelectors includes: #initialize) +] diff --git a/src/Chanel-Tests/ChanelNilAssignationInInitializeCleanerTest.class.st b/src/Chanel-Tests/ChanelNilAssignationInInitializeCleanerTest.class.st index 10e70b5..c76630e 100644 --- a/src/Chanel-Tests/ChanelNilAssignationInInitializeCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelNilAssignationInInitializeCleanerTest.class.st @@ -69,6 +69,19 @@ ChanelNilAssignationInInitializeCleanerTest >> testRemoveNilAssigment [ super initialize' ] +{ #category : #tests } +ChanelNilAssignationInInitializeCleanerTest >> testRemoveNilAssigmentOnClassSide [ + class class + compile: + 'initialize + test := nil'. + + self runCleaner. + + self assert: (class class >> #initialize) sourceCode equals: 'initialize + ' +] + { #category : #tests } ChanelNilAssignationInInitializeCleanerTest >> testRemoveNilAssigments [ class diff --git a/src/Chanel-Tests/ChanelProtocolsCleanerTest.class.st b/src/Chanel-Tests/ChanelProtocolsCleanerTest.class.st index 65c945c..aa7690a 100644 --- a/src/Chanel-Tests/ChanelProtocolsCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelProtocolsCleanerTest.class.st @@ -49,6 +49,15 @@ ChanelProtocolsCleanerTest >> testMethodInSpecificProtocolNotUpdateIfNotInTheLis self assert: (class >> #initialize2) protocol equals: 'random' ] +{ #category : #tests } +ChanelProtocolsCleanerTest >> testMethodInSpecificProtocolOnClassSide [ + class class compile: 'initialize' classified: 'random'. + + self runCleaner. + + self assert: (class class>> #initialize) protocol equals: 'initialization' +] + { #category : #tests } ChanelProtocolsCleanerTest >> testTestMethodInSpecificProtocol [ class := self createTestCaseNamed: #ChanelProtocolsFake. @@ -135,3 +144,12 @@ ChanelProtocolsCleanerTest >> testUpdateCloseProtocol [ self assert: (class >> #method) protocol equals: 'instance creation' ] + +{ #category : #tests } +ChanelProtocolsCleanerTest >> testUpdateCloseProtocolOnClassSide [ + class class compile: 'method' classified: 'instance-creation'. + + self runCleaner. + + self assert: (class class>> #method) protocol equals: 'instance creation' +] diff --git a/src/Chanel-Tests/ChanelTestEqualityCleanerTest.class.st b/src/Chanel-Tests/ChanelTestEqualityCleanerTest.class.st index 76cb727..82d851e 100644 --- a/src/Chanel-Tests/ChanelTestEqualityCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelTestEqualityCleanerTest.class.st @@ -73,6 +73,22 @@ ChanelTestEqualityCleanerTest >> testDenyIdenticalTo [ self assert: 'self deny: 3 == 2' isRewrittenAs: 'self deny: 3 identicalTo: 2' ] +{ #category : #tests } +ChanelTestEqualityCleanerTest >> testReplacementOnClassSide [ + class class + compile: + ('{1} + {2}' format: {self selector . 'self assert: 3 = 2'}). + + self runCleaner. + + self + assert: (class class >> self selector) sourceCode + equals: + ('{1} + {2}' format: {self selector . 'self assert: 3 equals: 2'}) +] + { #category : #tests } ChanelTestEqualityCleanerTest >> testShouldNotReplaceIfNotATestCase [ "We only replace the assertion of TestCase because other objects are much poorer in term of assertions." @@ -92,3 +108,23 @@ ChanelTestEqualityCleanerTest >> testShouldNotReplaceIfNotATestCase [ ('{1} {2}' format: {self selector . 'self assert: 3 = 2'}) ] + +{ #category : #tests } +ChanelTestEqualityCleanerTest >> testWithNothingToReplace [ + | oldMethod | + class + compile: + ('{1} + {2}' format: {self selector . 'self assert: 3 equals: 2'}). + + oldMethod := class >> self selector. + self runCleaner. + + self + assert: (class >> self selector) sourceCode + equals: + ('{1} + {2}' format: {self selector . 'self assert: 3 equals: 2'}). + + self assert: class >> self selector identicalTo: oldMethod +] diff --git a/src/Chanel-Tests/ChanelUnreadTemporaryCleanerTest.class.st b/src/Chanel-Tests/ChanelUnreadTemporaryCleanerTest.class.st index aaed53a..be6a3c7 100644 --- a/src/Chanel-Tests/ChanelUnreadTemporaryCleanerTest.class.st +++ b/src/Chanel-Tests/ChanelUnreadTemporaryCleanerTest.class.st @@ -87,6 +87,27 @@ ChanelUnreadTemporaryCleanerTest >> testRemoveTemporaries [ ^#one' ] +{ #category : #tests } +ChanelUnreadTemporaryCleanerTest >> testRemoveTemporariesOnClassSide [ + class class + compile: + 'testMethod + | test test2 | + test := self toto. + test2 := self toto2. + ^#one'. + + self runCleaner. + + self + assert: (class class>> #testMethod) sourceCode + equals: + 'testMethod + self toto. + self toto2. + ^#one' +] + { #category : #tests } ChanelUnreadTemporaryCleanerTest >> testRemoveTemporary [ class diff --git a/src/Chanel/ChanelAbstractCleaner.class.st b/src/Chanel/ChanelAbstractCleaner.class.st index 0bed850..4a88451 100644 --- a/src/Chanel/ChanelAbstractCleaner.class.st +++ b/src/Chanel/ChanelAbstractCleaner.class.st @@ -70,12 +70,6 @@ ChanelAbstractCleaner >> configuration: anObject [ { #category : #rewriting } ChanelAbstractCleaner >> rewriteMethodsOf: classes with: rewriter [ - classes - do: [ :class | - class localMethods - do: [ :method | - | ast | - ast := method ast. - (rewriter executeTree: ast) ifTrue: [ class compile: ast formattedCode ] ] ] - displayingProgress: [ :c | c printString ] + (classes flatCollect: [ :class | class localMethods , class class localMethods ]) + do: [ :method | (rewriter executeTree: method ast) ifTrue: [ method ast install ] ] ] diff --git a/src/Chanel/ClassDescription.extension.st b/src/Chanel/ClassDescription.extension.st index 8ab9605..91a210e 100644 --- a/src/Chanel/ClassDescription.extension.st +++ b/src/Chanel/ClassDescription.extension.st @@ -3,5 +3,8 @@ Extension { #name : #ClassDescription } { #category : #'*Chanel' } ClassDescription >> removeDuplicatedMethodsFromTrait [ self localMethods - do: [ :method | self traitComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeFromSystem ] ] ] + do: [ :method | self traitComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeFromSystem ] ] ]. + + self class localMethods + do: [ :method | self traitComposition classComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeFromSystem ] ] ]. ]