Small rewrites

I am certainly guilty of doing way too much work manually instead of writing short scripts to automate it. Of course if I am not familiar with the available tools it may be faster to do it by hand as I need to learn and try. But learning a bit about the system is the more valuable approach in the long run.

Changing the parent for a bunch of classes

I have a bunch of test classes in a package for which I would like to add a single parent class.

tests-before.png

So let’s first add the new parent class (for now as a subclass of Object).

1
2
3
4
Object subclass: #XMIBaseTest
instanceVariableNames: ''
classVariableNames: ''
package: 'XMI-Analyzer-Tests'

From the browser we can see that all the classes are in the XMI-Analyzer package and Tests tag, so let’s find a way to access that.

To access packages, you can ask the RPackage class for the RPackageOrganizer singleton and finally for the package itself. Punch it into playground and go.

1
RPackage organizer packageNamed: 'XMI-Analyzer'.
pkg.png

We can go deeper through the inspector and see what we have available there.

pkg-classes.png

If you also explore the available methods you can find a lot of convenience methods, so we can just type in this

1
((RPackage organizer packageNamed: 'XMI-Analyzer') classTagNamed: 'Tests') classes

Now all we have to do is select classes that inherit directly from TestCase and change their parent to XMIBaseTest. Finally we must change the parent class of the XMIBaseTest itself (since we’ve created it as a subclass of Object to avoid filtering it here).

Note that you don’t need intermediate variables, but they make for much easier debugging and inspecting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pkg := RPackage organizer packageNamed: 'XMI-Analyzer'.
tag := pkg classTagNamed: 'Tests'.
classes := tag classes.
classes select: [ :each |
each superclass = TestCase
] thenDo: [ :each |
each superclass: XMIBaseTest
XMIBaseTest addSubclass: each.
"Don't forget to all change the class sides!"
each class superclass: XMIBaseTest class.
XMIBaseTest class addSubclass: each class.
].
XMIBaseTest superclass: TestCase.
TestCase addSubclass: XMIBaseTest.
XMIBaseTest class superclass: TestCase class.
TestCase class addSubclass: XMIBaseTest class.

And we are done! The Hier. (Hierarchy) button shows you all the ancestors and descendants of the selected class.

tests-after.png

Of course in this particular case it may just be faster to do it by hand. But if I don’t know what tools I have available, how can I possibly decide which approach is better? A similar question arose when I wanted to change class prefixes, and doing it automatically is certainly the way to go there.