Skip to content

[checks]: Feedback #2510

@benthillerkus

Description

@benthillerkus

I'm currently porting a package with assorted tests from Kotlin to Dart using the matcher library.

The tests use a lot of composed matchers, which can be pretty tricky with matcher (the main capability missing is a Matcher that lets you construct a new Matcher based on the discriminated value).
The failure messages can also get very long and convoluted.

I recently learned about checks, the supposed successor for matcher and gave it a spin; here's my feedback:

  • The generated output on failure is more readable than with matcher, the indentations really help
  • Yet I think that everything related to passed checks should just be omitted, as it still can get very noisy (this is a light example, it gets really bad once you start overriding toString and use more Lists)
  Expected: a Car that:
    has an engine that:
      is identical to <Instance of 'InternalCombustionEngine'>
      is not null
    has doors that:
      is not a value that:
          contains, in order: [Instance of 'RearDoor', Instance of 'RearDoor']
  Actual: a Car that:
    has an engine that:
      is identical to <Instance of 'InternalCombustionEngine'>
      is not null
    has doors that:
    Actual: [Instance of 'Door',
    Instance of 'Door',
    Instance of 'Door',
    Instance of 'RearDoor',
    Instance of 'RearDoor']
    Which: is a value that:
        contains, in order: [Instance of 'RearDoor', Instance of 'RearDoor']
  • There should be an explicit way to compose matchers, so that you can give a name to them.
    • Like .which with a description field
    • Like .expect but I can just continue composing matchers instead of working on the actual value
    • Like check but accessible through chaining / flow
    • Like .nest but you don't extract a value and just return void
  Subject<List<Door>> get doors {
    return context.nest<List<Door>>(
      () => ["has doors"],
      (it) => Extracted.value(it.doors),
    );
  }

  void doorsAreOk() {
    doors.not( // not(containsInOrder) is very cryptic.
      // I should be able to clarify through descriptions that I'm testing
      // that there is at most one RearDoor
      (doors) => doors.containsInOrder(const [RearDoor(), RearDoor()]),
    );
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions