reader/flutter: WIP flutter test setup.
Adds basic UI testing example. Pending test support will be uploaded in a new
patch to this CL once a flutter profile has been added.
Change-Id: I4b02021b4a66884671b5e8652746c6bd52f952e2
diff --git a/flutter/Makefile b/flutter/Makefile
index dd3dee9..628a177 100644
--- a/flutter/Makefile
+++ b/flutter/Makefile
@@ -18,7 +18,8 @@
.PHONY: analyze
analyze:
- dartanalyzer lib/main.dart
+ @echo "=== Analyzing Dart code ==="
+ dartanalyzer lib/main.dart --lints --fatal-hints --fatal-warnings
.PHONY: fmt
fmt: packages
@@ -27,3 +28,11 @@
doc:
dartdoc
@touch $@
+
+# TODO(jasoncampbell): this task needs to use the jiri profile for flutter.
+# NOTE: $FLUTTER_ENGINE is automatically picked up by flutter but is explcitly
+# set here for calrity until the correct path can be set using a jiri profile.
+.PHONY: test
+test: analyze
+ @echo "=== Running tests ==="
+ flutter test --engine-src-path $(FLUTTER_ENGINE)/src
diff --git a/flutter/README.md b/flutter/README.md
index 8effe7a..bef43c1 100644
--- a/flutter/README.md
+++ b/flutter/README.md
@@ -6,3 +6,14 @@
For help getting started with Flutter, view our online
[documentation](http://flutter.io/).
+
+
+# Development
+
+## Testing
+
+TODO(jasoncampbell): Add docs for running tests.
+
+### Mac
+
+https://github.com/flutter/engine/blob/master/CONTRIBUTING.md
diff --git a/flutter/lib/components/flutter_demo.dart b/flutter/lib/components/flutter_demo.dart
new file mode 100644
index 0000000..a06cd66
--- /dev/null
+++ b/flutter/lib/components/flutter_demo.dart
@@ -0,0 +1,33 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+
+class FlutterDemo extends StatefulComponent {
+ FlutterDemo({Key key}): super(key: key);
+
+ FlutterDemoState createState() => new FlutterDemoState();
+}
+
+class FlutterDemoState extends State<FlutterDemo> {
+ int counter = 0;
+
+ void incrementCounter() {
+ setState(() {
+ counter++;
+ });
+ }
+
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ toolBar: new ToolBar(center: new Text('Flutter Demo')),
+ body: new Center(
+ child: new Text(
+ 'Button tapped $counter time${ counter == 1 ? '' : 's' }.')),
+ floatingActionButton: new FloatingActionButton(
+ onPressed: incrementCounter,
+ tooltip: 'Increment',
+ child: new Icon(icon: Icons.add)));
+ }
+}
diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart
index 6625aa4..2a10be3 100644
--- a/flutter/lib/main.dart
+++ b/flutter/lib/main.dart
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
+import 'components/flutter_demo.dart';
void main() {
runApp(new MaterialApp(
@@ -11,29 +12,3 @@
'/': (RouteArguments args) => new FlutterDemo()
}));
}
-
-class FlutterDemo extends StatefulComponent {
- _FlutterDemoState createState() => new _FlutterDemoState();
-}
-
-class _FlutterDemoState extends State<FlutterDemo> {
- int _counter = 0;
-
- void _incrementCounter() {
- setState(() {
- _counter++;
- });
- }
-
- Widget build(BuildContext context) {
- return new Scaffold(
- toolBar: new ToolBar(center: new Text('Flutter Demo')),
- body: new Center(
- child: new Text(
- 'Button tapped $_counter time${ _counter == 1 ? '' : 's' }.')),
- floatingActionButton: new FloatingActionButton(
- onPressed: _incrementCounter,
- tooltip: 'Increment',
- child: new Icon(icon: 'content/add')));
- }
-}
diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml
index df057b1..89098ec 100644
--- a/flutter/pubspec.yaml
+++ b/flutter/pubspec.yaml
@@ -3,3 +3,7 @@
dependencies:
flutter:
path: ../../../../../flutter/packages/flutter
+dev_dependencies:
+ test: ^0.12.6
+ flutter_test:
+ path: ../../../../../flutter/packages/flutter_test
diff --git a/flutter/test/flutter_demo_test.dart b/flutter/test/flutter_demo_test.dart
new file mode 100644
index 0000000..d2c890b
--- /dev/null
+++ b/flutter/test/flutter_demo_test.dart
@@ -0,0 +1,57 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import "package:test/test.dart";
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:reader/components/flutter_demo.dart';
+
+void main() {
+ test("Example State test", () {
+ testWidgets((WidgetTester tester) {
+ GlobalKey key = new GlobalKey();
+ tester.pumpWidget(new MaterialApp(
+ title: 'Test App',
+ routes: <String, RouteBuilder>{
+ '/': (RouteArguments args) => new FlutterDemo(key: key)
+ }));
+
+ // Test State.
+ StatefulComponentElement element = tester.findElementByKey(key);
+ FlutterDemoState state = element.state;
+
+ expect(tester.findText("Flutter Demo"), isNotNull);
+ expect(tester.findText("Button tapped 0 times."), isNotNull);
+
+ state.incrementCounter();
+ // Advance the flutter framework to the next tick.
+ tester.pump();
+
+ expect(state.counter, equals(1));
+ expect(tester.findText("Button tapped 1 time."), isNotNull);
+
+ // NOTE: There is an animation segue for the floating action button in
+ // the material scaffold. The FAB is not tappable during this initial
+ // segue, the FAB will not be responsive to tapping until the animation
+ // ends at 400ms.
+ //
+ // SEE: https://git.io/vaLPb
+ tester.pump(new Duration(milliseconds: 400));
+
+ // Test Widget input and rendering.
+ StatefulComponentElement fab = tester.findElement((Element element) {
+ return element.widget is FloatingActionButton;
+ });
+
+ expect(fab, isNotNull);
+
+ tester.tap(fab);
+ tester.pump();
+
+ expect(state.counter, equals(2));
+ expect(tester.findText("Button tapped 2 times."), isNotNull);
+ });
+ });
+}