evaluate method Null safety

  1. @override
Future<Evaluation> evaluate(
  1. WidgetTester tester
)
override

Evaluate whether the current state of the tester conforms to the rule.

Implementation

@override
Future<Evaluation> evaluate(WidgetTester tester) async {
  // Compute elements to be evaluated.

  final List<Element> elements = finder.evaluate().toList();

  // Obtain rendered image.

  final RenderView renderView = tester.binding.renderView;
  final OffsetLayer layer = renderView.debugLayer! as OffsetLayer;
  late ui.Image image;
  final ByteData? byteData = await tester.binding.runAsync<ByteData?>(
    () async {
      // Needs to be the same pixel ratio otherwise our dimensions won't match
      // the last transform layer.
      final double ratio = 1 / tester.binding.window.devicePixelRatio;
      image = await layer.toImage(renderView.paintBounds, pixelRatio: ratio);
      return image.toByteData();
    },
  );

  // How to evaluate a single element.

  Evaluation evaluateElement(Element element) {
    final RenderBox renderObject = element.renderObject! as RenderBox;

    final Rect originalPaintBounds = renderObject.paintBounds;

    final Rect inflatedPaintBounds = originalPaintBounds.inflate(4.0);

    final Rect paintBounds = Rect.fromPoints(
      renderObject.localToGlobal(inflatedPaintBounds.topLeft),
      renderObject.localToGlobal(inflatedPaintBounds.bottomRight),
    );

    final Map<Color, int> colorHistogram = _colorsWithinRect(byteData!, paintBounds, image.width, image.height);

    if (colorHistogram.isEmpty) {
      return const Evaluation.pass();
    }

    final _ContrastReport report = _ContrastReport(colorHistogram);
    final double contrastRatio = report.contrastRatio();

    if (contrastRatio >= minimumRatio - tolerance) {
      return const Evaluation.pass();
    } else {
      return Evaluation.fail(
        '$element:\nExpected contrast ratio of at least '
        '$minimumRatio but found ${contrastRatio.toStringAsFixed(2)} \n'
        'The computed light color was: ${report.lightColor}, '
        'The computed dark color was: ${report.darkColor}\n'
        '$description',
      );
    }
  }

  // Collate all evaluations into a final evaluation, then return.

  Evaluation result = const Evaluation.pass();

  for (final Element element in elements) {
    result = result + evaluateElement(element);
  }

  return result;
}