widget_tester.dart 3.72 KB
Newer Older
1
import 'dart:sky' as sky;
2

3
import 'package:sky/animation.dart';
4 5 6
import 'package:sky/rendering.dart';
import 'package:sky/widgets.dart';

7 8
import '../engine/mock_events.dart';

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
typedef Widget WidgetBuilder();

class TestApp extends App {
  TestApp();

  WidgetBuilder _builder;
  void set builder (WidgetBuilder value) {
    setState(() {
      _builder = value;
    });
  }

  Widget build() {
    if (_builder != null)
      return _builder();
    return new Container();
  }
}

class WidgetTester {
  WidgetTester() {
    _app = new TestApp();
31
    runApp(_app);
32 33 34 35
  }

  TestApp _app;

36 37 38 39 40 41 42 43 44 45 46 47
  List<Layer> _layers(Layer layer) {
    List<Layer> result = [layer];
    if (layer is ContainerLayer) {
      ContainerLayer root = layer;
      Layer child = root.firstChild;
      while(child != null) {
        result.addAll(_layers(child));
        child = child.nextSibling;
      }
    }
    return result;
  }
48
  List<Layer> get layers => _layers(SkyBinding.instance.renderView.layer);
49

50 51 52 53 54 55 56 57 58
  void walkWidgets(WidgetTreeWalker walker) {
    void walk(Widget widget) {
      walker(widget);
      widget.walkChildren(walk);
    }

    _app.walkChildren(walk);
  }

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
  Widget findWidget(bool predicate(Widget widget)) {
    try {
      walkWidgets((Widget widget) {
        if (predicate(widget))
          throw widget;
      });
    } catch (e) {
      if (e is Widget)
        return e;
      rethrow;
    }
    return null;
  }

  Text findText(String text) {
    return findWidget((Widget widget) {
      return widget is Text && widget.data == text;
    });
  }

79
  Point _getWidgetPoint(Widget widget, Function sizeToPoint) {
80 81 82
    assert(widget != null);
    RenderBox box = widget.renderObject as RenderBox;
    assert(box != null);
83 84 85 86 87
    return box.localToGlobal(sizeToPoint(box.size));
  }

  Point getCenter(Widget widget) {
    return _getWidgetPoint(widget, (Size size) => size.center(Point.origin));
88 89
  }

90
  Point getTopLeft(Widget widget) {
91
    return _getWidgetPoint(widget, (_) => Point.origin);
92 93 94
  }

  Point getTopRight(Widget widget) {
95 96 97 98 99 100 101 102 103
    return _getWidgetPoint(widget, (Size size) => size.topRight(Point.origin));
  }

  Point getBottomLeft(Widget widget) {
    return _getWidgetPoint(widget, (Size size) => size.bottomLeft(Point.origin));
  }

  Point getBottomRight(Widget widget) {
    return _getWidgetPoint(widget, (Size size) => size.bottomRight(Point.origin));
104 105
  }

106 107 108 109 110 111
  HitTestResult _hitTest(Point location) => SkyBinding.instance.hitTest(location);

  EventDisposition _dispatchEvent(sky.Event event, HitTestResult result) {
    return SkyBinding.instance.dispatchEvent(event, result);
  }

112
  void tap(Widget widget, { int pointer: 1 }) {
113 114 115 116
    tapAt(getCenter(widget), pointer: pointer);
  }

  void tapAt(Point location, { int pointer: 1 }) {
117
    HitTestResult result = _hitTest(location);
118 119 120
    TestPointer p = new TestPointer(pointer);
    _dispatchEvent(p.down(location), result);
    _dispatchEvent(p.up(), result);
121 122
  }

123
  void scroll(Widget widget, Offset offset, { int pointer: 1 }) {
124 125
    Point startLocation = getCenter(widget);
    Point endLocation = startLocation + offset;
126
    TestPointer p = new TestPointer(pointer);
127 128 129
    // Events for the entire press-drag-release gesture are dispatched
    // to the widgets "hit" by the pointer down event.
    HitTestResult result = _hitTest(startLocation);
130 131 132
    _dispatchEvent(p.down(startLocation), result);
    _dispatchEvent(p.move(endLocation), result);
    _dispatchEvent(p.up(), result);
133 134
  }

135 136
  void dispatchEvent(sky.Event event, Point location) {
    _dispatchEvent(event, _hitTest(location));
137 138
  }

139
  void pumpFrame(WidgetBuilder builder, [double frameTimeMs = 0.0]) {
140
    _app.builder = builder;
141
    scheduler.beginFrame(frameTimeMs);
142 143
  }

Hixie's avatar
Hixie committed
144 145 146 147
  void pumpFrameWithoutChange([double frameTimeMs = 0.0]) {
    scheduler.beginFrame(frameTimeMs);
  }

148
}