Skip to content

Testing for Platform Traits and Quirks instead of OS #293

Open
@NickGerleman

Description

@NickGerleman

Introduction

Different platforms running react-native have various implementation quirks inherent to the platform itself. This can lead to internals of react-native testing for Platform.OS to make branching decisions based off of implementation. This style of OS testing often causes issues for out-of-tree platforms, which need to fork private RN implementation to add themselves as a branch.

In many of these cases, the condition we're interested in can be expressed as a trait of the platform. E.g. in facebook/react-native#30374 we special-case Android, due to keyboard events not firing in certain cases on the platform. Instead of testing for Platform.OS === 'android', it is conceivable this limitation could instead be declared by the RN android platform itself. E.g. an API like Platform.quirks.keyboardEventsSometimesUnavailable. The same mechanism could be used to declare other interesting traits, like Platform.supportsMultipleViewports for whether usage of the Dimensions API is unsafe.

This proposal would introduce finer-grained Platform constants as a mechanism to allow shared code to adapt to Platform-specific behavior, while remaining friendly to out-of-tree platforms.

Details

Implementation could extend off of the existing PlatformConstants module, allowing native code for a platform to describe its abilities and limitations. Platforms should declare values for each of the traits, providing a fallback value for when using an older native module (both FB and Microsoft internally may use out-of-sync native and JS).

To avoid crowding the top-level Platform API, more fine-grained traits may be expressed behind a Quirks object, describing specific behavior

Discussion points

  • Decentralization of trait declaration: This approach makes RN core oblivious to what platforms have specific traits. This allows code in core to be somewhat generic to specific platforms, but also imposes risk with maintenance. E.g. it is harder to reason about who is relying on a quirk, and whether it it still applicable. This is somewhat eased by the limited number of popular out-of-tree platforms.

  • Global vs Local Traits: This approach creates a hub aware of the rest of the system. This has both advantages and disadvantages. Grouping traits related to all systems in a single place helps out-of-tree platforms to discover and accurately respond to them. Grouping them has the potential to create a bit of a dumping if widely adopted though, making it harder to maintain in relation to the code effected.

  • Public vs private: Some finer-grained platform information may be useful to library writers wanting to support multiple platforms. Quirks being tied to consumption in core makes the interface less likely to be stable however. A possible separation could be that quirks are private, but more fundamental traits are public.

  • Single platform traits vs OS testing: Platform quirks may sometimes belong to a single OS, in which case handling its behavior in core still feels like coupling it to a specific platform. I.e. it acts as a more abstracted Platform.OS check for an out-of-tree platform. It does architecturally let core be oblivious of the existence of the platform, but the actual maintenance in core would look very similar if untested.

  • Adoption: For the paradigm shift to achieve its goals, it would need to be followed across implementers of new library code. To do this it seems like we would need a critical mass of traits and trait testing. Staging this seems tricky.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🗣 DiscussionThis label identifies an ongoing discussion on a subject

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions