Showing posts with label android studio. Show all posts
Showing posts with label android studio. Show all posts

Monday, April 14, 2025

Making Dart test helper methods show up in the structure view of Android Studio

Why such an awkward title for this post? It is the kind of search I was doing the other day when I found no hits. I'm writing this in hopes that I can save someone else the trouble I faced when the solution is, in fact, quite simple.

My Dart project contains many unit tests, but many of them use helper methods rather than calling test directly. Unfortunately, I was deep into this approach when I realized that these tests were not showing up in Android Studio's Structure view, which is otherwise a good way to navigate files.

Here is an example to illustrate the problem. Notice that the call to test is nested within the helper function, testExample.

 import 'package:test/test.dart';  
   
 class Example {  
  bool isEven(int value) => value % 2 == 0;  
 }  
   
 void main() {  
  final example = Example();  
   
  void testExample(  
   String description, {  
   required int value,  
   required Function(bool) verify,  
  }) {  
   final result = example.isEven(value);  
   test(description, verify(result));  
  }  
   
  group('Example.isEven', () {  
   testExample(  
    '2 is even',  
    value: 2,  
    verify: (result) => expect(result, isTrue),  
   );  
  });  
 }  
   

When this is opened in Android Studio, the Structure view looks like this:

Notice how the group is empty. 

The other day, I tried different searches to find an answer. It seemed to me that there had to be some way that unit testing libraries communicated their structure to JetBrains IDEs; it could not be the case that the JetBrains engineers were doing simple string matching in source files. Yet, I had no luck. In my confusion, I even turned to ChatGPT, which confidently told me that the only way to do it would be to refactor all of my tests into (yet more) higher-order functions so that I was calling the standard test function at the top level. I asked it for a reference, hoping to find the documentation I had unsuccessfully been searching for, and it unhelpfully pointed me toward two web sites that don't address this issue. Still, I put a potential refactoring into my project plan, although with over a hundred tests and counting, and with a rather eloquent current solution, this would have been both tedious and disheartening.

One of the reasons I started writing helper methods in this particular style—that is, by sending named functions as parameters—was because this is how the bloc_test package handles testing. A day or two after having tried to search for a solution to my problem, I was in a test file and noticed that all my blocTest calls did show up in the Structure view. How was that possible? Thanks to the MIT license of bloc_test, I checked the implementation and found the @isTest annotation, which comes from the meta library. Quickly reviewing its documentation, this was clearly exactly what I needed. I included this little annotation to my project.

 import 'package:meta/meta.dart';  
 import 'package:test/test.dart';  
   
 class Example {  
  bool isEven(int value) => value % 2 == 0;  
 }  
   
 void main() {  
  final example = Example();  
   
  @isTest  
  void testExample(  
   String description, {  
   required int value,  
   required Function(bool) verify,  
  }) {  
   final result = example.isEven(value);  
   test(description, verify(result));  
  }  
   
  group('Example.isEven', () {  
   testExample(  
    '2 is even',  
    value: 2,  
    verify: (result) => expect(result, isTrue),  
   );  
  });  
 }  
   

The result was that my Structure view looked exactly how I wanted it.

There you go: the solution in Dart is to annotate the helper method with @isTest. The documentation of that annotation make it clear that it solves my problem, but I must not have hit the right keywords with my original search. I hope that this post helps anyone else who is caught by this issue.

Wednesday, June 27, 2018

Noise comments in Android Studio with Flutter

Flutter sounds neat, doesn't it? I decided to take a look yesterday, and it distracted me quite a bit from my course revision work. With my course revision and reflective blog post done, I decided to get into the Flutter codelab and see what I could do.

Step one is basically to copy and paste this code into Android Studio:
OK, copy, paste, and I get this abomination:
What the...?!

Those end-of-line comments are clearly not in the code. I do not want them. They are concretely, undeniably, irrevocably bad.

My first thought was, "I need to get Android Studio not to add those comments when I paste in code." I tried Googling for variations on this, but to no avail. Maybe I was calling it the wrong thing? I searched the preferences in Android Studio but couldn't find a good match either. Not wanting to waste more time, I decided I'd just go in and manually eliminate them for now.

I cannot.

They are not actually content in the editor! Those characters are not in the file. The view of the file is showing me data that do not exist. OK, stop and think about that, think about that for a long time if you have to. If you added this feature to Android Studio in particular, think about this for a long, long, long time. This is the worst idea.

But it's not the first time I've seen it. A few versions ago, IntelliJ IDEA added a "feature" in which it would show formal parameter names at the site of the actual parameter. It looks like this:

The text "bar:" is what they call a "parameter hint." It is not selectable or erasable. It's not really there in the data—once again, the view of the file is showing something that's not in the file. When I first saw this, I was aghast, and I could feel it in my bones that bad things were coming. I make all my students turn this abomination of a feature off.

Now, we see that my intuition was right. It's getting worse. Now, the view of my Dart source code file isn't just showing data that's not there: it's rendering that data as if it were. It's not using a different font or size, as in the parameter hints.

The good news is that this helped me consider where I might turn this off, and sharing this knowledge is the primary reason for this post. If you understand a modicum of what it means to write clean and maintainable code, then go to the File Menu, open the Settings dialog, and go to the Appearance section (with the Flutter Plug-in enabled, of course).


There it is. Untick that box and accept the changes, and your source code editor will be purified.

You're welcome.