Monday, July 29, 2019

Kotlin Gradle buildscripts can't easily apply arbitrary plugins from other repositories

Previously I published a Gradle plugin to Maven Central. It had been working fine in Groovy buildscripts, but using it from a Kotlin buildscript was tricky. It registers an extension, so using the apply function to apply it didn't work; the extension needed the plugin already applied to even compile. The plugins block didn't immediately work because it looked for a plugin in the Gradle Plugins Portal, or through some kind of placeholder/marker artifact of a different name in other repositories.

The way to deal with this is to add a pluginManagement block to settings.gradle to set which artifact coordinate Gradle will use to look for the plugin of a given ID. repositories should specify the repository containing the plugin plus gradlePluginPortal() for any other plugins. resolutionStrategyeachPlugin is run for every requested plugin and can intercept and change the artifact coordinate. The requested plugin information can be checked to see if it's the tricky one; if so the useModule function should be called to set the artifact coordinate.

Sunday, July 28, 2019

The phpBB 2 to 3 converter might blank a few posts with non-ASCII characters

Today I received a report from a user on a forum I host that a couple old posts appeared blank. These were made before I migrated the forum from phpBB 2 to phpBB 3, a transition that was made tricky by a problem with non-ASCII character encoding. Examining the phpbb_posts table showed that the affected posts' post_text had been replaced with <?xml version="1.0"?> plus a linefeed. Consulting a backup of the phpBB 2 database, I saw that both posts originally contained non-ASCII characters that get encoded into multiple bytes by UTF-8.

Wednesday, July 24, 2019

Detecting whether an Android ID is defined

I'm writing some test suites for student Android code. I'm trying to minimize the tests' compile-time dependencies on student code so that students can work on one part at a time without having compilable versions of everything. Some assignments ask them to set up layouts, in which view IDs create constants on R.id. The integer value of an ID constant can be looked up by name using the getIdentifier method of Resources. It can be called with all information in the first parameter...

resources.getIdentifier("com.example.app:id/theName", null, null)

...or with the resource type and package in separate parameters...

resources.getIdentifier("theName", "id", "com.example.app")

The return value is zero if the ID doesn't exist. That can be checked and used to throw a nice error message at runtime when that test is run rather than a compile error.

Monday, July 22, 2019

PowerMock stubbing can help deal with subclasses of private classes

Today I needed to mock an inner class that was a subclass of a different, private inner class. Creating a mock or spy failed in the class initializer because the generated mock class didn't have access to the private superclass. However, using PowerMockito.stub on a PowerMockito.method representation of the method to replace worked.

Ionic needs a full restart for some changes

The Ionic web server has a slick feature that detects changes to the source files, recompiles the appropriate components, and delivers the changes to the browser automatically. However, this does not appear to work for all changes. In particular, I've seen adding new TypeScript files cause strange behavior that was resolved by stopping and restarting ionic serve.

Saturday, July 20, 2019

Working with support library AlertDialog in Robolectric

Robolectric provides a ShadowAlertDialog class with a getLatestAlertDialog function to get the last Android AlertDialog. However, in my project that uses a support library (AndroidX), that function returned null. To get the last shown dialog, I had to use ShadowDialog.getLatestDialog and cast that Dialog to the AlertDialog type from the support library.

Wednesday, July 17, 2019

NullPointerExceptions from PowerMock can indicate a non-mocked static class

Today I was writing some PowerMock-based test code and encountered a NullPointerException in the middle of normal-looking and previously-working mock configuration for a static method. Another test in the same test suite was failing with an UnfinishedStubbingException in something that also looked reasonable. It turned out that I had forgotten to PowerMockito.mockStatic the class in that test.