Skip to content

Code quality improvements for text input deltas #107127

@matthew-carroll

Description

@matthew-carroll

I'm creating an IME simulator in the flutter_test_robots package so that developers can simulate the kind of input that's used in document editing.

I found some code quality issues that made it difficult for me to get the simulator working. I recommend improving these details.

Please see:

Issues:

  • Provide a toJSON() for text editing deltas: I'm sending deltas through the platform channel so that I get maximum correctness in the IME simulation. TextEditingDelta has a fromJSON() method, but no toJSON() method. Moreover, the fromJSON() method is very complicated. I found it impossible to read. So I made a guess about how I'm supposed to map values in the JSON blobs that I'm sending.
  • Clean up TextEditingDelta.fromJSON(): As mentioned above, I couldn't visually trace what was happening in the fromJSON() method. It's doing a lot more than just de-serializing values and it's unclear what's happening. I recommend taking a look at some of Robert Martin's "clean code" guidelines to help improve the readability of that method.
  • Multiple areas fail silently: I spent a while carefully tracing my fake JSON through the channel because any time something goes wrong in that channel, it fails silently. For example, I was passing some bad text bounds. This caused a "replace" call in fromJSON() to blow up, but I received no indication of this.
  • Conflicting terms for composing region: In the JSON parsing there are references to the composing start and end values, and those are used interchangeably with composingBase and composingExtent. However, those are not the same concepts. As seen in TextSelection, start and end mean "upstream to downstream", but base and extent mean "a range in a user specified direction".
  • Use constants for message names and parameters: All the message names are coded with inline strings. This might be appropriate for completely private details, but these names aren't private. These names are explicitly listed in the public docs for the channel. Thus, they should be public constants.
  • Offer message (de)serializers: I mentioned individual delta serialization, but also in general there's no need to make other developers copy and paste the structure of messages. For example, the arguments for a delta message is a List that contains an int, followed by a Map that contains a "deltas" key, which then contains the List of deltas. Why not wrap that with a public object that others can use to access the data without worrying about the JSON structure?
  • Make it clear that the text input connection needs a special debug reset in tests: I was hitting test failures with my simulator that I couldn't pin down. By luck, I found this line in the Flutter repo: TextInputConnection.debugResetId();. I'm still not sure why I need to call it. My widgets explicitly close() the input connection in their dispose() methods. Nonetheless, if I try to run more than 1 test at a time, the input connection holds on to the wrong connection ID and I can't connect the text fields in other tests.

You can see the simulator here:
https://github.com/Flutter-Bounty-Hunters/flutter_test_robots/blob/main/lib/src/input_method_engine.dart

You can see how I'm testing the simulator here:
https://github.com/Flutter-Bounty-Hunters/flutter_test_robots/blob/main/test/flutter_test_robots_ime_test.dart

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: text inputEntering text in a text field or keyboard related problemsc: proposalA detailed proposal for a change to Flutterc: tech-debtTechnical debt, code quality, testing, etc.f: material designflutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions