WTF!
I have to start this blog with a rant. I am currently working at Hibernate's reference implementation of JSR 303. I started out using Junit 4 for unit tests. However, in order to leverage from some other framework I had to switch to TestNG. I thought it should be quite easy to change from one framework to the other - basically just switch the import statements. Turns out is was more difficult than that. After a global find and replace in the test files replacing the package statement I ended up with multiple compilation errors. The problem was that in Junit the assertEquals method has the signature assertEquals(String message, Object expected, Object actual) whereas TestNG's assertEquals is assertEquals(Object expected, Object actual, String message). WTF! Given that TestNG came later - which reason did they have to swap the arguments? Just to make it harder to migrate from one to the other? This applies of course for all assert statements. I am just using assertEquals as an exmaple.
Anyways, I started manually changing the calls, but that was just too tedious. It was time to get sed out again, but soon I realized that sed was not going to cut it this time, because there is no way do non greedy regular expressions . The expression also had to take care of single and multi line statements. An example for a multi line statement would be:
Time to get good old perl out again. Here is what I came up with (the whole expression is one line!):
Well, it did not solve all my problems. In some cases the formatting was a little off, but that could be easily fixed with my IDE. Some comments about the expression:
enjoy!
Anyways, I started manually changing the calls, but that was just too tedious. It was time to get sed out again, but soon I realized that sed was not going to cut it this time, because there is no way do non greedy regular expressions . The expression also had to take care of single and multi line statements. An example for a multi line statement would be:
assertEquals(
"Wrong propertyPath",
propertyPath,
violation.getPropertyPath()
);
Time to get good old perl out again. Here is what I came up with (the whole expression is one line!):
perl -pi -0777 -e 's/(assertEquals.|\n*?)(".*?"),[ ,\n,\t]*(\w*?,)([ ,\n,\t]*.*?)([ ,\n,\t]*)\);/$1$3$4,$5$2\ );/g' MyClass.java
Well, it did not solve all my problems. In some cases the formatting was a little off, but that could be easily fixed with my IDE. Some comments about the expression:
- the -i option allows editing of the file in-line. A very nice feature of perl and something I miss a lot in sed
- -0777 specified the line break character in octa-decimal. Assuming 777 does not appear in your file this is an easy way to match across lines
- there are a lot of \n matches. Even when matching across the whole file .* won't match the new line character. It has to be explicitly specified
- using regular expression buffers I am able to capture the groups of the statement an put the expression together in a different order using $x notation for referring to the matching buffers
- and I almost forgot the ? after the operators ?, + and * turns on non greedy machting
enjoy!
Old comments
Thanks!