Unnecessary new (#20138)
* enable lint unnecessary_new * fix tests * fix tests * fix tests
This commit is contained in:
parent
d7a0dcaa4a
commit
d927c93310
@ -152,7 +152,7 @@ linter:
|
||||
- unnecessary_const
|
||||
- unnecessary_getters_setters
|
||||
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
|
||||
# - unnecessary_new # not yet tested
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
- unnecessary_null_in_if_null_operators
|
||||
- unnecessary_overrides
|
||||
|
@ -42,7 +42,7 @@ The following message was thrown running a test:
|
||||
Who lives, who dies, who tells your story\?
|
||||
|
||||
When the exception was thrown, this was the stack:
|
||||
#[0-9]+ +main.<anonymous closure> \(.+[/\\]dev[/\\]automated_tests[/\\]flutter_test[/\\]exception_handling_test\.dart:16:9\)
|
||||
#[0-9]+ +main.<anonymous closure> \(.+[/\\]dev[/\\]automated_tests[/\\]flutter_test[/\\]exception_handling_test\.dart:15:105\)
|
||||
#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\)
|
||||
#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\)
|
||||
#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\)
|
||||
|
@ -10,9 +10,9 @@ void main() {
|
||||
throw 'Who lives, who dies, who tells your story?';
|
||||
});
|
||||
testWidgets('Exception handling in test harness - FlutterError', (WidgetTester tester) async {
|
||||
throw new FlutterError('Who lives, who dies, who tells your story?');
|
||||
throw FlutterError('Who lives, who dies, who tells your story?');
|
||||
});
|
||||
testWidgets('Exception handling in test harness - uncaught Future error', (WidgetTester tester) async {
|
||||
new Future<Null>.error('Who lives, who dies, who tells your story?');
|
||||
Future<Null>.error('Who lives, who dies, who tells your story?');
|
||||
});
|
||||
}
|
||||
|
@ -19,9 +19,9 @@ Future<Null> guardedHelper(WidgetTester tester) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
new TestTestBinding();
|
||||
TestTestBinding();
|
||||
testWidgets('TestAsyncUtils - custom guarded sections', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Container());
|
||||
await tester.pumpWidget(Container());
|
||||
expect(find.byElementType(Container), isNotNull);
|
||||
guardedHelper(tester);
|
||||
expect(find.byElementType(Container), isNull);
|
||||
|
@ -16,7 +16,7 @@ Future<Null> helperFunction(WidgetTester tester) async {
|
||||
}
|
||||
|
||||
void main() {
|
||||
new TestTestBinding();
|
||||
TestTestBinding();
|
||||
testWidgets('TestAsyncUtils - handling unguarded async helper functions', (WidgetTester tester) async {
|
||||
helperFunction(tester);
|
||||
helperFunction(tester);
|
||||
|
@ -8,7 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Does flutter_test catch leaking tickers?', (WidgetTester tester) async {
|
||||
new Ticker((Duration duration) { })..start();
|
||||
Ticker((Duration duration) { })..start();
|
||||
|
||||
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
void main() {
|
||||
testWidgets('flutter_test timeout logic - addTime - negative', (WidgetTester tester) async {
|
||||
await tester.runAsync(() async {
|
||||
await new Future<void>.delayed(const Duration(milliseconds: 3500));
|
||||
await Future<void>.delayed(const Duration(milliseconds: 3500));
|
||||
}, additionalTime: const Duration(milliseconds: 200));
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
void main() {
|
||||
testWidgets('flutter_test timeout logic - addTime - positive', (WidgetTester tester) async {
|
||||
await tester.runAsync(() async {
|
||||
await new Future<void>.delayed(const Duration(milliseconds: 2500)); // must be longer than default timeout.
|
||||
await Future<void>.delayed(const Duration(milliseconds: 2500)); // must be longer than default timeout.
|
||||
}, additionalTime: const Duration(milliseconds: 2000)); // default timeout is 2s, so this makes it 4s.
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter/scheduler.dart' show timeDilation;
|
||||
|
||||
void main() {
|
||||
runApp(
|
||||
new ComplexLayoutApp()
|
||||
ComplexLayoutApp()
|
||||
);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ enum ScrollMode { complex, tile }
|
||||
|
||||
class ComplexLayoutApp extends StatefulWidget {
|
||||
@override
|
||||
ComplexLayoutAppState createState() => new ComplexLayoutAppState();
|
||||
ComplexLayoutAppState createState() => ComplexLayoutAppState();
|
||||
|
||||
static ComplexLayoutAppState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<ComplexLayoutAppState>());
|
||||
}
|
||||
@ -23,8 +23,8 @@ class ComplexLayoutApp extends StatefulWidget {
|
||||
class ComplexLayoutAppState extends State<ComplexLayoutApp> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
theme: lightTheme ? new ThemeData.light() : new ThemeData.dark(),
|
||||
return MaterialApp(
|
||||
theme: lightTheme ? ThemeData.light() : ThemeData.dark(),
|
||||
title: 'Advanced Layout',
|
||||
home: scrollMode == ScrollMode.complex ? const ComplexLayout() : const TileScrollLayout());
|
||||
}
|
||||
@ -57,18 +57,18 @@ class TileScrollLayout extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(title: const Text('Tile Scrolling Layout')),
|
||||
body: new ListView.builder(
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Tile Scrolling Layout')),
|
||||
body: ListView.builder(
|
||||
key: const Key('tiles-scroll'),
|
||||
itemCount: 200,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: new Material(
|
||||
child: Material(
|
||||
elevation: (index % 5 + 1).toDouble(),
|
||||
color: Colors.white,
|
||||
child: new IconBar(),
|
||||
child: IconBar(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -82,7 +82,7 @@ class ComplexLayout extends StatefulWidget {
|
||||
const ComplexLayout({ Key key }) : super(key: key);
|
||||
|
||||
@override
|
||||
ComplexLayoutState createState() => new ComplexLayoutState();
|
||||
ComplexLayoutState createState() => ComplexLayoutState();
|
||||
|
||||
static ComplexLayoutState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<ComplexLayoutState>());
|
||||
}
|
||||
@ -90,34 +90,34 @@ class ComplexLayout extends StatefulWidget {
|
||||
class ComplexLayoutState extends State<ComplexLayout> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Advanced Layout'),
|
||||
actions: <Widget>[
|
||||
new IconButton(
|
||||
IconButton(
|
||||
icon: const Icon(Icons.create),
|
||||
tooltip: 'Search',
|
||||
onPressed: () {
|
||||
print('Pressed search');
|
||||
},
|
||||
),
|
||||
new TopBarMenu()
|
||||
TopBarMenu()
|
||||
]
|
||||
),
|
||||
body: new Column(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new ListView.builder(
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
key: const Key('complex-scroll'), // this key is used by the driver test
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (index % 2 == 0)
|
||||
return new FancyImageItem(index, key: new PageStorageKey<int>(index));
|
||||
return FancyImageItem(index, key: PageStorageKey<int>(index));
|
||||
else
|
||||
return new FancyGalleryItem(index, key: new PageStorageKey<int>(index));
|
||||
return FancyGalleryItem(index, key: PageStorageKey<int>(index));
|
||||
},
|
||||
)
|
||||
),
|
||||
new BottomBar(),
|
||||
BottomBar(),
|
||||
],
|
||||
),
|
||||
drawer: const GalleryDrawer(),
|
||||
@ -128,7 +128,7 @@ class ComplexLayoutState extends State<ComplexLayout> {
|
||||
class TopBarMenu extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new PopupMenuButton<String>(
|
||||
return PopupMenuButton<String>(
|
||||
onSelected: (String value) { print('Selected: $value'); },
|
||||
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
|
||||
const PopupMenuItem<String>(
|
||||
@ -185,14 +185,14 @@ class MenuItemWithIcon extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Row(
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
new Icon(icon),
|
||||
new Padding(
|
||||
Icon(icon),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
|
||||
child: new Text(title)
|
||||
child: Text(title)
|
||||
),
|
||||
new Text(subtitle, style: Theme.of(context).textTheme.caption)
|
||||
Text(subtitle, style: Theme.of(context).textTheme.caption)
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -205,18 +205,18 @@ class FancyImageItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new ListBody(
|
||||
return ListBody(
|
||||
children: <Widget>[
|
||||
new UserHeader('Ali Connors $index'),
|
||||
new ItemDescription(),
|
||||
new ItemImageBox(),
|
||||
new InfoBar(),
|
||||
UserHeader('Ali Connors $index'),
|
||||
ItemDescription(),
|
||||
ItemImageBox(),
|
||||
InfoBar(),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Divider()
|
||||
),
|
||||
new IconBar(),
|
||||
new FatDivider()
|
||||
IconBar(),
|
||||
FatDivider()
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -228,17 +228,17 @@ class FancyGalleryItem extends StatelessWidget {
|
||||
final int index;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new ListBody(
|
||||
return ListBody(
|
||||
children: <Widget>[
|
||||
const UserHeader('Ali Connors'),
|
||||
new ItemGalleryBox(index),
|
||||
new InfoBar(),
|
||||
ItemGalleryBox(index),
|
||||
InfoBar(),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Divider()
|
||||
),
|
||||
new IconBar(),
|
||||
new FatDivider()
|
||||
IconBar(),
|
||||
FatDivider()
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -247,13 +247,13 @@ class FancyGalleryItem extends StatelessWidget {
|
||||
class InfoBar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
const MiniIconWithText(Icons.thumb_up, '42'),
|
||||
new Text('3 Comments', style: Theme.of(context).textTheme.caption)
|
||||
Text('3 Comments', style: Theme.of(context).textTheme.caption)
|
||||
]
|
||||
)
|
||||
);
|
||||
@ -263,9 +263,9 @@ class InfoBar extends StatelessWidget {
|
||||
class IconBar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: const <Widget>[
|
||||
IconWithText(Icons.thumb_up, 'Like'),
|
||||
@ -285,14 +285,14 @@ class IconWithText extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Row(
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
new IconButton(
|
||||
icon: new Icon(icon),
|
||||
IconButton(
|
||||
icon: Icon(icon),
|
||||
onPressed: () { print('Pressed $title button'); }
|
||||
),
|
||||
new Text(title)
|
||||
Text(title)
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -306,22 +306,22 @@ class MiniIconWithText extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Row(
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: new Container(
|
||||
child: Container(
|
||||
width: 16.0,
|
||||
height: 16.0,
|
||||
decoration: new BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
shape: BoxShape.circle
|
||||
),
|
||||
child: new Icon(icon, color: Colors.white, size: 12.0)
|
||||
child: Icon(icon, color: Colors.white, size: 12.0)
|
||||
)
|
||||
),
|
||||
new Text(title, style: Theme.of(context).textTheme.caption)
|
||||
Text(title, style: Theme.of(context).textTheme.caption)
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -330,7 +330,7 @@ class MiniIconWithText extends StatelessWidget {
|
||||
class FatDivider extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
return Container(
|
||||
height: 8.0,
|
||||
color: Theme.of(context).dividerColor,
|
||||
);
|
||||
@ -344,9 +344,9 @@ class UserHeader extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const Padding(
|
||||
@ -357,29 +357,29 @@ class UserHeader extends StatelessWidget {
|
||||
height: 32.0
|
||||
)
|
||||
),
|
||||
new Expanded(
|
||||
child: new Column(
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
new RichText(text: new TextSpan(
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.body1,
|
||||
children: <TextSpan>[
|
||||
new TextSpan(text: userName, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
TextSpan(text: userName, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
const TextSpan(text: ' shared a new '),
|
||||
const TextSpan(text: 'photo', style: TextStyle(fontWeight: FontWeight.bold))
|
||||
]
|
||||
)),
|
||||
new Row(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
new Text('Yesterday at 11:55 • ', style: Theme.of(context).textTheme.caption),
|
||||
new Icon(Icons.people, size: 16.0, color: Theme.of(context).textTheme.caption.color)
|
||||
Text('Yesterday at 11:55 • ', style: Theme.of(context).textTheme.caption),
|
||||
Icon(Icons.people, size: 16.0, color: Theme.of(context).textTheme.caption.color)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
new TopBarMenu()
|
||||
TopBarMenu()
|
||||
]
|
||||
)
|
||||
);
|
||||
@ -399,13 +399,13 @@ class ItemDescription extends StatelessWidget {
|
||||
class ItemImageBox extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Card(
|
||||
child: new Column(
|
||||
child: Card(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
new Stack(
|
||||
Stack(
|
||||
children: <Widget>[
|
||||
const SizedBox(
|
||||
height: 230.0,
|
||||
@ -413,29 +413,29 @@ class ItemImageBox extends StatelessWidget {
|
||||
image: AssetImage('packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png')
|
||||
)
|
||||
),
|
||||
new Theme(
|
||||
data: new ThemeData.dark(),
|
||||
child: new Row(
|
||||
Theme(
|
||||
data: ThemeData.dark(),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
new IconButton(
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit),
|
||||
onPressed: () { print('Pressed edit button'); }
|
||||
),
|
||||
new IconButton(
|
||||
IconButton(
|
||||
icon: const Icon(Icons.zoom_in),
|
||||
onPressed: () { print('Pressed zoom button'); }
|
||||
),
|
||||
]
|
||||
)
|
||||
),
|
||||
new Positioned(
|
||||
Positioned(
|
||||
bottom: 4.0,
|
||||
left: 4.0,
|
||||
child: new Container(
|
||||
decoration: new BoxDecoration(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black54,
|
||||
borderRadius: new BorderRadius.circular(2.0)
|
||||
borderRadius: BorderRadius.circular(2.0)
|
||||
),
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: const RichText(
|
||||
@ -457,14 +457,14 @@ class ItemImageBox extends StatelessWidget {
|
||||
]
|
||||
)
|
||||
,
|
||||
new Padding(
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
new Text('Artisans of Southern India', style: Theme.of(context).textTheme.body2),
|
||||
new Text('Silk Spinners', style: Theme.of(context).textTheme.body1),
|
||||
new Text('Sivaganga, Tamil Nadu', style: Theme.of(context).textTheme.caption)
|
||||
Text('Artisans of Southern India', style: Theme.of(context).textTheme.body2),
|
||||
Text('Silk Spinners', style: Theme.of(context).textTheme.body1),
|
||||
Text('Sivaganga, Tamil Nadu', style: Theme.of(context).textTheme.caption)
|
||||
]
|
||||
)
|
||||
)
|
||||
@ -486,44 +486,44 @@ class ItemGalleryBox extends StatelessWidget {
|
||||
'A', 'B', 'C', 'D'
|
||||
];
|
||||
|
||||
return new SizedBox(
|
||||
return SizedBox(
|
||||
height: 200.0,
|
||||
child: new DefaultTabController(
|
||||
child: DefaultTabController(
|
||||
length: tabNames.length,
|
||||
child: new Column(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new TabBarView(
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: tabNames.map((String tabName) {
|
||||
return new Container(
|
||||
key: new PageStorageKey<String>(tabName),
|
||||
child: new Padding(
|
||||
return Container(
|
||||
key: PageStorageKey<String>(tabName),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Card(
|
||||
child: new Column(
|
||||
child: Card(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new Container(
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: new Center(
|
||||
child: new Text(tabName, style: Theme.of(context).textTheme.headline.copyWith(color: Colors.white)),
|
||||
child: Center(
|
||||
child: Text(tabName, style: Theme.of(context).textTheme.headline.copyWith(color: Colors.white)),
|
||||
)
|
||||
)
|
||||
),
|
||||
new Row(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
new IconButton(
|
||||
IconButton(
|
||||
icon: const Icon(Icons.share),
|
||||
onPressed: () { print('Pressed share'); },
|
||||
),
|
||||
new IconButton(
|
||||
IconButton(
|
||||
icon: const Icon(Icons.event),
|
||||
onPressed: () { print('Pressed event'); },
|
||||
),
|
||||
new Expanded(
|
||||
child: new Padding(
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: new Text('This is item $tabName'),
|
||||
child: Text('This is item $tabName'),
|
||||
)
|
||||
)
|
||||
]
|
||||
@ -536,7 +536,7 @@ class ItemGalleryBox extends StatelessWidget {
|
||||
}).toList()
|
||||
)
|
||||
),
|
||||
new Container(
|
||||
Container(
|
||||
child: const TabPageSelector()
|
||||
)
|
||||
]
|
||||
@ -549,16 +549,16 @@ class ItemGalleryBox extends StatelessWidget {
|
||||
class BottomBar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
decoration: new BoxDecoration(
|
||||
border: new Border(
|
||||
top: new BorderSide(
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
width: 1.0
|
||||
)
|
||||
)
|
||||
),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: const <Widget>[
|
||||
BottomBarButton(Icons.new_releases, 'News'),
|
||||
@ -580,15 +580,15 @@ class BottomBarButton extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
new IconButton(
|
||||
icon: new Icon(icon),
|
||||
IconButton(
|
||||
icon: Icon(icon),
|
||||
onPressed: () { print('Pressed: $title'); }
|
||||
),
|
||||
new Text(title, style: Theme.of(context).textTheme.caption)
|
||||
Text(title, style: Theme.of(context).textTheme.caption)
|
||||
]
|
||||
)
|
||||
);
|
||||
@ -609,49 +609,49 @@ class GalleryDrawer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ScrollMode currentMode = ComplexLayoutApp.of(context).scrollMode;
|
||||
return new Drawer(
|
||||
return Drawer(
|
||||
// Note: for real apps, see the Gallery material Drawer demo. More
|
||||
// typically, a drawer would have a fixed header with a scrolling body
|
||||
// below it.
|
||||
child: new ListView(
|
||||
child: ListView(
|
||||
key: const PageStorageKey<String>('gallery-drawer'),
|
||||
padding: EdgeInsets.zero,
|
||||
children: <Widget>[
|
||||
new FancyDrawerHeader(),
|
||||
new ListTile(
|
||||
FancyDrawerHeader(),
|
||||
ListTile(
|
||||
key: const Key('scroll-switcher'),
|
||||
onTap: () { _changeScrollMode(context, currentMode == ScrollMode.complex ? ScrollMode.tile : ScrollMode.complex); },
|
||||
trailing: new Text(currentMode == ScrollMode.complex ? 'Tile' : 'Complex')
|
||||
trailing: Text(currentMode == ScrollMode.complex ? 'Tile' : 'Complex')
|
||||
),
|
||||
new ListTile(
|
||||
ListTile(
|
||||
leading: const Icon(Icons.brightness_5),
|
||||
title: const Text('Light'),
|
||||
onTap: () { _changeTheme(context, true); },
|
||||
selected: ComplexLayoutApp.of(context).lightTheme,
|
||||
trailing: new Radio<bool>(
|
||||
trailing: Radio<bool>(
|
||||
value: true,
|
||||
groupValue: ComplexLayoutApp.of(context).lightTheme,
|
||||
onChanged: (bool value) { _changeTheme(context, value); }
|
||||
),
|
||||
),
|
||||
new ListTile(
|
||||
ListTile(
|
||||
leading: const Icon(Icons.brightness_7),
|
||||
title: const Text('Dark'),
|
||||
onTap: () { _changeTheme(context, false); },
|
||||
selected: !ComplexLayoutApp.of(context).lightTheme,
|
||||
trailing: new Radio<bool>(
|
||||
trailing: Radio<bool>(
|
||||
value: false,
|
||||
groupValue: ComplexLayoutApp.of(context).lightTheme,
|
||||
onChanged: (bool value) { _changeTheme(context, value); },
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
new ListTile(
|
||||
ListTile(
|
||||
leading: const Icon(Icons.hourglass_empty),
|
||||
title: const Text('Animate Slowly'),
|
||||
selected: timeDilation != 1.0,
|
||||
onTap: () { ComplexLayoutApp.of(context).toggleAnimationSpeed(); },
|
||||
trailing: new Checkbox(
|
||||
trailing: Checkbox(
|
||||
value: timeDilation != 1.0,
|
||||
onChanged: (bool value) { ComplexLayoutApp.of(context).toggleAnimationSpeed(); }
|
||||
),
|
||||
@ -665,7 +665,7 @@ class GalleryDrawer extends StatelessWidget {
|
||||
class FancyDrawerHeader extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
return Container(
|
||||
color: Colors.purple,
|
||||
height: 200.0,
|
||||
child: const SafeArea(
|
||||
|
@ -25,7 +25,7 @@ void main() {
|
||||
// period of increased load on the device. Without this delay, the
|
||||
// benchmark has greater noise.
|
||||
// See: https://github.com/flutter/flutter/issues/19434
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 250));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 250));
|
||||
final Timeline timeline = await driver.traceAction(() async {
|
||||
// Find the scrollable stock list
|
||||
final SerializableFinder list = find.byValueKey(listKey);
|
||||
@ -34,17 +34,17 @@ void main() {
|
||||
// Scroll down
|
||||
for (int i = 0; i < 5; i += 1) {
|
||||
await driver.scroll(list, 0.0, -300.0, const Duration(milliseconds: 300));
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 500));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
// Scroll up
|
||||
for (int i = 0; i < 5; i += 1) {
|
||||
await driver.scroll(list, 0.0, 300.0, const Duration(milliseconds: 300));
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 500));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
});
|
||||
|
||||
final TimelineSummary summary = new TimelineSummary.summarize(timeline);
|
||||
final TimelineSummary summary = TimelineSummary.summarize(timeline);
|
||||
summary.writeSummaryToFile(summaryName, pretty: true);
|
||||
summary.writeTimelineToFile(summaryName, pretty: true);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ void main() {
|
||||
|
||||
test('inital tree creation', () async {
|
||||
// Let app become fully idle.
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
|
||||
final Timeline timeline = await driver.traceAction(() async {
|
||||
expect(await driver.setSemantics(true), isTrue);
|
||||
@ -37,7 +37,7 @@ void main() {
|
||||
final Duration semanticsTreeCreation = semanticsEvents.first.duration;
|
||||
|
||||
final String jsonEncoded = json.encode(<String, dynamic>{'initialSemanticsTreeCreation': semanticsTreeCreation.inMilliseconds});
|
||||
new File(p.join(testOutputsDirectory, 'complex_layout_semantics_perf.json')).writeAsStringSync(jsonEncoded);
|
||||
File(p.join(testOutputsDirectory, 'complex_layout_semantics_perf.json')).writeAsStringSync(jsonEncoded);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -20,16 +20,16 @@ const int maxIterations = 4;
|
||||
const Duration pauses = Duration(milliseconds: 500);
|
||||
|
||||
Future<void> main() async {
|
||||
final Completer<void> ready = new Completer<void>();
|
||||
runApp(new GestureDetector(
|
||||
final Completer<void> ready = Completer<void>();
|
||||
runApp(GestureDetector(
|
||||
onTap: () {
|
||||
debugPrint('Received tap.');
|
||||
ready.complete();
|
||||
},
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: new IgnorePointer(
|
||||
child: IgnorePointer(
|
||||
ignoring: true,
|
||||
child: new ComplexLayoutApp(),
|
||||
child: ComplexLayoutApp(),
|
||||
),
|
||||
));
|
||||
await SchedulerBinding.instance.endOfFrame;
|
||||
@ -37,35 +37,35 @@ Future<void> main() async {
|
||||
/// Wait 50ms to allow the GPU thread to actually put up the frame. (The
|
||||
/// endOfFrame future ends when we send the data to the engine, before the GPU
|
||||
/// thread has had a chance to rasterize, etc.)
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 50));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 50));
|
||||
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
|
||||
|
||||
await ready.future; // waits for tap sent by devicelab task
|
||||
debugPrint('Continuing...');
|
||||
|
||||
// remove onTap handler, enable pointer events for app
|
||||
runApp(new GestureDetector(
|
||||
child: new IgnorePointer(
|
||||
runApp(GestureDetector(
|
||||
child: IgnorePointer(
|
||||
ignoring: false,
|
||||
child: new ComplexLayoutApp(),
|
||||
child: ComplexLayoutApp(),
|
||||
),
|
||||
));
|
||||
await SchedulerBinding.instance.endOfFrame;
|
||||
|
||||
final WidgetController controller = new LiveWidgetController(WidgetsBinding.instance);
|
||||
final WidgetController controller = LiveWidgetController(WidgetsBinding.instance);
|
||||
|
||||
// Scroll down
|
||||
for (int iteration = 0; iteration < maxIterations; iteration += 1) {
|
||||
debugPrint('Scroll down... $iteration/$maxIterations');
|
||||
await controller.fling(find.byType(ListView), const Offset(0.0, -700.0), speed);
|
||||
await new Future<Null>.delayed(pauses);
|
||||
await Future<Null>.delayed(pauses);
|
||||
}
|
||||
|
||||
// Scroll up
|
||||
for (int iteration = 0; iteration < maxIterations; iteration += 1) {
|
||||
debugPrint('Scroll up... $iteration/$maxIterations');
|
||||
await controller.fling(find.byType(ListView), const Offset(0.0, 300.0), speed);
|
||||
await new Future<Null>.delayed(pauses);
|
||||
await Future<Null>.delayed(pauses);
|
||||
}
|
||||
|
||||
debugPrint('==== MEMORY BENCHMARK ==== DONE ====');
|
||||
|
@ -32,7 +32,7 @@ class BenchmarkResultPrinter {
|
||||
/// [name] is a computer-readable name of the result used as a key in the JSON
|
||||
/// serialization of the results.
|
||||
void addResult({ @required String description, @required double value, @required String unit, @required String name }) {
|
||||
_results.add(new _BenchmarkResult(description, value, unit, name));
|
||||
_results.add(_BenchmarkResult(description, value, unit, name));
|
||||
}
|
||||
|
||||
/// Prints the results added via [addResult] to standard output, once as JSON
|
||||
@ -58,7 +58,7 @@ class BenchmarkResultPrinter {
|
||||
}
|
||||
|
||||
String _printPlainText() {
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
final StringBuffer buf = StringBuffer();
|
||||
for (_BenchmarkResult result in _results) {
|
||||
buf.writeln('${result.description}: ${result.value.toStringAsFixed(1)} ${result.unit}');
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import 'data/velocity_tracker_data.dart';
|
||||
const int _kNumIters = 10000;
|
||||
|
||||
void main() {
|
||||
final VelocityTracker tracker = new VelocityTracker();
|
||||
final Stopwatch watch = new Stopwatch();
|
||||
final VelocityTracker tracker = VelocityTracker();
|
||||
final Stopwatch watch = Stopwatch();
|
||||
print('Velocity tracker benchmark...');
|
||||
watch.start();
|
||||
for (int i = 0; i < _kNumIters; i += 1) {
|
||||
@ -24,7 +24,7 @@ void main() {
|
||||
}
|
||||
watch.stop();
|
||||
|
||||
final BenchmarkResultPrinter printer = new BenchmarkResultPrinter();
|
||||
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
|
||||
printer.addResult(
|
||||
description: 'Velocity tracker',
|
||||
value: watch.elapsedMicroseconds / _kNumIters,
|
||||
|
@ -37,9 +37,9 @@ Future<Null> main() async {
|
||||
assert(false); // don't run this in checked mode! Use --release.
|
||||
stock_data.StockData.actuallyFetchData = false;
|
||||
|
||||
final Stopwatch wallClockWatch = new Stopwatch();
|
||||
final Stopwatch cpuWatch = new Stopwatch();
|
||||
new BenchmarkingBinding(cpuWatch);
|
||||
final Stopwatch wallClockWatch = Stopwatch();
|
||||
final Stopwatch cpuWatch = Stopwatch();
|
||||
BenchmarkingBinding(cpuWatch);
|
||||
|
||||
int totalOpenFrameElapsedMicroseconds = 0;
|
||||
int totalOpenIterationCount = 0;
|
||||
@ -80,7 +80,7 @@ Future<Null> main() async {
|
||||
}
|
||||
});
|
||||
|
||||
final BenchmarkResultPrinter printer = new BenchmarkResultPrinter();
|
||||
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
|
||||
printer.addResult(
|
||||
description: 'Stock animation',
|
||||
value: wallClockWatch.elapsedMicroseconds / (1000 * 1000),
|
||||
|
@ -23,7 +23,7 @@ Future<Null> main() async {
|
||||
// the engine, so that the engine does not interfere with our timings.
|
||||
final LiveTestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final Stopwatch watch = new Stopwatch();
|
||||
final Stopwatch watch = Stopwatch();
|
||||
int iterations = 0;
|
||||
|
||||
await benchmarkWidgets((WidgetTester tester) async {
|
||||
@ -46,7 +46,7 @@ Future<Null> main() async {
|
||||
// frames are missed, etc.
|
||||
// We use Timer.run to ensure there's a microtask flush in between
|
||||
// the two calls below.
|
||||
Timer.run(() { ui.window.onBeginFrame(new Duration(milliseconds: iterations * 16)); });
|
||||
Timer.run(() { ui.window.onBeginFrame(Duration(milliseconds: iterations * 16)); });
|
||||
Timer.run(() { ui.window.onDrawFrame(); });
|
||||
await tester.idle(); // wait until the frame has run (also uses Timer.run)
|
||||
iterations += 1;
|
||||
@ -54,7 +54,7 @@ Future<Null> main() async {
|
||||
watch.stop();
|
||||
});
|
||||
|
||||
final BenchmarkResultPrinter printer = new BenchmarkResultPrinter();
|
||||
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
|
||||
printer.addResult(
|
||||
description: 'Stock build',
|
||||
value: watch.elapsedMicroseconds / iterations,
|
||||
|
@ -22,7 +22,7 @@ Future<Null> main() async {
|
||||
// the engine, so that the engine does not interfere with our timings.
|
||||
final LiveTestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final Stopwatch watch = new Stopwatch();
|
||||
final Stopwatch watch = Stopwatch();
|
||||
int iterations = 0;
|
||||
|
||||
await benchmarkWidgets((WidgetTester tester) async {
|
||||
@ -37,8 +37,8 @@ Future<Null> main() async {
|
||||
ui.window.onBeginFrame = null;
|
||||
ui.window.onDrawFrame = null;
|
||||
|
||||
final TestViewConfiguration big = new TestViewConfiguration(size: const Size(360.0, 640.0));
|
||||
final TestViewConfiguration small = new TestViewConfiguration(size: const Size(355.0, 635.0));
|
||||
final TestViewConfiguration big = TestViewConfiguration(size: const Size(360.0, 640.0));
|
||||
final TestViewConfiguration small = TestViewConfiguration(size: const Size(355.0, 635.0));
|
||||
final RenderView renderView = WidgetsBinding.instance.renderView;
|
||||
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
|
||||
|
||||
@ -51,7 +51,7 @@ Future<Null> main() async {
|
||||
// frames are missed, etc.
|
||||
// We use Timer.run to ensure there's a microtask flush in between
|
||||
// the two calls below.
|
||||
Timer.run(() { binding.handleBeginFrame(new Duration(milliseconds: iterations * 16)); });
|
||||
Timer.run(() { binding.handleBeginFrame(Duration(milliseconds: iterations * 16)); });
|
||||
Timer.run(() { binding.handleDrawFrame(); });
|
||||
await tester.idle(); // wait until the frame has run (also uses Timer.run)
|
||||
iterations += 1;
|
||||
@ -59,7 +59,7 @@ Future<Null> main() async {
|
||||
watch.stop();
|
||||
});
|
||||
|
||||
final BenchmarkResultPrinter printer = new BenchmarkResultPrinter();
|
||||
final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
|
||||
printer.addResult(
|
||||
description: 'Stock layout',
|
||||
value: watch.elapsedMicroseconds / iterations,
|
||||
|
@ -58,7 +58,7 @@ class Line {
|
||||
Line operator +(int count) {
|
||||
if (count == 0)
|
||||
return this;
|
||||
return new Line(filename, line + count, indent);
|
||||
return Line(filename, line + count, indent);
|
||||
}
|
||||
@override
|
||||
String toString([int column]) {
|
||||
@ -87,7 +87,7 @@ class Section {
|
||||
}
|
||||
}
|
||||
List<Line> get lines {
|
||||
final List<Line> result = new List<Line>.generate(code.length, (int index) => start + index);
|
||||
final List<Line> result = List<Line>.generate(code.length, (int index) => start + index);
|
||||
if (preamble != null)
|
||||
result.insert(0, null);
|
||||
if (postamble != null)
|
||||
@ -105,15 +105,15 @@ Future<Null> main(List<String> arguments) async {
|
||||
bool keepMain = false;
|
||||
final List<String> buffer = <String>[];
|
||||
try {
|
||||
final File mainDart = new File(path.join(tempDir.path, 'main.dart'));
|
||||
final File pubSpec = new File(path.join(tempDir.path, 'pubspec.yaml'));
|
||||
final File analysisOptions = new File(path.join(tempDir.path, 'analysis_options.yaml'));
|
||||
final File mainDart = File(path.join(tempDir.path, 'main.dart'));
|
||||
final File pubSpec = File(path.join(tempDir.path, 'pubspec.yaml'));
|
||||
final File analysisOptions = File(path.join(tempDir.path, 'analysis_options.yaml'));
|
||||
Directory flutterPackage;
|
||||
if (arguments.length == 1) {
|
||||
// Used for testing.
|
||||
flutterPackage = new Directory(arguments.single);
|
||||
flutterPackage = Directory(arguments.single);
|
||||
} else {
|
||||
flutterPackage = new Directory(path.join(_flutterRoot, 'packages', 'flutter', 'lib'));
|
||||
flutterPackage = Directory(path.join(_flutterRoot, 'packages', 'flutter', 'lib'));
|
||||
}
|
||||
final List<Section> sections = <Section>[];
|
||||
int sampleCodeSections = 0;
|
||||
@ -161,7 +161,7 @@ Future<Null> main(List<String> arguments) async {
|
||||
}
|
||||
} else if (trimmedLine == '/// ```dart') {
|
||||
assert(block.isEmpty);
|
||||
startLine = new Line(file.path, lineNumber + 1, line.indexOf(kDartDocPrefixWithSpace) + kDartDocPrefixWithSpace.length);
|
||||
startLine = Line(file.path, lineNumber + 1, line.indexOf(kDartDocPrefixWithSpace) + kDartDocPrefixWithSpace.length);
|
||||
inDart = true;
|
||||
foundDart = true;
|
||||
}
|
||||
@ -170,7 +170,7 @@ Future<Null> main(List<String> arguments) async {
|
||||
if (!inSampleSection) {
|
||||
if (line == '// Examples can assume:') {
|
||||
assert(block.isEmpty);
|
||||
startLine = new Line(file.path, lineNumber + 1, 3);
|
||||
startLine = Line(file.path, lineNumber + 1, 3);
|
||||
inPreamble = true;
|
||||
} else if (trimmedLine == '/// ## Sample code' ||
|
||||
trimmedLine.startsWith('/// ## Sample code:') ||
|
||||
@ -199,7 +199,7 @@ Future<Null> main(List<String> arguments) async {
|
||||
}
|
||||
}
|
||||
buffer.add('');
|
||||
final List<Line> lines = new List<Line>.filled(buffer.length, null, growable: true);
|
||||
final List<Line> lines = List<Line>.filled(buffer.length, null, growable: true);
|
||||
for (Section section in sections) {
|
||||
buffer.addAll(section.strings);
|
||||
lines.addAll(section.lines);
|
||||
@ -247,7 +247,7 @@ linter:
|
||||
errors.removeAt(0);
|
||||
int errorCount = 0;
|
||||
final String kBullet = Platform.isWindows ? ' - ' : ' • ';
|
||||
final RegExp errorPattern = new RegExp('^ +([a-z]+)$kBullet(.+)$kBullet(.+):([0-9]+):([0-9]+)$kBullet([-a-z_]+)\$', caseSensitive: false);
|
||||
final RegExp errorPattern = RegExp('^ +([a-z]+)$kBullet(.+)$kBullet(.+):([0-9]+):([0-9]+)$kBullet([-a-z_]+)\$', caseSensitive: false);
|
||||
for (String error in errors) {
|
||||
final Match parts = errorPattern.matchAsPrefix(error);
|
||||
if (parts != null) {
|
||||
@ -315,7 +315,7 @@ linter:
|
||||
exit(exitCode);
|
||||
}
|
||||
|
||||
final RegExp _constructorRegExp = new RegExp(r'[A-Z][a-zA-Z0-9<>.]*\(');
|
||||
final RegExp _constructorRegExp = RegExp(r'[A-Z][a-zA-Z0-9<>.]*\(');
|
||||
|
||||
int _expressionId = 0;
|
||||
|
||||
@ -324,12 +324,12 @@ void processBlock(Line line, List<String> block, List<Section> sections) {
|
||||
throw '$line: Empty ```dart block in sample code.';
|
||||
if (block.first.startsWith('new ') || block.first.startsWith('const ') || block.first.startsWith(_constructorRegExp)) {
|
||||
_expressionId += 1;
|
||||
sections.add(new Section(line, 'dynamic expression$_expressionId = ', block.toList(), ';'));
|
||||
sections.add(Section(line, 'dynamic expression$_expressionId = ', block.toList(), ';'));
|
||||
} else if (block.first.startsWith('await ')) {
|
||||
_expressionId += 1;
|
||||
sections.add(new Section(line, 'Future<Null> expression$_expressionId() async { ', block.toList(), ' }'));
|
||||
sections.add(Section(line, 'Future<Null> expression$_expressionId() async { ', block.toList(), ' }'));
|
||||
} else if (block.first.startsWith('class ') || block.first.startsWith('enum ')) {
|
||||
sections.add(new Section(line, null, block.toList(), null));
|
||||
sections.add(Section(line, null, block.toList(), null));
|
||||
} else {
|
||||
final List<String> buffer = <String>[];
|
||||
int subblocks = 0;
|
||||
@ -354,7 +354,7 @@ void processBlock(Line line, List<String> block, List<Section> sections) {
|
||||
if (subline != null)
|
||||
processBlock(subline, buffer, sections);
|
||||
} else {
|
||||
sections.add(new Section(line, null, block.toList(), null));
|
||||
sections.add(Section(line, null, block.toList(), null));
|
||||
}
|
||||
}
|
||||
block.clear();
|
||||
|
@ -94,7 +94,7 @@ Future<Null> _verifyInternationalizations() async {
|
||||
);
|
||||
|
||||
final String localizationsFile = path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n', 'localizations.dart');
|
||||
final String expectedResult = await new File(localizationsFile).readAsString();
|
||||
final String expectedResult = await File(localizationsFile).readAsString();
|
||||
|
||||
if (genResult.stdout.trim() != expectedResult.trim()) {
|
||||
stderr
|
||||
@ -153,7 +153,7 @@ Future<Null> _checkForTrailingSpaces() async {
|
||||
// Only include files that actually exist, so that we don't try and grep for
|
||||
// nonexistent files, which can occur when files are deleted or moved.
|
||||
final List<String> changedFiles = changedFilesResult.stdout.split('\n').where((String filename) {
|
||||
return new File(filename).existsSync();
|
||||
return File(filename).existsSync();
|
||||
}).toList();
|
||||
if (changedFiles.isNotEmpty) {
|
||||
await runCommand('grep',
|
||||
@ -197,7 +197,7 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
|
||||
}
|
||||
printProgress('RUNNING', relativeWorkingDir, commandDescription);
|
||||
|
||||
final DateTime start = new DateTime.now();
|
||||
final DateTime start = DateTime.now();
|
||||
final Process process = await Process.start(executable, arguments,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
@ -206,7 +206,7 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
|
||||
final Future<List<List<int>>> savedStdout = process.stdout.toList();
|
||||
final Future<List<List<int>>> savedStderr = process.stderr.toList();
|
||||
final int exitCode = await process.exitCode;
|
||||
final EvalResult result = new EvalResult(
|
||||
final EvalResult result = EvalResult(
|
||||
stdout: utf8.decode((await savedStdout).expand((List<int> ints) => ints).toList()),
|
||||
stderr: utf8.decode((await savedStderr).expand((List<int> ints) => ints).toList()),
|
||||
exitCode: exitCode,
|
||||
@ -240,7 +240,7 @@ Future<Null> _runFlutterAnalyze(String workingDirectory, {
|
||||
Future<Null> _verifyNoTestPackageImports(String workingDirectory) async {
|
||||
// TODO(ianh): Remove this whole test once https://github.com/dart-lang/matcher/issues/98 is fixed.
|
||||
final List<String> shims = <String>[];
|
||||
final List<String> errors = new Directory(workingDirectory)
|
||||
final List<String> errors = Directory(workingDirectory)
|
||||
.listSync(recursive: true)
|
||||
.where((FileSystemEntity entity) {
|
||||
return entity is File && entity.path.endsWith('.dart');
|
||||
@ -320,11 +320,11 @@ Future<Null> _verifyNoBadImportsInFlutter(String workingDirectory) async {
|
||||
final String libPath = path.join(workingDirectory, 'packages', 'flutter', 'lib');
|
||||
final String srcPath = path.join(workingDirectory, 'packages', 'flutter', 'lib', 'src');
|
||||
// Verify there's one libPath/*.dart for each srcPath/*/.
|
||||
final List<String> packages = new Directory(libPath).listSync()
|
||||
final List<String> packages = Directory(libPath).listSync()
|
||||
.where((FileSystemEntity entity) => entity is File && path.extension(entity.path) == '.dart')
|
||||
.map<String>((FileSystemEntity entity) => path.basenameWithoutExtension(entity.path))
|
||||
.toList()..sort();
|
||||
final List<String> directories = new Directory(srcPath).listSync()
|
||||
final List<String> directories = Directory(srcPath).listSync()
|
||||
.whereType<Directory>()
|
||||
.map<String>((Directory entity) => path.basename(entity.path))
|
||||
.toList()..sort();
|
||||
@ -384,14 +384,14 @@ bool _matches<T>(List<T> a, List<T> b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final RegExp _importPattern = new RegExp(r"import 'package:flutter/([^.]+)\.dart'");
|
||||
final RegExp _importMetaPattern = new RegExp(r"import 'package:meta/meta.dart'");
|
||||
final RegExp _importPattern = RegExp(r"import 'package:flutter/([^.]+)\.dart'");
|
||||
final RegExp _importMetaPattern = RegExp(r"import 'package:meta/meta.dart'");
|
||||
|
||||
Set<String> _findDependencies(String srcPath, List<String> errors, { bool checkForMeta = false }) {
|
||||
return new Directory(srcPath).listSync(recursive: true).where((FileSystemEntity entity) {
|
||||
return Directory(srcPath).listSync(recursive: true).where((FileSystemEntity entity) {
|
||||
return entity is File && path.extension(entity.path) == '.dart';
|
||||
}).map<Set<String>>((FileSystemEntity entity) {
|
||||
final Set<String> result = new Set<String>();
|
||||
final Set<String> result = Set<String>();
|
||||
final File file = entity;
|
||||
for (String line in file.readAsLinesSync()) {
|
||||
Match match = _importPattern.firstMatch(line);
|
||||
@ -409,7 +409,7 @@ Set<String> _findDependencies(String srcPath, List<String> errors, { bool checkF
|
||||
}
|
||||
return result;
|
||||
}).reduce((Set<String> value, Set<String> element) {
|
||||
value ??= new Set<String>();
|
||||
value ??= Set<String>();
|
||||
value.addAll(element);
|
||||
return value;
|
||||
});
|
||||
@ -424,7 +424,7 @@ List<T> _deepSearch<T>(Map<T, Set<T>> map, T start, [ Set<T> seen ]) {
|
||||
final List<T> result = _deepSearch(
|
||||
map,
|
||||
key,
|
||||
(seen == null ? new Set<T>.from(<T>[start]) : new Set<T>.from(seen))..add(key),
|
||||
(seen == null ? Set<T>.from(<T>[start]) : Set<T>.from(seen))..add(key),
|
||||
);
|
||||
if (result != null) {
|
||||
result.insert(0, start);
|
||||
@ -441,7 +441,7 @@ List<T> _deepSearch<T>(Map<T, Set<T>> map, T start, [ Set<T> seen ]) {
|
||||
|
||||
Future<Null> _verifyNoBadImportsInFlutterTools(String workingDirectory) async {
|
||||
final List<String> errors = <String>[];
|
||||
for (FileSystemEntity entity in new Directory(path.join(workingDirectory, 'packages', 'flutter_tools', 'lib'))
|
||||
for (FileSystemEntity entity in Directory(path.join(workingDirectory, 'packages', 'flutter_tools', 'lib'))
|
||||
.listSync(recursive: true)
|
||||
.where((FileSystemEntity entity) => entity is File && path.extension(entity.path) == '.dart')) {
|
||||
final File file = entity;
|
||||
@ -464,7 +464,7 @@ Future<Null> _verifyNoBadImportsInFlutterTools(String workingDirectory) async {
|
||||
}
|
||||
|
||||
Future<Null> _verifyGeneratedPluginRegistrants(String flutterRoot) async {
|
||||
final Directory flutterRootDir = new Directory(flutterRoot);
|
||||
final Directory flutterRootDir = Directory(flutterRoot);
|
||||
|
||||
final Map<String, List<File>> packageToRegistrants = <String, List<File>>{};
|
||||
|
||||
@ -478,7 +478,7 @@ Future<Null> _verifyGeneratedPluginRegistrants(String flutterRoot) async {
|
||||
}
|
||||
}
|
||||
|
||||
final Set<String> outOfDate = new Set<String>();
|
||||
final Set<String> outOfDate = Set<String>();
|
||||
|
||||
for (String package in packageToRegistrants.keys) {
|
||||
final Map<File, String> fileToContent = <File, String>{};
|
||||
@ -510,11 +510,11 @@ Future<Null> _verifyGeneratedPluginRegistrants(String flutterRoot) async {
|
||||
|
||||
String _getPackageFor(File entity, Directory flutterRootDir) {
|
||||
for (Directory dir = entity.parent; dir != flutterRootDir; dir = dir.parent) {
|
||||
if (new File(path.join(dir.path, 'pubspec.yaml')).existsSync()) {
|
||||
if (File(path.join(dir.path, 'pubspec.yaml')).existsSync()) {
|
||||
return dir.path;
|
||||
}
|
||||
}
|
||||
throw new ArgumentError('$entity is not within a dart package.');
|
||||
throw ArgumentError('$entity is not within a dart package.');
|
||||
}
|
||||
|
||||
bool _isGeneratedPluginRegistrant(File file) {
|
||||
|
@ -68,7 +68,7 @@ Branch fromBranchName(String name) {
|
||||
case 'release':
|
||||
return Branch.release;
|
||||
default:
|
||||
throw new ArgumentError('Invalid branch name.');
|
||||
throw ArgumentError('Invalid branch name.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ class ProcessRunner {
|
||||
this.defaultWorkingDirectory,
|
||||
this.platform = const LocalPlatform(),
|
||||
}) : processManager = processManager ?? const LocalProcessManager() {
|
||||
environment = new Map<String, String>.from(platform.environment);
|
||||
environment = Map<String, String>.from(platform.environment);
|
||||
}
|
||||
|
||||
/// The platform to use for a starting environment.
|
||||
@ -119,8 +119,8 @@ class ProcessRunner {
|
||||
stderr.write('Running "${commandLine.join(' ')}" in ${workingDirectory.path}.\n');
|
||||
}
|
||||
final List<int> output = <int>[];
|
||||
final Completer<Null> stdoutComplete = new Completer<Null>();
|
||||
final Completer<Null> stderrComplete = new Completer<Null>();
|
||||
final Completer<Null> stdoutComplete = Completer<Null>();
|
||||
final Completer<Null> stderrComplete = Completer<Null>();
|
||||
Process process;
|
||||
Future<int> allComplete() async {
|
||||
await stderrComplete.future;
|
||||
@ -156,19 +156,19 @@ class ProcessRunner {
|
||||
} on ProcessException catch (e) {
|
||||
final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} '
|
||||
'failed with:\n${e.toString()}';
|
||||
throw new ProcessRunnerException(message);
|
||||
throw ProcessRunnerException(message);
|
||||
} on ArgumentError catch (e) {
|
||||
final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} '
|
||||
'failed with:\n${e.toString()}';
|
||||
throw new ProcessRunnerException(message);
|
||||
throw ProcessRunnerException(message);
|
||||
}
|
||||
|
||||
final int exitCode = await allComplete();
|
||||
if (exitCode != 0 && !failOk) {
|
||||
final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} failed';
|
||||
throw new ProcessRunnerException(
|
||||
throw ProcessRunnerException(
|
||||
message,
|
||||
new ProcessResult(0, exitCode, null, 'returned $exitCode'),
|
||||
ProcessResult(0, exitCode, null, 'returned $exitCode'),
|
||||
);
|
||||
}
|
||||
return utf8.decoder.convert(output).trim();
|
||||
@ -197,9 +197,9 @@ class ArchiveCreator {
|
||||
this.platform = const LocalPlatform(),
|
||||
HttpReader httpReader,
|
||||
}) : assert(revision.length == 40),
|
||||
flutterRoot = new Directory(path.join(tempDir.path, 'flutter')),
|
||||
flutterRoot = Directory(path.join(tempDir.path, 'flutter')),
|
||||
httpReader = httpReader ?? http.readBytes,
|
||||
_processRunner = new ProcessRunner(
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
platform: platform,
|
||||
@ -276,7 +276,7 @@ class ArchiveCreator {
|
||||
/// Performs all of the steps needed to create an archive.
|
||||
Future<File> createArchive() async {
|
||||
assert(_version != null, 'Must run initializeRepo before createArchive');
|
||||
_outputFile = new File(path.join(outputDir.absolute.path, _archiveName));
|
||||
_outputFile = File(path.join(outputDir.absolute.path, _archiveName));
|
||||
await _installMinGitIfNeeded();
|
||||
await _populateCaches();
|
||||
await _archiveFiles(_outputFile);
|
||||
@ -308,11 +308,11 @@ class ArchiveCreator {
|
||||
return;
|
||||
}
|
||||
final Uint8List data = await httpReader(_minGitUri);
|
||||
final File gitFile = new File(path.join(tempDir.absolute.path, 'mingit.zip'));
|
||||
final File gitFile = File(path.join(tempDir.absolute.path, 'mingit.zip'));
|
||||
await gitFile.writeAsBytes(data, flush: true);
|
||||
|
||||
final Directory minGitPath =
|
||||
new Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit'));
|
||||
Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit'));
|
||||
await minGitPath.create(recursive: true);
|
||||
await _unzipArchive(gitFile, workingDirectory: minGitPath);
|
||||
}
|
||||
@ -367,7 +367,7 @@ class ArchiveCreator {
|
||||
/// Unpacks the given zip file into the currentDirectory (if set), or the
|
||||
/// same directory as the archive.
|
||||
Future<String> _unzipArchive(File archive, {Directory workingDirectory}) {
|
||||
workingDirectory ??= new Directory(path.dirname(archive.absolute.path));
|
||||
workingDirectory ??= Directory(path.dirname(archive.absolute.path));
|
||||
List<String> commandLine;
|
||||
if (platform.isWindows) {
|
||||
commandLine = <String>[
|
||||
@ -407,7 +407,7 @@ class ArchiveCreator {
|
||||
}
|
||||
return _processRunner.runProcess(
|
||||
commandLine,
|
||||
workingDirectory: new Directory(path.dirname(source.absolute.path)),
|
||||
workingDirectory: Directory(path.dirname(source.absolute.path)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ class ArchiveCreator {
|
||||
'cJf',
|
||||
output.absolute.path,
|
||||
path.basename(source.absolute.path),
|
||||
], workingDirectory: new Directory(path.dirname(source.absolute.path)));
|
||||
], workingDirectory: Directory(path.dirname(source.absolute.path)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ class ArchivePublisher {
|
||||
}) : assert(revision.length == 40),
|
||||
platformName = platform.operatingSystem.toLowerCase(),
|
||||
metadataGsPath = '$gsReleaseFolder/${getMetadataFilename(platform)}',
|
||||
_processRunner = new ProcessRunner(
|
||||
_processRunner = ProcessRunner(
|
||||
processManager: processManager,
|
||||
subprocessOutput: subprocessOutput,
|
||||
);
|
||||
@ -475,7 +475,7 @@ class ArchivePublisher {
|
||||
newEntry['hash'] = revision;
|
||||
newEntry['channel'] = branchName;
|
||||
newEntry['version'] = version;
|
||||
newEntry['release_date'] = new DateTime.now().toUtc().toIso8601String();
|
||||
newEntry['release_date'] = DateTime.now().toUtc().toIso8601String();
|
||||
newEntry['archive'] = destinationArchivePath;
|
||||
|
||||
// Search for any entries with the same hash and channel and remove them.
|
||||
@ -502,20 +502,20 @@ class ArchivePublisher {
|
||||
// Windows wants to echo the commands that execute in gsutil.bat to the
|
||||
// stdout when we do that. So, we copy the file locally and then read it
|
||||
// back in.
|
||||
final File metadataFile = new File(
|
||||
final File metadataFile = File(
|
||||
path.join(tempDir.absolute.path, getMetadataFilename(platform)),
|
||||
);
|
||||
await _runGsUtil(<String>['cp', metadataGsPath, metadataFile.absolute.path]);
|
||||
final String currentMetadata = metadataFile.readAsStringSync();
|
||||
if (currentMetadata.isEmpty) {
|
||||
throw new ProcessRunnerException('Empty metadata received from server');
|
||||
throw ProcessRunnerException('Empty metadata received from server');
|
||||
}
|
||||
|
||||
Map<String, dynamic> jsonData;
|
||||
try {
|
||||
jsonData = json.decode(currentMetadata);
|
||||
} on FormatException catch (e) {
|
||||
throw new ProcessRunnerException('Unable to parse JSON metadata received from cloud: $e');
|
||||
throw ProcessRunnerException('Unable to parse JSON metadata received from cloud: $e');
|
||||
}
|
||||
|
||||
jsonData = _addRelease(jsonData);
|
||||
@ -570,7 +570,7 @@ class ArchivePublisher {
|
||||
/// Note that archives contain the executables and customizations for the
|
||||
/// platform that they are created on.
|
||||
Future<Null> main(List<String> argList) async {
|
||||
final ArgParser argParser = new ArgParser();
|
||||
final ArgParser argParser = ArgParser();
|
||||
argParser.addOption(
|
||||
'temp_dir',
|
||||
defaultsTo: null,
|
||||
@ -643,7 +643,7 @@ Future<Null> main(List<String> argList) async {
|
||||
tempDir = Directory.systemTemp.createTempSync('flutter_package.');
|
||||
removeTempDir = true;
|
||||
} else {
|
||||
tempDir = new Directory(args['temp_dir']);
|
||||
tempDir = Directory(args['temp_dir']);
|
||||
if (!tempDir.existsSync()) {
|
||||
errorExit("Temporary directory ${args['temp_dir']} doesn't exist.");
|
||||
}
|
||||
@ -653,21 +653,21 @@ Future<Null> main(List<String> argList) async {
|
||||
if (args['output'] == null) {
|
||||
outputDir = tempDir;
|
||||
} else {
|
||||
outputDir = new Directory(args['output']);
|
||||
outputDir = Directory(args['output']);
|
||||
if (!outputDir.existsSync()) {
|
||||
outputDir.createSync(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
final Branch branch = fromBranchName(args['branch']);
|
||||
final ArchiveCreator creator = new ArchiveCreator(tempDir, outputDir, revision, branch);
|
||||
final ArchiveCreator creator = ArchiveCreator(tempDir, outputDir, revision, branch);
|
||||
int exitCode = 0;
|
||||
String message;
|
||||
try {
|
||||
final String version = await creator.initializeRepo();
|
||||
final File outputFile = await creator.createArchive();
|
||||
if (args['publish']) {
|
||||
final ArchivePublisher publisher = new ArchivePublisher(
|
||||
final ArchivePublisher publisher = ArchivePublisher(
|
||||
tempDir,
|
||||
revision,
|
||||
branch,
|
||||
|
@ -23,7 +23,7 @@ const String clock = '🕐';
|
||||
const Duration _kLongTimeout = Duration(minutes: 45);
|
||||
|
||||
String elapsedTime(DateTime start) {
|
||||
return new DateTime.now().difference(start).toString();
|
||||
return DateTime.now().difference(start).toString();
|
||||
}
|
||||
|
||||
void printProgress(String action, String workingDir, String command) {
|
||||
@ -48,7 +48,7 @@ Future<Null> runCommand(String executable, List<String> arguments, {
|
||||
}
|
||||
printProgress('RUNNING', relativeWorkingDir, commandDescription);
|
||||
|
||||
final DateTime start = new DateTime.now();
|
||||
final DateTime start = DateTime.now();
|
||||
final Process process = await Process.start(executable, arguments,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
|
@ -173,7 +173,7 @@ Future<Null> _runTests() async {
|
||||
}
|
||||
|
||||
Future<Null> _runCoverage() async {
|
||||
final File coverageFile = new File(path.join(flutterRoot, 'packages', 'flutter', 'coverage', 'lcov.info'));
|
||||
final File coverageFile = File(path.join(flutterRoot, 'packages', 'flutter', 'coverage', 'lcov.info'));
|
||||
if (!coverageFile.existsSync()) {
|
||||
print('${red}Coverage file not found.$reset');
|
||||
print('Expected to find: ${coverageFile.absolute}');
|
||||
@ -209,7 +209,7 @@ Future<Null> _pubRunTest(
|
||||
if (testPath != null)
|
||||
args.add(testPath);
|
||||
final Map<String, String> pubEnvironment = <String, String>{};
|
||||
if (new Directory(pubCache).existsSync()) {
|
||||
if (Directory(pubCache).existsSync()) {
|
||||
pubEnvironment['PUB_CACHE'] = pubCache;
|
||||
}
|
||||
if (enableFlutterToolAsserts) {
|
||||
@ -274,20 +274,20 @@ Future<Null> _runFlutterTest(String workingDirectory, {
|
||||
}
|
||||
|
||||
Future<Null> _verifyVersion(String filename) async {
|
||||
if (!new File(filename).existsSync()) {
|
||||
if (!File(filename).existsSync()) {
|
||||
print('$redLine');
|
||||
print('The version logic failed to create the Flutter version file.');
|
||||
print('$redLine');
|
||||
exit(1);
|
||||
}
|
||||
final String version = await new File(filename).readAsString();
|
||||
final String version = await File(filename).readAsString();
|
||||
if (version == '0.0.0-unknown') {
|
||||
print('$redLine');
|
||||
print('The version logic failed to determine the Flutter version.');
|
||||
print('$redLine');
|
||||
exit(1);
|
||||
}
|
||||
final RegExp pattern = new RegExp(r'^[0-9]+\.[0-9]+\.[0-9]+(-pre\.[0-9]+)?$');
|
||||
final RegExp pattern = RegExp(r'^[0-9]+\.[0-9]+\.[0-9]+(-pre\.[0-9]+)?$');
|
||||
if (!version.contains(pattern)) {
|
||||
print('$redLine');
|
||||
print('The version logic generated an invalid version string.');
|
||||
|
@ -15,10 +15,10 @@ void main() {
|
||||
);
|
||||
final List<String> stdout = await process.stdout.transform(utf8.decoder).transform(const LineSplitter()).toList();
|
||||
final List<String> stderr = await process.stderr.transform(utf8.decoder).transform(const LineSplitter()).toList();
|
||||
final Match line = new RegExp(r'^(.+)/main\.dart:[0-9]+:[0-9]+: .+$').matchAsPrefix(stdout[1]);
|
||||
final Match line = RegExp(r'^(.+)/main\.dart:[0-9]+:[0-9]+: .+$').matchAsPrefix(stdout[1]);
|
||||
expect(line, isNot(isNull));
|
||||
final String directory = line.group(1);
|
||||
new Directory(directory).deleteSync(recursive: true);
|
||||
Directory(directory).deleteSync(recursive: true);
|
||||
expect(await process.exitCode, 1);
|
||||
expect(stderr, isEmpty);
|
||||
expect(stdout, <String>[
|
||||
|
@ -13,7 +13,7 @@ export 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
// TODO(ianh): Remove this file once https://github.com/dart-lang/matcher/issues/98 is fixed
|
||||
|
||||
/// A matcher that compares the type of the actual value to the type argument T.
|
||||
Matcher isInstanceOf<T>() => new test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
Matcher isInstanceOf<T>() => test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
|
||||
void tryToDelete(Directory directory) {
|
||||
// This should not be necessary, but it turns out that
|
||||
|
@ -36,7 +36,7 @@ class FakeProcessManager extends Mock implements ProcessManager {
|
||||
_fakeResults = <String, List<ProcessResult>>{};
|
||||
for (String key in value.keys) {
|
||||
_fakeResults[key] = <ProcessResult>[]
|
||||
..addAll(value[key] ?? <ProcessResult>[new ProcessResult(0, 0, '', '')]);
|
||||
..addAll(value[key] ?? <ProcessResult>[ProcessResult(0, 0, '', '')]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,11 +63,11 @@ class FakeProcessManager extends Mock implements ProcessManager {
|
||||
}
|
||||
|
||||
FakeProcess _popProcess(List<String> command) =>
|
||||
new FakeProcess(_popResult(command), stdinResults: stdinResults);
|
||||
FakeProcess(_popResult(command), stdinResults: stdinResults);
|
||||
|
||||
Future<Process> _nextProcess(Invocation invocation) async {
|
||||
invocations.add(invocation);
|
||||
return new Future<Process>.value(_popProcess(invocation.positionalArguments[0]));
|
||||
return Future<Process>.value(_popProcess(invocation.positionalArguments[0]));
|
||||
}
|
||||
|
||||
ProcessResult _nextResultSync(Invocation invocation) {
|
||||
@ -77,7 +77,7 @@ class FakeProcessManager extends Mock implements ProcessManager {
|
||||
|
||||
Future<ProcessResult> _nextResult(Invocation invocation) async {
|
||||
invocations.add(invocation);
|
||||
return new Future<ProcessResult>.value(_popResult(invocation.positionalArguments[0]));
|
||||
return Future<ProcessResult>.value(_popResult(invocation.positionalArguments[0]));
|
||||
}
|
||||
|
||||
void _setupMock() {
|
||||
@ -118,10 +118,10 @@ class FakeProcessManager extends Mock implements ProcessManager {
|
||||
/// A fake process that can be used to interact with a process "started" by the FakeProcessManager.
|
||||
class FakeProcess extends Mock implements Process {
|
||||
FakeProcess(ProcessResult result, {void stdinResults(String input)})
|
||||
: stdoutStream = new Stream<List<int>>.fromIterable(<List<int>>[result.stdout.codeUnits]),
|
||||
stderrStream = new Stream<List<int>>.fromIterable(<List<int>>[result.stderr.codeUnits]),
|
||||
: stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[result.stdout.codeUnits]),
|
||||
stderrStream = Stream<List<int>>.fromIterable(<List<int>>[result.stderr.codeUnits]),
|
||||
desiredExitCode = result.exitCode,
|
||||
stdinSink = new IOSink(new StringStreamConsumer(stdinResults)) {
|
||||
stdinSink = IOSink(StringStreamConsumer(stdinResults)) {
|
||||
_setupMock();
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ class FakeProcess extends Mock implements Process {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> get exitCode => new Future<int>.value(desiredExitCode);
|
||||
Future<int> get exitCode => Future<int>.value(desiredExitCode);
|
||||
|
||||
@override
|
||||
int get pid => 0;
|
||||
@ -167,14 +167,14 @@ class StringStreamConsumer implements StreamConsumer<List<int>> {
|
||||
@override
|
||||
Future<dynamic> addStream(Stream<List<int>> value) {
|
||||
streams.add(value);
|
||||
completers.add(new Completer<dynamic>());
|
||||
completers.add(Completer<dynamic>());
|
||||
subscriptions.add(
|
||||
value.listen((List<int> data) {
|
||||
sendString(utf8.decode(data));
|
||||
}),
|
||||
);
|
||||
subscriptions.last.onDone(() => completers.last.complete(null));
|
||||
return new Future<dynamic>.value(null);
|
||||
return Future<dynamic>.value(null);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -185,6 +185,6 @@ class StringStreamConsumer implements StreamConsumer<List<int>> {
|
||||
completers.clear();
|
||||
streams.clear();
|
||||
subscriptions.clear();
|
||||
return new Future<dynamic>.value(null);
|
||||
return Future<dynamic>.value(null);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ void main() {
|
||||
}
|
||||
|
||||
setUp(() async {
|
||||
processManager = new FakeProcessManager(stdinResults: _captureStdin);
|
||||
processManager = FakeProcessManager(stdinResults: _captureStdin);
|
||||
});
|
||||
|
||||
tearDown(() async {});
|
||||
@ -27,10 +27,10 @@ void main() {
|
||||
test('start works', () async {
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'gsutil acl get gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output1', '')
|
||||
ProcessResult(0, 0, 'output1', '')
|
||||
],
|
||||
'gsutil cat gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output2', '')
|
||||
ProcessResult(0, 0, 'output2', '')
|
||||
],
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
@ -49,10 +49,10 @@ void main() {
|
||||
test('run works', () async {
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'gsutil acl get gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output1', '')
|
||||
ProcessResult(0, 0, 'output1', '')
|
||||
],
|
||||
'gsutil cat gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output2', '')
|
||||
ProcessResult(0, 0, 'output2', '')
|
||||
],
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
@ -66,10 +66,10 @@ void main() {
|
||||
test('runSync works', () async {
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'gsutil acl get gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output1', '')
|
||||
ProcessResult(0, 0, 'output1', '')
|
||||
],
|
||||
'gsutil cat gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output2', '')
|
||||
ProcessResult(0, 0, 'output2', '')
|
||||
],
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
@ -83,10 +83,10 @@ void main() {
|
||||
test('captures stdin', () async {
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'gsutil acl get gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output1', '')
|
||||
ProcessResult(0, 0, 'output1', '')
|
||||
],
|
||||
'gsutil cat gs://flutter_infra/releases/releases.json': <ProcessResult>[
|
||||
new ProcessResult(0, 0, 'output2', '')
|
||||
ProcessResult(0, 0, 'output2', '')
|
||||
],
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
|
@ -20,7 +20,7 @@ void main() {
|
||||
test('Throws on missing executable', () async {
|
||||
// Uses a *real* process manager, since we want to know what happens if
|
||||
// it can't find an executable.
|
||||
final ProcessRunner processRunner = new ProcessRunner(subprocessOutput: false);
|
||||
final ProcessRunner processRunner = ProcessRunner(subprocessOutput: false);
|
||||
expect(
|
||||
expectAsync1((List<String> commandLine) async {
|
||||
return processRunner.runProcess(commandLine);
|
||||
@ -36,27 +36,27 @@ void main() {
|
||||
}
|
||||
});
|
||||
for (String platformName in <String>['macos', 'linux', 'windows']) {
|
||||
final FakePlatform platform = new FakePlatform(
|
||||
final FakePlatform platform = FakePlatform(
|
||||
operatingSystem: platformName,
|
||||
environment: <String, String>{},
|
||||
);
|
||||
group('ProcessRunner for $platform', () {
|
||||
test('Returns stdout', () async {
|
||||
final FakeProcessManager fakeProcessManager = new FakeProcessManager();
|
||||
final FakeProcessManager fakeProcessManager = FakeProcessManager();
|
||||
fakeProcessManager.fakeResults = <String, List<ProcessResult>>{
|
||||
'echo test': <ProcessResult>[new ProcessResult(0, 0, 'output', 'error')],
|
||||
'echo test': <ProcessResult>[ProcessResult(0, 0, 'output', 'error')],
|
||||
};
|
||||
final ProcessRunner processRunner = new ProcessRunner(
|
||||
final ProcessRunner processRunner = ProcessRunner(
|
||||
subprocessOutput: false, platform: platform, processManager: fakeProcessManager);
|
||||
final String output = await processRunner.runProcess(<String>['echo', 'test']);
|
||||
expect(output, equals('output'));
|
||||
});
|
||||
test('Throws on process failure', () async {
|
||||
final FakeProcessManager fakeProcessManager = new FakeProcessManager();
|
||||
final FakeProcessManager fakeProcessManager = FakeProcessManager();
|
||||
fakeProcessManager.fakeResults = <String, List<ProcessResult>>{
|
||||
'echo test': <ProcessResult>[new ProcessResult(0, -1, 'output', 'error')],
|
||||
'echo test': <ProcessResult>[ProcessResult(0, -1, 'output', 'error')],
|
||||
};
|
||||
final ProcessRunner processRunner = new ProcessRunner(
|
||||
final ProcessRunner processRunner = ProcessRunner(
|
||||
subprocessOutput: false, platform: platform, processManager: fakeProcessManager);
|
||||
expect(
|
||||
expectAsync1((List<String> commandLine) async {
|
||||
@ -75,17 +75,17 @@ void main() {
|
||||
String flutter;
|
||||
|
||||
Future<Uint8List> fakeHttpReader(Uri url, {Map<String, String> headers}) {
|
||||
return new Future<Uint8List>.value(new Uint8List(0));
|
||||
return Future<Uint8List>.value(Uint8List(0));
|
||||
}
|
||||
|
||||
setUp(() async {
|
||||
processManager = new FakeProcessManager();
|
||||
processManager = FakeProcessManager();
|
||||
args.clear();
|
||||
namedArgs.clear();
|
||||
tempDir = Directory.systemTemp.createTempSync('flutter_prepage_package_test.');
|
||||
flutterDir = new Directory(path.join(tempDir.path, 'flutter'));
|
||||
flutterDir = Directory(path.join(tempDir.path, 'flutter'));
|
||||
flutterDir.createSync(recursive: true);
|
||||
creator = new ArchiveCreator(
|
||||
creator = ArchiveCreator(
|
||||
tempDir,
|
||||
tempDir,
|
||||
testRef,
|
||||
@ -108,7 +108,7 @@ void main() {
|
||||
'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter': null,
|
||||
'git reset --hard $testRef': null,
|
||||
'git remote set-url origin https://github.com/flutter/flutter.git': null,
|
||||
'git describe --tags --abbrev=0': <ProcessResult>[new ProcessResult(0, 0, 'v1.2.3', '')],
|
||||
'git describe --tags --abbrev=0': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')],
|
||||
};
|
||||
if (platform.isWindows) {
|
||||
calls['7za x ${path.join(tempDir.path, 'mingit.zip')}'] = null;
|
||||
@ -151,7 +151,7 @@ void main() {
|
||||
'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter': null,
|
||||
'git reset --hard $testRef': null,
|
||||
'git remote set-url origin https://github.com/flutter/flutter.git': null,
|
||||
'git describe --tags --abbrev=0': <ProcessResult>[new ProcessResult(0, 0, 'v1.2.3', '')],
|
||||
'git describe --tags --abbrev=0': <ProcessResult>[ProcessResult(0, 0, 'v1.2.3', '')],
|
||||
};
|
||||
if (platform.isWindows) {
|
||||
calls['7za x ${path.join(tempDir.path, 'mingit.zip')}'] = null;
|
||||
@ -176,7 +176,7 @@ void main() {
|
||||
calls['tar cJf $archiveName flutter'] = null;
|
||||
}
|
||||
processManager.fakeResults = calls;
|
||||
creator = new ArchiveCreator(
|
||||
creator = ArchiveCreator(
|
||||
tempDir,
|
||||
tempDir,
|
||||
testRef,
|
||||
@ -194,8 +194,8 @@ void main() {
|
||||
test('throws when a command errors out', () async {
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter':
|
||||
<ProcessResult>[new ProcessResult(0, 0, 'output1', '')],
|
||||
'git reset --hard $testRef': <ProcessResult>[new ProcessResult(0, -1, 'output2', '')],
|
||||
<ProcessResult>[ProcessResult(0, 0, 'output1', '')],
|
||||
'git reset --hard $testRef': <ProcessResult>[ProcessResult(0, -1, 'output2', '')],
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
expect(expectAsync0(creator.initializeRepo),
|
||||
@ -208,7 +208,7 @@ void main() {
|
||||
Directory tempDir;
|
||||
|
||||
setUp(() async {
|
||||
processManager = new FakeProcessManager();
|
||||
processManager = FakeProcessManager();
|
||||
tempDir = Directory.systemTemp.createTempSync('flutter_prepage_package_test.');
|
||||
});
|
||||
|
||||
@ -255,7 +255,7 @@ void main() {
|
||||
]
|
||||
}
|
||||
''';
|
||||
new File(jsonPath).writeAsStringSync(releasesJson);
|
||||
File(jsonPath).writeAsStringSync(releasesJson);
|
||||
final Map<String, List<ProcessResult>> calls = <String, List<ProcessResult>>{
|
||||
'gsutil rm $gsArchivePath': null,
|
||||
'gsutil -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
|
||||
@ -264,9 +264,9 @@ void main() {
|
||||
'gsutil -h Content-Type:application/json cp $jsonPath $gsJsonPath': null,
|
||||
};
|
||||
processManager.fakeResults = calls;
|
||||
final File outputFile = new File(path.join(tempDir.absolute.path, archiveName));
|
||||
final File outputFile = File(path.join(tempDir.absolute.path, archiveName));
|
||||
assert(tempDir.existsSync());
|
||||
final ArchivePublisher publisher = new ArchivePublisher(
|
||||
final ArchivePublisher publisher = ArchivePublisher(
|
||||
tempDir,
|
||||
testRef,
|
||||
Branch.release,
|
||||
@ -279,7 +279,7 @@ void main() {
|
||||
assert(tempDir.existsSync());
|
||||
await publisher.publishArchive();
|
||||
processManager.verifyCalls(calls.keys.toList());
|
||||
final File releaseFile = new File(jsonPath);
|
||||
final File releaseFile = File(jsonPath);
|
||||
expect(releaseFile.existsSync(), isTrue);
|
||||
final String contents = releaseFile.readAsStringSync();
|
||||
// Make sure new data is added.
|
||||
@ -299,7 +299,7 @@ void main() {
|
||||
// Make sure the new entry is first (and hopefully it takes less than a
|
||||
// minute to go from publishArchive above to this line!).
|
||||
expect(
|
||||
new DateTime.now().difference(DateTime.parse(releases[0]['release_date'])),
|
||||
DateTime.now().difference(DateTime.parse(releases[0]['release_date'])),
|
||||
lessThan(const Duration(minutes: 1)),
|
||||
);
|
||||
const JsonEncoder encoder = JsonEncoder.withIndent(' ');
|
||||
|
@ -69,7 +69,7 @@ Future<Null> main(List<String> rawArgs) async {
|
||||
}
|
||||
|
||||
/// Command-line options for the `run.dart` command.
|
||||
final ArgParser _argParser = new ArgParser()
|
||||
final ArgParser _argParser = ArgParser()
|
||||
..addMultiOption(
|
||||
'task',
|
||||
abbr: 't',
|
||||
@ -89,7 +89,7 @@ final ArgParser _argParser = new ArgParser()
|
||||
_taskNames.add(nameOrPath);
|
||||
} else if (!isDartFile || fragments.length != 3 || !_listsEqual(<String>['bin', 'tasks'], fragments.take(2).toList())) {
|
||||
// Unsupported executable location
|
||||
throw new FormatException('Invalid value for option -t (--task): $nameOrPath');
|
||||
throw FormatException('Invalid value for option -t (--task): $nameOrPath');
|
||||
} else {
|
||||
_taskNames.add(path.withoutExtension(fragments.last));
|
||||
}
|
||||
|
@ -21,14 +21,14 @@ void main() {
|
||||
await device.unlock();
|
||||
final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
||||
await inDirectory(appDir, () async {
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
bool ok;
|
||||
print('run: starting...');
|
||||
final Process run = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
<String>['run', '--verbose', '-d', device.deviceId, 'lib/commands.dart'],
|
||||
);
|
||||
final StreamController<String> stdout = new StreamController<String>.broadcast();
|
||||
final StreamController<String> stdout = StreamController<String>.broadcast();
|
||||
run.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
@ -56,9 +56,9 @@ void main() {
|
||||
if (!ok)
|
||||
throw 'Failed to run test app.';
|
||||
|
||||
final VMServiceClient client = new VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
final VMServiceClient client = VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
|
||||
final DriveHelper driver = new DriveHelper(vmServicePort);
|
||||
final DriveHelper driver = DriveHelper(vmServicePort);
|
||||
|
||||
await driver.drive('none');
|
||||
print('test: pressing "p" to enable debugPaintSize...');
|
||||
@ -98,7 +98,7 @@ void main() {
|
||||
print('test: validating that the app has in fact closed...');
|
||||
await client.done.timeout(const Duration(seconds: 5));
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import 'package:flutter_devicelab/tasks/perf_tests.dart';
|
||||
|
||||
Future<Null> main() async {
|
||||
deviceOperatingSystem = DeviceOperatingSystem.android;
|
||||
await task(new MemoryTest(
|
||||
await task(MemoryTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
||||
'test_memory/scroll_perf.dart',
|
||||
'com.yourcompany.complexLayout',
|
||||
|
@ -31,7 +31,7 @@ void main() {
|
||||
});
|
||||
|
||||
final String dataPath = p.join(complexLayoutPath, 'build', 'complex_layout_semantics_perf.json');
|
||||
return new TaskResult.successFromFile(file(dataPath), benchmarkScoreKeys: <String>[
|
||||
return TaskResult.successFromFile(file(dataPath), benchmarkScoreKeys: <String>[
|
||||
'initialSemanticsTreeCreation',
|
||||
]);
|
||||
});
|
||||
|
@ -12,7 +12,7 @@ import 'package:path/path.dart' as path;
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(() async {
|
||||
final Stopwatch clock = new Stopwatch()..start();
|
||||
final Stopwatch clock = Stopwatch()..start();
|
||||
final Process analysis = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
<String>['analyze', '--no-preamble', '--no-congratulate', '--flutter-repo', '--dartdocs'],
|
||||
@ -47,16 +47,16 @@ Future<Null> main() async {
|
||||
final int result = await analysis.exitCode;
|
||||
clock.stop();
|
||||
if (publicMembers == 0 && otherErrors == 0 && result != 0)
|
||||
throw new Exception('flutter analyze exited with unexpected error code $result');
|
||||
throw Exception('flutter analyze exited with unexpected error code $result');
|
||||
if (publicMembers != 0 && otherErrors != 0 && result == 0)
|
||||
throw new Exception('flutter analyze exited with successful status code despite reporting errors');
|
||||
throw Exception('flutter analyze exited with successful status code despite reporting errors');
|
||||
if (otherLines != 0)
|
||||
throw new Exception('flutter analyze had unexpected output (we saw $otherLines unexpected line${ otherLines == 1 ? "" : "s" })');
|
||||
throw Exception('flutter analyze had unexpected output (we saw $otherLines unexpected line${ otherLines == 1 ? "" : "s" })');
|
||||
final Map<String, dynamic> data = <String, dynamic>{
|
||||
'members_missing_dartdocs': publicMembers,
|
||||
'analysis_errors': otherErrors,
|
||||
'elapsed_time_ms': clock.elapsedMilliseconds,
|
||||
};
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
return TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
});
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import 'package:flutter_devicelab/framework/utils.dart';
|
||||
|
||||
Future<void> testReload(Process process, { Future<void> Function() onListening }) async {
|
||||
section('Testing hot reload, restart and quit');
|
||||
final Completer<Null> listening = new Completer<Null>();
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> reloaded = new Completer<Null>();
|
||||
final Completer<Null> restarted = new Completer<Null>();
|
||||
final Completer<Null> finished = new Completer<Null>();
|
||||
final Completer<Null> listening = Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
final Completer<Null> reloaded = Completer<Null>();
|
||||
final Completer<Null> restarted = Completer<Null>();
|
||||
final Completer<Null> finished = Completer<Null>();
|
||||
final List<String> stdout = <String>[];
|
||||
final List<String> stderr = <String>[];
|
||||
|
||||
@ -96,7 +96,7 @@ void main() {
|
||||
<String>['--suppress-analytics', 'build', 'apk', '--debug', 'lib/main.dart'],
|
||||
);
|
||||
final String lastLine = buildStdout.split('\n').last;
|
||||
final RegExp builtRegExp = new RegExp(r'Built (.+)( \(|\.$)');
|
||||
final RegExp builtRegExp = RegExp(r'Built (.+)( \(|\.$)');
|
||||
final String apkPath = builtRegExp.firstMatch(lastLine)[1];
|
||||
|
||||
section('Installing $apkPath');
|
||||
@ -116,7 +116,7 @@ void main() {
|
||||
});
|
||||
|
||||
// Give the device the time to really shut down the app.
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 200));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 200));
|
||||
// After the delay, force-stopping it shouldn't do anything, but doesn't hurt.
|
||||
await device.shellExec('am', <String>['force-stop', kAppId]);
|
||||
|
||||
@ -128,7 +128,7 @@ void main() {
|
||||
// If the next line fails, your device may not support regexp search.
|
||||
final String observatoryLine = await device.adb(<String>['logcat', '-e', 'Observatory listening on http:', '-m', '1', '-T', currentTime]);
|
||||
print('Found observatory line: $observatoryLine');
|
||||
final String observatoryPort = new RegExp(r'Observatory listening on http://.*:([0-9]+)').firstMatch(observatoryLine)[1];
|
||||
final String observatoryPort = RegExp(r'Observatory listening on http://.*:([0-9]+)').firstMatch(observatoryLine)[1];
|
||||
print('Extracted observatory port: $observatoryPort');
|
||||
|
||||
section('Launching attach with given port');
|
||||
@ -144,6 +144,6 @@ void main() {
|
||||
await device.adb(<String>['uninstall', kAppId]);
|
||||
}
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class BackButtonMemoryTest extends MemoryTest {
|
||||
await receivedNextMessage;
|
||||
|
||||
// Give Android time to settle (e.g. run GCs) after closing the app.
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
// Relaunch the app, wait for it to launch.
|
||||
prepareForNextMessage('READY');
|
||||
@ -46,7 +46,7 @@ class BackButtonMemoryTest extends MemoryTest {
|
||||
await receivedNextMessage;
|
||||
|
||||
// Wait for the Flutter app to settle (e.g. run GCs).
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
}
|
||||
await recordEnd();
|
||||
}
|
||||
@ -54,5 +54,5 @@ class BackButtonMemoryTest extends MemoryTest {
|
||||
|
||||
Future<Null> main() async {
|
||||
deviceOperatingSystem = DeviceOperatingSystem.android;
|
||||
await task(new BackButtonMemoryTest().run);
|
||||
await task(BackButtonMemoryTest().run);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/utils.dart';
|
||||
import 'package:flutter_devicelab/tasks/perf_tests.dart';
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(new MemoryTest(
|
||||
await task(MemoryTest(
|
||||
'${flutterDirectory.path}/examples/flutter_gallery',
|
||||
'test_memory/memory_nav.dart',
|
||||
'io.flutter.demo.gallery',
|
||||
|
@ -24,6 +24,6 @@ Future<Null> main() async {
|
||||
benchmarkScoreKeys.add(deltaKey);
|
||||
}
|
||||
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: benchmarkScoreKeys);
|
||||
return TaskResult.success(data, benchmarkScoreKeys: benchmarkScoreKeys);
|
||||
});
|
||||
}
|
||||
|
@ -30,6 +30,6 @@ Future<Null> main() async {
|
||||
});
|
||||
});
|
||||
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
|
||||
// Matches the output of the "test" package, e.g.: "00:01 +1 loading foo"
|
||||
final RegExp testOutputPattern = new RegExp(r'^[0-9][0-9]:[0-9][0-9] \+[0-9]+: (.+?) *$');
|
||||
final RegExp testOutputPattern = RegExp(r'^[0-9][0-9]:[0-9][0-9] \+[0-9]+: (.+?) *$');
|
||||
|
||||
enum TestStep {
|
||||
starting,
|
||||
@ -37,7 +37,7 @@ enum TestStep {
|
||||
}
|
||||
|
||||
Future<int> runTest() async {
|
||||
final Stopwatch clock = new Stopwatch()..start();
|
||||
final Stopwatch clock = Stopwatch()..start();
|
||||
final Process analysis = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
<String>['test', path.join('flutter_test', 'trivial_widget_test.dart')],
|
||||
@ -83,18 +83,18 @@ Future<int> runTest() async {
|
||||
final int result = await analysis.exitCode;
|
||||
clock.stop();
|
||||
if (result != 0)
|
||||
throw new Exception('flutter test failed with exit code $result');
|
||||
throw Exception('flutter test failed with exit code $result');
|
||||
if (badLines > 0)
|
||||
throw new Exception('flutter test renderered unexpected output ($badLines bad lines)');
|
||||
throw Exception('flutter test renderered unexpected output ($badLines bad lines)');
|
||||
if (step != TestStep.testPassed)
|
||||
throw new Exception('flutter test did not finish (only reached step $step)');
|
||||
throw Exception('flutter test did not finish (only reached step $step)');
|
||||
print('elapsed time: ${clock.elapsedMilliseconds}ms');
|
||||
return clock.elapsedMilliseconds;
|
||||
}
|
||||
|
||||
void main() {
|
||||
task(() async {
|
||||
final File nodeSourceFile = new File(path.join(
|
||||
final File nodeSourceFile = File(path.join(
|
||||
flutterDirectory.path, 'packages', 'flutter', 'lib', 'src', 'foundation', 'node.dart',
|
||||
));
|
||||
final String originalSource = await nodeSourceFile.readAsString();
|
||||
@ -118,7 +118,7 @@ void main() {
|
||||
'implementation_change_elapsed_time_ms': implementationChange,
|
||||
'interface_change_elapsed_time_ms': interfaceChange,
|
||||
};
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
return TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
} finally {
|
||||
await nodeSourceFile.writeAsString(originalSource);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ Future<void> main() async {
|
||||
|
||||
javaHome = await findJavaHome();
|
||||
if (javaHome == null)
|
||||
return new TaskResult.failure('Could not find Java');
|
||||
return TaskResult.failure('Could not find Java');
|
||||
print('\nUsing JAVA_HOME=$javaHome');
|
||||
|
||||
try {
|
||||
@ -51,7 +51,7 @@ Future<void> main() async {
|
||||
await project.runGradleTask('assembleDebug');
|
||||
errorMessage = _validateSnapshotDependency(project, 'build/app.dill');
|
||||
if (errorMessage != null) {
|
||||
throw new TaskResult.failure(errorMessage);
|
||||
throw TaskResult.failure(errorMessage);
|
||||
}
|
||||
});
|
||||
|
||||
@ -125,15 +125,15 @@ Future<void> main() async {
|
||||
section('gradlew assembleDebug on plugin example');
|
||||
await pluginProject.runGradleTask('assembleDebug');
|
||||
if (!pluginProject.hasDebugApk)
|
||||
throw new TaskResult.failure(
|
||||
throw TaskResult.failure(
|
||||
'Gradle did not produce an apk file at the expected place');
|
||||
});
|
||||
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
} on TaskResult catch (taskResult) {
|
||||
return taskResult;
|
||||
} catch (e) {
|
||||
return new TaskResult.failure(e.toString());
|
||||
return TaskResult.failure(e.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -143,7 +143,7 @@ TaskResult _failure(String message, ProcessResult result) {
|
||||
print('Exit code: ${result.exitCode}');
|
||||
print('Std out :\n${result.stdout}');
|
||||
print('Std err :\n${result.stderr}');
|
||||
return new TaskResult.failure(message);
|
||||
return TaskResult.failure(message);
|
||||
}
|
||||
|
||||
bool _hasMultipleOccurrences(String text, Pattern pattern) {
|
||||
@ -160,14 +160,14 @@ class FlutterProject {
|
||||
await inDirectory(directory, () async {
|
||||
await flutter('create', options: <String>[name]);
|
||||
});
|
||||
return new FlutterProject(directory, name);
|
||||
return FlutterProject(directory, name);
|
||||
}
|
||||
|
||||
String get rootPath => path.join(parent.path, name);
|
||||
String get androidPath => path.join(rootPath, 'android');
|
||||
|
||||
Future<Null> addCustomBuildType(String name, {String initWith}) async {
|
||||
final File buildScript = new File(
|
||||
final File buildScript = File(
|
||||
path.join(androidPath, 'app', 'build.gradle'),
|
||||
);
|
||||
|
||||
@ -184,7 +184,7 @@ android {
|
||||
}
|
||||
|
||||
Future<Null> addProductFlavor(String name) async {
|
||||
final File buildScript = new File(
|
||||
final File buildScript = File(
|
||||
path.join(androidPath, 'app', 'build.gradle'),
|
||||
);
|
||||
|
||||
@ -203,7 +203,7 @@ android {
|
||||
}
|
||||
|
||||
Future<Null> introduceError() async {
|
||||
final File buildScript = new File(
|
||||
final File buildScript = File(
|
||||
path.join(androidPath, 'app', 'build.gradle'),
|
||||
);
|
||||
await buildScript.writeAsString((await buildScript.readAsString()).replaceAll('buildTypes', 'builTypes'));
|
||||
@ -236,7 +236,7 @@ class FlutterPluginProject {
|
||||
await inDirectory(directory, () async {
|
||||
await flutter('create', options: <String>['-t', 'plugin', name]);
|
||||
});
|
||||
return new FlutterPluginProject(directory, name);
|
||||
return FlutterPluginProject(directory, name);
|
||||
}
|
||||
|
||||
String get rootPath => path.join(parent.path, name);
|
||||
@ -248,7 +248,7 @@ class FlutterPluginProject {
|
||||
return _runGradleTask(workingDirectory: exampleAndroidPath, task: task, options: options);
|
||||
}
|
||||
|
||||
bool get hasDebugApk => new File(debugApkPath).existsSync();
|
||||
bool get hasDebugApk => File(debugApkPath).existsSync();
|
||||
}
|
||||
|
||||
Future<Null> _runGradleTask({String workingDirectory, String task, List<String> options}) async {
|
||||
@ -284,12 +284,12 @@ class _Dependencies {
|
||||
String target;
|
||||
Set<String> dependencies;
|
||||
_Dependencies(String depfilePath) {
|
||||
final RegExp _separatorExpr = new RegExp(r'([^\\]) ');
|
||||
final RegExp _escapeExpr = new RegExp(r'\\(.)');
|
||||
final RegExp _separatorExpr = RegExp(r'([^\\]) ');
|
||||
final RegExp _escapeExpr = RegExp(r'\\(.)');
|
||||
|
||||
// Depfile format:
|
||||
// outfile1 outfile2 : file1.dart file2.dart file3.dart file\ 4.dart
|
||||
final String contents = new File(depfilePath).readAsStringSync();
|
||||
final String contents = File(depfilePath).readAsStringSync();
|
||||
final List<String> colonSeparated = contents.split(': ');
|
||||
target = colonSeparated[0].trim();
|
||||
dependencies = colonSeparated[1]
|
||||
@ -305,7 +305,7 @@ class _Dependencies {
|
||||
|
||||
/// Returns [null] if target matches [expectedTarget], otherwise returns an error message.
|
||||
String _validateSnapshotDependency(FlutterProject project, String expectedTarget) {
|
||||
final _Dependencies deps = new _Dependencies(
|
||||
final _Dependencies deps = _Dependencies(
|
||||
path.join(project.rootPath, 'build', 'app', 'intermediates',
|
||||
'flutter', 'debug', 'snapshot_blob.bin.d'));
|
||||
return deps.target == expectedTarget ? null :
|
||||
|
@ -27,13 +27,13 @@ class HelloWorldMemoryTest extends MemoryTest {
|
||||
'-d', device.deviceId,
|
||||
test,
|
||||
]);
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 1500));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 1500));
|
||||
await recordStart();
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 3000));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 3000));
|
||||
await recordEnd();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(new HelloWorldMemoryTest().run);
|
||||
await task(HelloWorldMemoryTest().run);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ Future<Null> main() async {
|
||||
|
||||
final String javaHome = await findJavaHome();
|
||||
if (javaHome == null)
|
||||
return new TaskResult.failure('Could not find Java');
|
||||
return TaskResult.failure('Could not find Java');
|
||||
print('\nUsing JAVA_HOME=$javaHome');
|
||||
|
||||
section('Create Flutter module project');
|
||||
@ -34,14 +34,14 @@ Future<Null> main() async {
|
||||
|
||||
section('Add plugins');
|
||||
|
||||
final File pubspec = new File(path.join(tempDir.path, 'hello', 'pubspec.yaml'));
|
||||
final File pubspec = File(path.join(tempDir.path, 'hello', 'pubspec.yaml'));
|
||||
String content = await pubspec.readAsString();
|
||||
content = content.replaceFirst(
|
||||
'\ndependencies:\n',
|
||||
'\ndependencies:\n battery:\n package_info:\n',
|
||||
);
|
||||
await pubspec.writeAsString(content, flush: true);
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await flutter(
|
||||
'packages',
|
||||
options: <String>['get'],
|
||||
@ -50,7 +50,7 @@ Future<Null> main() async {
|
||||
|
||||
section('Build Flutter module library archive');
|
||||
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello', '.android')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello', '.android')), () async {
|
||||
await exec(
|
||||
'./gradlew',
|
||||
<String>['flutter:assembleDebug'],
|
||||
@ -58,7 +58,7 @@ Future<Null> main() async {
|
||||
);
|
||||
});
|
||||
|
||||
final bool aarBuilt = exists(new File(path.join(
|
||||
final bool aarBuilt = exists(File(path.join(
|
||||
tempDir.path,
|
||||
'hello',
|
||||
'.android',
|
||||
@ -70,19 +70,19 @@ Future<Null> main() async {
|
||||
)));
|
||||
|
||||
if (!aarBuilt) {
|
||||
return new TaskResult.failure('Failed to build .aar');
|
||||
return TaskResult.failure('Failed to build .aar');
|
||||
}
|
||||
|
||||
section('Build ephemeral host app');
|
||||
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await flutter(
|
||||
'build',
|
||||
options: <String>['apk'],
|
||||
);
|
||||
});
|
||||
|
||||
final bool ephemeralHostApkBuilt = exists(new File(path.join(
|
||||
final bool ephemeralHostApkBuilt = exists(File(path.join(
|
||||
tempDir.path,
|
||||
'hello',
|
||||
'build',
|
||||
@ -94,18 +94,18 @@ Future<Null> main() async {
|
||||
)));
|
||||
|
||||
if (!ephemeralHostApkBuilt) {
|
||||
return new TaskResult.failure('Failed to build ephemeral host .apk');
|
||||
return TaskResult.failure('Failed to build ephemeral host .apk');
|
||||
}
|
||||
|
||||
section('Clean build');
|
||||
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await flutter('clean');
|
||||
});
|
||||
|
||||
section('Materialize host app');
|
||||
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await flutter(
|
||||
'materialize',
|
||||
options: <String>['android'],
|
||||
@ -114,14 +114,14 @@ Future<Null> main() async {
|
||||
|
||||
section('Build materialized host app');
|
||||
|
||||
await inDirectory(new Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await inDirectory(Directory(path.join(tempDir.path, 'hello')), () async {
|
||||
await flutter(
|
||||
'build',
|
||||
options: <String>['apk'],
|
||||
);
|
||||
});
|
||||
|
||||
final bool materializedHostApkBuilt = exists(new File(path.join(
|
||||
final bool materializedHostApkBuilt = exists(File(path.join(
|
||||
tempDir.path,
|
||||
'hello',
|
||||
'build',
|
||||
@ -133,24 +133,24 @@ Future<Null> main() async {
|
||||
)));
|
||||
|
||||
if (!materializedHostApkBuilt) {
|
||||
return new TaskResult.failure('Failed to build materialized host .apk');
|
||||
return TaskResult.failure('Failed to build materialized host .apk');
|
||||
}
|
||||
|
||||
section('Add to Android app');
|
||||
|
||||
final Directory hostApp = new Directory(path.join(tempDir.path, 'hello_host_app'));
|
||||
final Directory hostApp = Directory(path.join(tempDir.path, 'hello_host_app'));
|
||||
mkdir(hostApp);
|
||||
recursiveCopy(
|
||||
new Directory(path.join(flutterDirectory.path, 'dev', 'integration_tests', 'android_host_app')),
|
||||
Directory(path.join(flutterDirectory.path, 'dev', 'integration_tests', 'android_host_app')),
|
||||
hostApp,
|
||||
);
|
||||
copy(
|
||||
new File(path.join(tempDir.path, 'hello', '.android', 'gradlew')),
|
||||
File(path.join(tempDir.path, 'hello', '.android', 'gradlew')),
|
||||
hostApp,
|
||||
);
|
||||
copy(
|
||||
new File(path.join(tempDir.path, 'hello', '.android', 'gradle', 'wrapper', 'gradle-wrapper.jar')),
|
||||
new Directory(path.join(hostApp.path, 'gradle', 'wrapper')),
|
||||
File(path.join(tempDir.path, 'hello', '.android', 'gradle', 'wrapper', 'gradle-wrapper.jar')),
|
||||
Directory(path.join(hostApp.path, 'gradle', 'wrapper')),
|
||||
);
|
||||
|
||||
await inDirectory(hostApp, () async {
|
||||
@ -161,7 +161,7 @@ Future<Null> main() async {
|
||||
);
|
||||
});
|
||||
|
||||
final bool existingAppBuilt = exists(new File(path.join(
|
||||
final bool existingAppBuilt = exists(File(path.join(
|
||||
hostApp.path,
|
||||
'app',
|
||||
'build',
|
||||
@ -172,11 +172,11 @@ Future<Null> main() async {
|
||||
)));
|
||||
|
||||
if (!existingAppBuilt) {
|
||||
return new TaskResult.failure('Failed to build existing app .apk');
|
||||
return TaskResult.failure('Failed to build existing app .apk');
|
||||
}
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
} catch (e) {
|
||||
return new TaskResult.failure(e.toString());
|
||||
return TaskResult.failure(e.toString());
|
||||
} finally {
|
||||
rmTree(tempDir);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(combine(<TaskFunction>[
|
||||
new PluginTest('apk', <String>['-a', 'java']),
|
||||
new PluginTest('apk', <String>['-a', 'kotlin']),
|
||||
PluginTest('apk', <String>['-a', 'java']),
|
||||
PluginTest('apk', <String>['-a', 'kotlin']),
|
||||
]));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(combine(<TaskFunction>[
|
||||
new PluginTest('ios', <String>['-i', 'objc']),
|
||||
new PluginTest('ios', <String>['-i', 'swift']),
|
||||
PluginTest('ios', <String>['-i', 'objc']),
|
||||
PluginTest('ios', <String>['-i', 'swift']),
|
||||
]));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(combine(<TaskFunction>[
|
||||
new PluginTest('apk', <String>['-a', 'java']),
|
||||
new PluginTest('apk', <String>['-a', 'kotlin']),
|
||||
PluginTest('apk', <String>['-a', 'java']),
|
||||
PluginTest('apk', <String>['-a', 'kotlin']),
|
||||
]));
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ void main() {
|
||||
});
|
||||
section('TEST WHETHER `flutter run --route` WORKS');
|
||||
await inDirectory(appDir, () async {
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
bool ok;
|
||||
print('run: starting...');
|
||||
final Process run = await startProcess(
|
||||
@ -86,6 +86,6 @@ void main() {
|
||||
if (result != 0)
|
||||
throw 'Received unexpected exit code $result from run process.';
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ void main() {
|
||||
final Directory appDir =
|
||||
dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
||||
await inDirectory(appDir, () async {
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
bool ok;
|
||||
print('run: starting...');
|
||||
final Process run = await startProcess(
|
||||
@ -54,7 +54,7 @@ void main() {
|
||||
],
|
||||
);
|
||||
final StreamController<String> stdout =
|
||||
new StreamController<String>.broadcast();
|
||||
StreamController<String>.broadcast();
|
||||
transformToLines(run.stdout).listen((String line) {
|
||||
print('run:stdout: $line');
|
||||
stdout.add(line);
|
||||
@ -80,14 +80,14 @@ void main() {
|
||||
throw 'Failed to run test app.';
|
||||
|
||||
final VMServiceClient client =
|
||||
new VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
|
||||
int id = 1;
|
||||
Future<Map<String, dynamic>> sendRequest(
|
||||
String method, dynamic params) async {
|
||||
final int requestId = id++;
|
||||
final Completer<Map<String, dynamic>> response =
|
||||
new Completer<Map<String, dynamic>>();
|
||||
Completer<Map<String, dynamic>>();
|
||||
final StreamSubscription<String> responseSubscription =
|
||||
stdout.stream.listen((String line) {
|
||||
final Map<String, dynamic> json = parseFlutterResponse(line);
|
||||
@ -150,6 +150,6 @@ void main() {
|
||||
print('test: validating that the app has in fact closed...');
|
||||
await client.done.timeout(const Duration(seconds: 5));
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ void main() {
|
||||
await device.unlock();
|
||||
final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
||||
await inDirectory(appDir, () async {
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
print('run: starting...');
|
||||
final Process run = await startProcess(
|
||||
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
||||
@ -76,6 +76,6 @@ void main() {
|
||||
'${stdout.join('\n')}';
|
||||
}
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ void main() {
|
||||
await device.unlock();
|
||||
final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
||||
await inDirectory(appDir, () async {
|
||||
final Completer<Null> ready = new Completer<Null>();
|
||||
final Completer<Null> ready = Completer<Null>();
|
||||
bool ok;
|
||||
print('run: starting...');
|
||||
final Process run = await startProcess(
|
||||
@ -54,7 +54,7 @@ void main() {
|
||||
if (!ok)
|
||||
throw 'Failed to run test app.';
|
||||
|
||||
final VMServiceClient client = new VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
final VMServiceClient client = VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
|
||||
final VM vm = await client.getVM();
|
||||
final VMIsolateRef isolate = vm.isolates.first;
|
||||
final Stream<VMExtensionEvent> frameEvents = isolate.onExtensionEvent.where(
|
||||
@ -82,7 +82,7 @@ void main() {
|
||||
if (result != 0)
|
||||
throw 'Received unexpected exit code $result from run process.';
|
||||
});
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,6 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
/// Smoke test of a task that fails by returning an unsuccessful response.
|
||||
Future<Null> main() async {
|
||||
await task(() async {
|
||||
return new TaskResult.failure('Failed');
|
||||
return TaskResult.failure('Failed');
|
||||
});
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
||||
/// Smoke test of a successful task.
|
||||
Future<Null> main() async {
|
||||
await task(() async {
|
||||
return new TaskResult.success(<String, dynamic>{});
|
||||
return TaskResult.success(<String, dynamic>{});
|
||||
});
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ const double skipCost = 2473.0; // 20 hours: 5 to fix the issue we're ignoring,
|
||||
const double ignoreForFileCost = 2477.0; // similar thinking as skipCost
|
||||
const double asDynamicCost = 2003.0; // same as ignoring analyzer warning
|
||||
|
||||
final RegExp todoPattern = new RegExp(r'(?://|#) *TODO');
|
||||
final RegExp ignorePattern = new RegExp(r'// *ignore:');
|
||||
final RegExp ignoreForFilePattern = new RegExp(r'// *ignore_for_file:');
|
||||
final RegExp asDynamicPattern = new RegExp(r'as dynamic');
|
||||
final RegExp todoPattern = RegExp(r'(?://|#) *TODO');
|
||||
final RegExp ignorePattern = RegExp(r'// *ignore:');
|
||||
final RegExp ignoreForFilePattern = RegExp(r'// *ignore_for_file:');
|
||||
final RegExp asDynamicPattern = RegExp(r'as dynamic');
|
||||
|
||||
Future<double> findCostsForFile(File file) async {
|
||||
if (path.extension(file.path) == '.py')
|
||||
@ -55,10 +55,10 @@ Future<double> findCostsForRepo() async {
|
||||
);
|
||||
double total = 0.0;
|
||||
await for (String entry in git.stdout.transform(utf8.decoder).transform(const LineSplitter()))
|
||||
total += await findCostsForFile(new File(path.join(flutterDirectory.path, entry)));
|
||||
total += await findCostsForFile(File(path.join(flutterDirectory.path, entry)));
|
||||
final int gitExitCode = await git.exitCode;
|
||||
if (gitExitCode != 0)
|
||||
throw new Exception('git exit with unexpected error code $gitExitCode');
|
||||
throw Exception('git exit with unexpected error code $gitExitCode');
|
||||
return total;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ Future<int> countDependencies() async {
|
||||
)).split('\n');
|
||||
final int count = lines.where((String line) => line.contains('->')).length;
|
||||
if (count < 2) // we'll always have flutter and flutter_test, at least...
|
||||
throw new Exception('"flutter update-packages --transitive-closure" returned bogus output:\n${lines.join("\n")}');
|
||||
throw Exception('"flutter update-packages --transitive-closure" returned bogus output:\n${lines.join("\n")}');
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ const String _kNumberOfDependenciesKey = 'dependencies_count';
|
||||
|
||||
Future<Null> main() async {
|
||||
await task(() async {
|
||||
return new TaskResult.success(
|
||||
return TaskResult.success(
|
||||
<String, dynamic>{
|
||||
_kCostBenchmarkKey: await findCostsForRepo(),
|
||||
_kNumberOfDependenciesKey: await countDependencies(),
|
||||
|
@ -13,7 +13,7 @@ import 'package:path/path.dart' as path;
|
||||
import 'utils.dart';
|
||||
|
||||
/// The root of the API for controlling devices.
|
||||
DeviceDiscovery get devices => new DeviceDiscovery();
|
||||
DeviceDiscovery get devices => DeviceDiscovery();
|
||||
|
||||
/// Device operating system the test is configured to test.
|
||||
enum DeviceOperatingSystem { android, ios }
|
||||
@ -26,11 +26,11 @@ abstract class DeviceDiscovery {
|
||||
factory DeviceDiscovery() {
|
||||
switch (deviceOperatingSystem) {
|
||||
case DeviceOperatingSystem.android:
|
||||
return new AndroidDeviceDiscovery();
|
||||
return AndroidDeviceDiscovery();
|
||||
case DeviceOperatingSystem.ios:
|
||||
return new IosDeviceDiscovery();
|
||||
return IosDeviceDiscovery();
|
||||
default:
|
||||
throw new StateError('Unsupported device operating system: {config.deviceOperatingSystem}');
|
||||
throw StateError('Unsupported device operating system: {config.deviceOperatingSystem}');
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,12 +103,12 @@ class AndroidDeviceDiscovery implements DeviceDiscovery {
|
||||
// Parses information about a device. Example:
|
||||
//
|
||||
// 015d172c98400a03 device usb:340787200X product:nakasi model:Nexus_7 device:grouper
|
||||
static final RegExp _kDeviceRegex = new RegExp(r'^(\S+)\s+(\S+)(.*)');
|
||||
static final RegExp _kDeviceRegex = RegExp(r'^(\S+)\s+(\S+)(.*)');
|
||||
|
||||
static AndroidDeviceDiscovery _instance;
|
||||
|
||||
factory AndroidDeviceDiscovery() {
|
||||
return _instance ??= new AndroidDeviceDiscovery._();
|
||||
return _instance ??= AndroidDeviceDiscovery._();
|
||||
}
|
||||
|
||||
AndroidDeviceDiscovery._();
|
||||
@ -129,14 +129,14 @@ class AndroidDeviceDiscovery implements DeviceDiscovery {
|
||||
@override
|
||||
Future<Null> chooseWorkingDevice() async {
|
||||
final List<Device> allDevices = (await discoverDevices())
|
||||
.map((String id) => new AndroidDevice(deviceId: id))
|
||||
.map((String id) => AndroidDevice(deviceId: id))
|
||||
.toList();
|
||||
|
||||
if (allDevices.isEmpty)
|
||||
throw 'No Android devices detected';
|
||||
|
||||
// TODO(yjbanov): filter out and warn about those with low battery level
|
||||
_workingDevice = allDevices[new math.Random().nextInt(allDevices.length)];
|
||||
_workingDevice = allDevices[math.Random().nextInt(allDevices.length)];
|
||||
}
|
||||
|
||||
@override
|
||||
@ -174,13 +174,13 @@ class AndroidDeviceDiscovery implements DeviceDiscovery {
|
||||
final Map<String, HealthCheckResult> results = <String, HealthCheckResult>{};
|
||||
for (String deviceId in await discoverDevices()) {
|
||||
try {
|
||||
final AndroidDevice device = new AndroidDevice(deviceId: deviceId);
|
||||
final AndroidDevice device = AndroidDevice(deviceId: deviceId);
|
||||
// Just a smoke test that we can read wakefulness state
|
||||
// TODO(yjbanov): check battery level
|
||||
await device._getWakefulness();
|
||||
results['android-device-$deviceId'] = new HealthCheckResult.success();
|
||||
results['android-device-$deviceId'] = HealthCheckResult.success();
|
||||
} catch (e, s) {
|
||||
results['android-device-$deviceId'] = new HealthCheckResult.error(e, s);
|
||||
results['android-device-$deviceId'] = HealthCheckResult.error(e, s);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
@ -278,7 +278,7 @@ class AndroidDevice implements Device {
|
||||
@override
|
||||
Future<Map<String, dynamic>> getMemoryStats(String packageName) async {
|
||||
final String meminfo = await shellEval('dumpsys', <String>['meminfo', packageName]);
|
||||
final Match match = new RegExp(r'TOTAL\s+(\d+)').firstMatch(meminfo);
|
||||
final Match match = RegExp(r'TOTAL\s+(\d+)').firstMatch(meminfo);
|
||||
assert(match != null, 'could not parse dumpsys meminfo output');
|
||||
return <String, dynamic>{
|
||||
'total_kb': int.parse(match.group(1)),
|
||||
@ -287,13 +287,13 @@ class AndroidDevice implements Device {
|
||||
|
||||
@override
|
||||
Stream<String> get logcat {
|
||||
final Completer<void> stdoutDone = new Completer<void>();
|
||||
final Completer<void> stderrDone = new Completer<void>();
|
||||
final Completer<void> processDone = new Completer<void>();
|
||||
final Completer<void> abort = new Completer<void>();
|
||||
final Completer<void> stdoutDone = Completer<void>();
|
||||
final Completer<void> stderrDone = Completer<void>();
|
||||
final Completer<void> processDone = Completer<void>();
|
||||
final Completer<void> abort = Completer<void>();
|
||||
bool aborted = false;
|
||||
StreamController<String> stream;
|
||||
stream = new StreamController<String>(
|
||||
stream = StreamController<String>(
|
||||
onListen: () async {
|
||||
await adb(<String>['logcat', '--clear']);
|
||||
final Process process = await startProcess(adbPath, <String>['-s', deviceId, 'logcat']);
|
||||
@ -353,7 +353,7 @@ class IosDeviceDiscovery implements DeviceDiscovery {
|
||||
static IosDeviceDiscovery _instance;
|
||||
|
||||
factory IosDeviceDiscovery() {
|
||||
return _instance ??= new IosDeviceDiscovery._();
|
||||
return _instance ??= IosDeviceDiscovery._();
|
||||
}
|
||||
|
||||
IosDeviceDiscovery._();
|
||||
@ -374,14 +374,14 @@ class IosDeviceDiscovery implements DeviceDiscovery {
|
||||
@override
|
||||
Future<Null> chooseWorkingDevice() async {
|
||||
final List<IosDevice> allDevices = (await discoverDevices())
|
||||
.map((String id) => new IosDevice(deviceId: id))
|
||||
.map((String id) => IosDevice(deviceId: id))
|
||||
.toList();
|
||||
|
||||
if (allDevices.isEmpty)
|
||||
throw 'No iOS devices detected';
|
||||
|
||||
// TODO(yjbanov): filter out and warn about those with low battery level
|
||||
_workingDevice = allDevices[new math.Random().nextInt(allDevices.length)];
|
||||
_workingDevice = allDevices[math.Random().nextInt(allDevices.length)];
|
||||
}
|
||||
|
||||
@override
|
||||
@ -400,7 +400,7 @@ class IosDeviceDiscovery implements DeviceDiscovery {
|
||||
final Map<String, HealthCheckResult> results = <String, HealthCheckResult>{};
|
||||
for (String deviceId in await discoverDevices()) {
|
||||
// TODO(ianh): do a more meaningful connectivity check than just recording the ID
|
||||
results['ios-device-$deviceId'] = new HealthCheckResult.success();
|
||||
results['ios-device-$deviceId'] = HealthCheckResult.success();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ bool _isTaskRegistered = false;
|
||||
/// registered per Dart VM.
|
||||
Future<TaskResult> task(TaskFunction task) {
|
||||
if (_isTaskRegistered)
|
||||
throw new StateError('A task is already registered');
|
||||
throw StateError('A task is already registered');
|
||||
|
||||
_isTaskRegistered = true;
|
||||
|
||||
@ -43,13 +43,13 @@ Future<TaskResult> task(TaskFunction task) {
|
||||
print('${rec.level.name}: ${rec.time}: ${rec.message}');
|
||||
});
|
||||
|
||||
final _TaskRunner runner = new _TaskRunner(task);
|
||||
final _TaskRunner runner = _TaskRunner(task);
|
||||
runner.keepVmAliveUntilTaskRunRequested();
|
||||
return runner.whenDone;
|
||||
}
|
||||
|
||||
class _TaskRunner {
|
||||
static final Logger logger = new Logger('TaskRunner');
|
||||
static final Logger logger = Logger('TaskRunner');
|
||||
|
||||
final TaskFunction task;
|
||||
|
||||
@ -58,20 +58,20 @@ class _TaskRunner {
|
||||
Timer _startTaskTimeout;
|
||||
bool _taskStarted = false;
|
||||
|
||||
final Completer<TaskResult> _completer = new Completer<TaskResult>();
|
||||
final Completer<TaskResult> _completer = Completer<TaskResult>();
|
||||
|
||||
_TaskRunner(this.task) {
|
||||
registerExtension('ext.cocoonRunTask',
|
||||
(String method, Map<String, String> parameters) async {
|
||||
final Duration taskTimeout = parameters.containsKey('timeoutInMinutes')
|
||||
? new Duration(minutes: int.parse(parameters['timeoutInMinutes']))
|
||||
? Duration(minutes: int.parse(parameters['timeoutInMinutes']))
|
||||
: _kDefaultTaskTimeout;
|
||||
final TaskResult result = await run(taskTimeout);
|
||||
return new ServiceExtensionResponse.result(json.encode(result.toJson()));
|
||||
return ServiceExtensionResponse.result(json.encode(result.toJson()));
|
||||
});
|
||||
registerExtension('ext.cocoonRunnerReady',
|
||||
(String method, Map<String, String> parameters) async {
|
||||
return new ServiceExtensionResponse.result('"ready"');
|
||||
return ServiceExtensionResponse.result('"ready"');
|
||||
});
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ class _TaskRunner {
|
||||
return result;
|
||||
} on TimeoutException catch (_) {
|
||||
print('Task timed out in framework.dart after $taskTimeout.');
|
||||
return new TaskResult.failure('Task timed out after $taskTimeout');
|
||||
return TaskResult.failure('Task timed out after $taskTimeout');
|
||||
} finally {
|
||||
print('Cleaning up after task...');
|
||||
await forceQuitRunningProcesses();
|
||||
@ -99,15 +99,15 @@ class _TaskRunner {
|
||||
/// received via the VM service protocol.
|
||||
void keepVmAliveUntilTaskRunRequested() {
|
||||
if (_taskStarted)
|
||||
throw new StateError('Task already started.');
|
||||
throw StateError('Task already started.');
|
||||
|
||||
// Merely creating this port object will cause the VM to stay alive and keep
|
||||
// the VM service server running until the port is disposed of.
|
||||
_keepAlivePort = new RawReceivePort();
|
||||
_keepAlivePort = RawReceivePort();
|
||||
|
||||
// Timeout if nothing bothers to connect and ask us to run the task.
|
||||
const Duration taskStartTimeout = Duration(seconds: 60);
|
||||
_startTaskTimeout = new Timer(taskStartTimeout, () {
|
||||
_startTaskTimeout = Timer(taskStartTimeout, () {
|
||||
if (!_taskStarted) {
|
||||
logger.severe('Task did not start in $taskStartTimeout.');
|
||||
_closeKeepAlivePort();
|
||||
@ -123,7 +123,7 @@ class _TaskRunner {
|
||||
}
|
||||
|
||||
Future<TaskResult> _performTask() {
|
||||
final Completer<TaskResult> completer = new Completer<TaskResult>();
|
||||
final Completer<TaskResult> completer = Completer<TaskResult>();
|
||||
Chain.capture(() async {
|
||||
completer.complete(await task());
|
||||
}, onError: (dynamic taskError, Chain taskErrorStack) {
|
||||
@ -138,7 +138,7 @@ class _TaskRunner {
|
||||
// code. Our goal is to convert the failure into a readable message.
|
||||
// Propagating it further is not useful.
|
||||
if (!completer.isCompleted)
|
||||
completer.complete(new TaskResult.failure(message));
|
||||
completer.complete(TaskResult.failure(message));
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
@ -167,7 +167,7 @@ class TaskResult {
|
||||
/// Constructs a successful result using JSON data stored in a file.
|
||||
factory TaskResult.successFromFile(File file,
|
||||
{List<String> benchmarkScoreKeys}) {
|
||||
return new TaskResult.success(json.decode(file.readAsStringSync()),
|
||||
return TaskResult.success(json.decode(file.readAsStringSync()),
|
||||
benchmarkScoreKeys: benchmarkScoreKeys);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class ManifestError extends Error {
|
||||
// manually. It's not too much code and produces good error messages.
|
||||
Manifest _validateAndParseManifest(Map<dynamic, dynamic> manifestYaml) {
|
||||
_checkKeys(manifestYaml, 'manifest', const <String>['tasks']);
|
||||
return new Manifest._(_validateAndParseTasks(manifestYaml['tasks']));
|
||||
return Manifest._(_validateAndParseTasks(manifestYaml['tasks']));
|
||||
}
|
||||
|
||||
List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) {
|
||||
@ -108,7 +108,7 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
|
||||
}
|
||||
|
||||
final List<dynamic> capabilities = _validateAndParseCapabilities(taskName, taskYaml['required_agent_capabilities']);
|
||||
return new ManifestTask._(
|
||||
return ManifestTask._(
|
||||
name: taskName,
|
||||
description: taskYaml['description'],
|
||||
stage: taskYaml['stage'],
|
||||
@ -129,7 +129,7 @@ List<String> _validateAndParseCapabilities(String taskName, dynamic capabilities
|
||||
|
||||
void _checkType(bool isValid, dynamic value, String variableName, String typeName) {
|
||||
if (!isValid) {
|
||||
throw new ManifestError(
|
||||
throw ManifestError(
|
||||
'$variableName must be a $typeName but was ${value.runtimeType}: $value',
|
||||
);
|
||||
}
|
||||
@ -137,14 +137,14 @@ void _checkType(bool isValid, dynamic value, String variableName, String typeNam
|
||||
|
||||
void _checkIsNotBlank(dynamic value, String variableName, String ownerName) {
|
||||
if (value == null || value.isEmpty) {
|
||||
throw new ManifestError('$variableName must not be empty in $ownerName.');
|
||||
throw ManifestError('$variableName must not be empty in $ownerName.');
|
||||
}
|
||||
}
|
||||
|
||||
void _checkKeys(Map<dynamic, dynamic> map, String variableName, List<String> allowedKeys) {
|
||||
for (String key in map.keys) {
|
||||
if (!allowedKeys.contains(key)) {
|
||||
throw new ManifestError(
|
||||
throw ManifestError(
|
||||
'Unrecognized property "$key" in $variableName. '
|
||||
'Allowed properties: ${allowedKeys.join(', ')}');
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ Future<Map<String, dynamic>> runTask(String taskName, { bool silent = false }) a
|
||||
runnerFinished = true;
|
||||
});
|
||||
|
||||
final Completer<int> port = new Completer<int>();
|
||||
final Completer<int> port = Completer<int>();
|
||||
|
||||
final StreamSubscription<String> stdoutSub = runner.stdout
|
||||
.transform(const Utf8Decoder())
|
||||
@ -90,14 +90,14 @@ Future<Map<String, dynamic>> runTask(String taskName, { bool silent = false }) a
|
||||
|
||||
Future<VMIsolateRef> _connectToRunnerIsolate(int vmServicePort) async {
|
||||
final String url = 'ws://localhost:$vmServicePort/ws';
|
||||
final DateTime started = new DateTime.now();
|
||||
final DateTime started = DateTime.now();
|
||||
|
||||
// TODO(yjbanov): due to lack of imagination at the moment the handshake with
|
||||
// the task process is very rudimentary and requires this small
|
||||
// delay to let the task process open up the VM service port.
|
||||
// Otherwise we almost always hit the non-ready case first and
|
||||
// wait a whole 1 second, which is annoying.
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
@ -105,7 +105,7 @@ Future<VMIsolateRef> _connectToRunnerIsolate(int vmServicePort) async {
|
||||
await (await WebSocket.connect(url)).close();
|
||||
|
||||
// Look up the isolate.
|
||||
final VMServiceClient client = new VMServiceClient.connect(url);
|
||||
final VMServiceClient client = VMServiceClient.connect(url);
|
||||
final VM vm = await client.getVM();
|
||||
final VMIsolateRef isolate = vm.isolates.single;
|
||||
final String response = await isolate.invokeExtension('ext.cocoonRunnerReady');
|
||||
@ -114,8 +114,8 @@ Future<VMIsolateRef> _connectToRunnerIsolate(int vmServicePort) async {
|
||||
return isolate;
|
||||
} catch (error) {
|
||||
const Duration connectionTimeout = Duration(seconds: 10);
|
||||
if (new DateTime.now().difference(started) > connectionTimeout) {
|
||||
throw new TimeoutException(
|
||||
if (DateTime.now().difference(started) > connectionTimeout) {
|
||||
throw TimeoutException(
|
||||
'Failed to connect to the task runner process',
|
||||
connectionTimeout,
|
||||
);
|
||||
@ -123,7 +123,7 @@ Future<VMIsolateRef> _connectToRunnerIsolate(int vmServicePort) async {
|
||||
print('VM service not ready yet: $error');
|
||||
const Duration pauseBetweenRetries = Duration(milliseconds: 200);
|
||||
print('Will retry in $pauseBetweenRetries.');
|
||||
await new Future<Null>.delayed(pauseBetweenRetries);
|
||||
await Future<Null>.delayed(pauseBetweenRetries);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,8 +142,8 @@ Future<void> cleanupSystem() async {
|
||||
print('\nTelling Gradle to shut down (JAVA_HOME=$javaHome)');
|
||||
final String gradlewBinaryName = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
|
||||
final Directory tempDir = Directory.systemTemp.createTempSync('flutter_devicelab_shutdown_gradle.');
|
||||
recursiveCopy(new Directory(path.join(flutterDirectory.path, 'bin', 'cache', 'artifacts', 'gradle_wrapper')), tempDir);
|
||||
copy(new File(path.join(path.join(flutterDirectory.path, 'packages', 'flutter_tools'), 'templates', 'create', 'android.tmpl', 'gradle', 'wrapper', 'gradle-wrapper.properties')), new Directory(path.join(tempDir.path, 'gradle', 'wrapper')));
|
||||
recursiveCopy(Directory(path.join(flutterDirectory.path, 'bin', 'cache', 'artifacts', 'gradle_wrapper')), tempDir);
|
||||
copy(File(path.join(path.join(flutterDirectory.path, 'packages', 'flutter_tools'), 'templates', 'create', 'android.tmpl', 'gradle', 'wrapper', 'gradle-wrapper.properties')), Directory(path.join(tempDir.path, 'gradle', 'wrapper')));
|
||||
if (!Platform.isWindows) {
|
||||
await exec(
|
||||
'chmod',
|
||||
|
@ -24,7 +24,7 @@ ProcessManager _processManager = const LocalProcessManager();
|
||||
class ProcessInfo {
|
||||
ProcessInfo(this.command, this.process);
|
||||
|
||||
final DateTime startTime = new DateTime.now();
|
||||
final DateTime startTime = DateTime.now();
|
||||
final String command;
|
||||
final Process process;
|
||||
|
||||
@ -52,7 +52,7 @@ class HealthCheckResult {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final StringBuffer buf = new StringBuffer(succeeded ? 'succeeded' : 'failed');
|
||||
final StringBuffer buf = StringBuffer(succeeded ? 'succeeded' : 'failed');
|
||||
if (details != null && details.trim().isNotEmpty) {
|
||||
buf.writeln();
|
||||
// Indent details by 4 spaces
|
||||
@ -74,7 +74,7 @@ class BuildFailedError extends Error {
|
||||
}
|
||||
|
||||
void fail(String message) {
|
||||
throw new BuildFailedError(message);
|
||||
throw BuildFailedError(message);
|
||||
}
|
||||
|
||||
// Remove the given file or directory.
|
||||
@ -98,9 +98,9 @@ void rmTree(FileSystemEntity entity) {
|
||||
|
||||
List<FileSystemEntity> ls(Directory directory) => directory.listSync();
|
||||
|
||||
Directory dir(String path) => new Directory(path);
|
||||
Directory dir(String path) => Directory(path);
|
||||
|
||||
File file(String path) => new File(path);
|
||||
File file(String path) => File(path);
|
||||
|
||||
void copy(File sourceFile, Directory targetDirectory, {String name}) {
|
||||
final File target = file(
|
||||
@ -115,9 +115,9 @@ void recursiveCopy(Directory source, Directory target) {
|
||||
for (FileSystemEntity entity in source.listSync(followLinks: false)) {
|
||||
final String name = path.basename(entity.path);
|
||||
if (entity is Directory)
|
||||
recursiveCopy(entity, new Directory(path.join(target.path, name)));
|
||||
recursiveCopy(entity, Directory(path.join(target.path, name)));
|
||||
else if (entity is File) {
|
||||
final File dest = new File(path.join(target.path, name));
|
||||
final File dest = File(path.join(target.path, name));
|
||||
dest.writeAsBytesSync(entity.readAsBytesSync());
|
||||
}
|
||||
}
|
||||
@ -187,7 +187,7 @@ Future<DateTime> getFlutterRepoCommitTimestamp(String commit) {
|
||||
commit,
|
||||
]);
|
||||
final int secondsSinceEpoch = int.parse(unixTimestamp);
|
||||
return new DateTime.fromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
|
||||
return DateTime.fromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
|
||||
});
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ Future<Process> startProcess(
|
||||
environment: environment,
|
||||
workingDirectory: workingDirectory ?? cwd,
|
||||
);
|
||||
final ProcessInfo processInfo = new ProcessInfo(command, process);
|
||||
final ProcessInfo processInfo = ProcessInfo(command, process);
|
||||
_runningProcesses.add(processInfo);
|
||||
|
||||
process.exitCode.then((int exitCode) {
|
||||
@ -248,7 +248,7 @@ Future<Null> forceQuitRunningProcesses() async {
|
||||
return;
|
||||
|
||||
// Give normally quitting processes a chance to report their exit code.
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
|
||||
// Whatever's left, kill it.
|
||||
for (ProcessInfo p in _runningProcesses) {
|
||||
@ -270,8 +270,8 @@ Future<int> exec(
|
||||
}) async {
|
||||
final Process process = await startProcess(executable, arguments, environment: environment, workingDirectory: workingDirectory);
|
||||
|
||||
final Completer<Null> stdoutDone = new Completer<Null>();
|
||||
final Completer<Null> stderrDone = new Completer<Null>();
|
||||
final Completer<Null> stdoutDone = Completer<Null>();
|
||||
final Completer<Null> stderrDone = Completer<Null>();
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
@ -306,9 +306,9 @@ Future<String> eval(
|
||||
}) async {
|
||||
final Process process = await startProcess(executable, arguments, environment: environment, workingDirectory: workingDirectory);
|
||||
|
||||
final StringBuffer output = new StringBuffer();
|
||||
final Completer<Null> stdoutDone = new Completer<Null>();
|
||||
final Completer<Null> stderrDone = new Completer<Null>();
|
||||
final StringBuffer output = StringBuffer();
|
||||
final Completer<Null> stdoutDone = Completer<Null>();
|
||||
final Completer<Null> stderrDone = Completer<Null>();
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
@ -496,7 +496,7 @@ Iterable<String> grep(Pattern pattern, {@required String from}) {
|
||||
///
|
||||
/// }
|
||||
Future<Null> runAndCaptureAsyncStacks(Future<Null> callback()) {
|
||||
final Completer<Null> completer = new Completer<Null>();
|
||||
final Completer<Null> completer = Completer<Null>();
|
||||
Chain.capture(() async {
|
||||
await callback();
|
||||
completer.complete();
|
||||
@ -507,7 +507,7 @@ Future<Null> runAndCaptureAsyncStacks(Future<Null> callback()) {
|
||||
bool canRun(String path) => _processManager.canRun(path);
|
||||
|
||||
String extractCloudAuthTokenArg(List<String> rawArgs) {
|
||||
final ArgParser argParser = new ArgParser()..addOption('cloud-auth-token');
|
||||
final ArgParser argParser = ArgParser()..addOption('cloud-auth-token');
|
||||
ArgResults args;
|
||||
try {
|
||||
args = argParser.parse(rawArgs);
|
||||
@ -536,7 +536,7 @@ int parseServicePort(String line, {
|
||||
bool multiLine = false,
|
||||
}) {
|
||||
// e.g. "An Observatory debugger and profiler on ... is available at: http://127.0.0.1:8100/"
|
||||
final RegExp pattern = new RegExp('$prefix(\\S+:(\\d+)/\\S*)\$', multiLine: multiLine);
|
||||
final RegExp pattern = RegExp('$prefix(\\S+:(\\d+)/\\S*)\$', multiLine: multiLine);
|
||||
final Match match = pattern.firstMatch(line);
|
||||
return match == null ? null : int.parse(match.group(2));
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ Future<TaskResult> analyzerBenchmarkTask() async {
|
||||
});
|
||||
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data.addAll((await _run(new _FlutterRepoBenchmark())).asMap('flutter_repo', 'batch'));
|
||||
data.addAll((await _run(new _FlutterRepoBenchmark(watch: true))).asMap('flutter_repo', 'watch'));
|
||||
data.addAll((await _run(new _MegaGalleryBenchmark())).asMap('mega_gallery', 'batch'));
|
||||
data.addAll((await _run(new _MegaGalleryBenchmark(watch: true))).asMap('mega_gallery', 'watch'));
|
||||
data.addAll((await _run(_FlutterRepoBenchmark())).asMap('flutter_repo', 'batch'));
|
||||
data.addAll((await _run(_FlutterRepoBenchmark(watch: true))).asMap('flutter_repo', 'watch'));
|
||||
data.addAll((await _run(_MegaGalleryBenchmark())).asMap('mega_gallery', 'batch'));
|
||||
data.addAll((await _run(_MegaGalleryBenchmark(watch: true))).asMap('mega_gallery', 'watch'));
|
||||
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
return TaskResult.success(data, benchmarkScoreKeys: data.keys.toList());
|
||||
}
|
||||
|
||||
class _BenchmarkResult {
|
||||
@ -73,7 +73,7 @@ abstract class _Benchmark {
|
||||
|
||||
Future<double> execute(int iteration, int targetIterations) async {
|
||||
section('Analyze $title ${watch ? 'with watcher' : ''} - ${iteration + 1} / $targetIterations');
|
||||
final Stopwatch stopwatch = new Stopwatch();
|
||||
final Stopwatch stopwatch = Stopwatch();
|
||||
await inDirectory(directory, () async {
|
||||
stopwatch.start();
|
||||
await flutter('analyze', options: options);
|
||||
@ -124,5 +124,5 @@ Future<_BenchmarkResult> _run(_Benchmark benchmark) async {
|
||||
0.0,
|
||||
(double previousValue, double element) => previousValue + element,
|
||||
);
|
||||
return new _BenchmarkResult(sum / results.length, results.first, results.last);
|
||||
return _BenchmarkResult(sum / results.length, results.first, results.last);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import '../framework/ios.dart';
|
||||
import '../framework/utils.dart';
|
||||
|
||||
TaskFunction createGalleryTransitionTest({ bool semanticsEnabled = false }) {
|
||||
return new GalleryTransitionTest(semanticsEnabled: semanticsEnabled);
|
||||
return GalleryTransitionTest(semanticsEnabled: semanticsEnabled);
|
||||
}
|
||||
|
||||
class GalleryTransitionTest {
|
||||
@ -67,7 +67,7 @@ class GalleryTransitionTest {
|
||||
};
|
||||
data.addAll(summary);
|
||||
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
return TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
'missed_transition_count',
|
||||
'average_frame_build_time_millis',
|
||||
'worst_frame_build_time_millis',
|
||||
|
@ -43,8 +43,8 @@ TaskFunction createHotModeTest() {
|
||||
environment: null
|
||||
);
|
||||
|
||||
final Completer<Null> stdoutDone = new Completer<Null>();
|
||||
final Completer<Null> stderrDone = new Completer<Null>();
|
||||
final Completer<Null> stdoutDone = Completer<Null>();
|
||||
final Completer<Null> stderrDone = Completer<Null>();
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
@ -96,8 +96,8 @@ TaskFunction createHotModeTest() {
|
||||
<String>['run']..addAll(options),
|
||||
environment: null
|
||||
);
|
||||
final Completer<Null> stdoutDone = new Completer<Null>();
|
||||
final Completer<Null> stderrDone = new Completer<Null>();
|
||||
final Completer<Null> stdoutDone = Completer<Null>();
|
||||
final Completer<Null> stderrDone = Completer<Null>();
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
@ -130,7 +130,7 @@ TaskFunction createHotModeTest() {
|
||||
|
||||
|
||||
|
||||
return new TaskResult.success(
|
||||
return TaskResult.success(
|
||||
<String, dynamic> {
|
||||
'hotReloadInitialDevFSSyncMilliseconds': twoReloadsData['hotReloadInitialDevFSSyncMilliseconds'][0],
|
||||
'hotRestartMillisecondsToFrame': twoReloadsData['hotRestartMillisecondsToFrame'][0],
|
||||
|
@ -10,21 +10,21 @@ import '../framework/ios.dart';
|
||||
import '../framework/utils.dart';
|
||||
|
||||
TaskFunction createChannelsIntegrationTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/channels',
|
||||
'lib/main.dart',
|
||||
);
|
||||
}
|
||||
|
||||
TaskFunction createPlatformInteractionTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/platform_interaction',
|
||||
'lib/main.dart',
|
||||
);
|
||||
}
|
||||
|
||||
TaskFunction createFlavorsTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/flavors',
|
||||
'lib/main.dart',
|
||||
extraOptions: <String>['--flavor', 'paid']
|
||||
@ -32,28 +32,28 @@ TaskFunction createFlavorsTest() {
|
||||
}
|
||||
|
||||
TaskFunction createExternalUiIntegrationTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/external_ui',
|
||||
'lib/main.dart',
|
||||
);
|
||||
}
|
||||
|
||||
TaskFunction createPlatformChannelSampleTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/examples/platform_channel',
|
||||
'test_driver/button_tap.dart',
|
||||
);
|
||||
}
|
||||
|
||||
TaskFunction createEmbeddedAndroidViewsIntegrationTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/android_views',
|
||||
'lib/main.dart',
|
||||
);
|
||||
}
|
||||
|
||||
TaskFunction createAndroidSemanticsIntegrationTest() {
|
||||
return new DriverTest(
|
||||
return DriverTest(
|
||||
'${flutterDirectory.path}/dev/integration_tests/android_semantics_testing',
|
||||
'lib/main.dart',
|
||||
);
|
||||
@ -91,7 +91,7 @@ class DriverTest {
|
||||
options.addAll(extraOptions);
|
||||
await flutter('drive', options: options);
|
||||
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -33,5 +33,5 @@ Future<TaskResult> runEndToEndTests() async {
|
||||
}
|
||||
});
|
||||
|
||||
return new TaskResult.success(<String, dynamic>{});
|
||||
return TaskResult.success(<String, dynamic>{});
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ TaskFunction createMicrobenchmarkTask() {
|
||||
allResults.addAll(await _runMicrobench('lib/gestures/velocity_tracker_bench.dart'));
|
||||
allResults.addAll(await _runMicrobench('lib/stocks/animation_bench.dart'));
|
||||
|
||||
return new TaskResult.success(allResults, benchmarkScoreKeys: allResults.keys.toList());
|
||||
return TaskResult.success(allResults, benchmarkScoreKeys: allResults.keys.toList());
|
||||
};
|
||||
}
|
||||
|
||||
@ -74,8 +74,8 @@ Future<Map<String, double>> _readJsonResults(Process process) {
|
||||
const String jsonEnd = '================ FORMATTED ==============';
|
||||
const String jsonPrefix = ':::JSON:::';
|
||||
bool jsonStarted = false;
|
||||
final StringBuffer jsonBuf = new StringBuffer();
|
||||
final Completer<Map<String, double>> completer = new Completer<Map<String, double>>();
|
||||
final StringBuffer jsonBuf = StringBuffer();
|
||||
final Completer<Map<String, double>> completer = Completer<Map<String, double>>();
|
||||
|
||||
final StreamSubscription<String> stderrSub = process.stderr
|
||||
.transform(const Utf8Decoder())
|
||||
@ -126,7 +126,7 @@ Future<Map<String, double>> _readJsonResults(Process process) {
|
||||
// Also send a kill signal in case the `q` above didn't work.
|
||||
process.kill(ProcessSignal.sigint); // ignore: deprecated_member_use
|
||||
try {
|
||||
completer.complete(new Map<String, double>.from(json.decode(jsonOutput)));
|
||||
completer.complete(Map<String, double>.from(json.decode(jsonOutput)));
|
||||
} catch (ex) {
|
||||
completer.completeError('Decoding JSON failed ($ex). JSON string was: $jsonOutput');
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import '../framework/ios.dart';
|
||||
import '../framework/utils.dart';
|
||||
|
||||
TaskFunction createComplexLayoutScrollPerfTest() {
|
||||
return new PerfTest(
|
||||
return PerfTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
||||
'test_driver/scroll_perf.dart',
|
||||
'complex_layout_scroll_perf',
|
||||
@ -23,7 +23,7 @@ TaskFunction createComplexLayoutScrollPerfTest() {
|
||||
}
|
||||
|
||||
TaskFunction createTilesScrollPerfTest() {
|
||||
return new PerfTest(
|
||||
return PerfTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
||||
'test_driver/scroll_perf.dart',
|
||||
'tiles_scroll_perf',
|
||||
@ -31,38 +31,38 @@ TaskFunction createTilesScrollPerfTest() {
|
||||
}
|
||||
|
||||
TaskFunction createFlutterGalleryStartupTest() {
|
||||
return new StartupTest(
|
||||
return StartupTest(
|
||||
'${flutterDirectory.path}/examples/flutter_gallery',
|
||||
).run;
|
||||
}
|
||||
|
||||
TaskFunction createComplexLayoutStartupTest() {
|
||||
return new StartupTest(
|
||||
return StartupTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
||||
).run;
|
||||
}
|
||||
|
||||
TaskFunction createFlutterGalleryCompileTest() {
|
||||
return new CompileTest('${flutterDirectory.path}/examples/flutter_gallery').run;
|
||||
return CompileTest('${flutterDirectory.path}/examples/flutter_gallery').run;
|
||||
}
|
||||
|
||||
TaskFunction createHelloWorldCompileTest() {
|
||||
return new CompileTest('${flutterDirectory.path}/examples/hello_world', reportPackageContentSizes: true).run;
|
||||
return CompileTest('${flutterDirectory.path}/examples/hello_world', reportPackageContentSizes: true).run;
|
||||
}
|
||||
|
||||
TaskFunction createComplexLayoutCompileTest() {
|
||||
return new CompileTest('${flutterDirectory.path}/dev/benchmarks/complex_layout').run;
|
||||
return CompileTest('${flutterDirectory.path}/dev/benchmarks/complex_layout').run;
|
||||
}
|
||||
|
||||
TaskFunction createFlutterViewStartupTest() {
|
||||
return new StartupTest(
|
||||
return StartupTest(
|
||||
'${flutterDirectory.path}/examples/flutter_view',
|
||||
reportMetrics: false,
|
||||
).run;
|
||||
}
|
||||
|
||||
TaskFunction createPlatformViewStartupTest() {
|
||||
return new StartupTest(
|
||||
return StartupTest(
|
||||
'${flutterDirectory.path}/examples/platform_view',
|
||||
reportMetrics: false,
|
||||
).run;
|
||||
@ -82,7 +82,7 @@ TaskFunction createBasicMaterialCompileTest() {
|
||||
if (!(await sampleDir.exists()))
|
||||
throw 'Failed to create default Flutter app in ${sampleDir.path}';
|
||||
|
||||
return new CompileTest(sampleDir.path).run();
|
||||
return CompileTest(sampleDir.path).run();
|
||||
};
|
||||
}
|
||||
|
||||
@ -112,9 +112,9 @@ class StartupTest {
|
||||
final Map<String, dynamic> data = json.decode(file('$testDirectory/build/start_up_info.json').readAsStringSync());
|
||||
|
||||
if (!reportMetrics)
|
||||
return new TaskResult.success(data);
|
||||
return TaskResult.success(data);
|
||||
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
return TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
'timeToFirstFrameMicros',
|
||||
]);
|
||||
});
|
||||
@ -152,13 +152,13 @@ class PerfTest {
|
||||
final Map<String, dynamic> data = json.decode(file('$testDirectory/build/$timelineFileName.timeline_summary.json').readAsStringSync());
|
||||
|
||||
if (data['frame_count'] < 5) {
|
||||
return new TaskResult.failure(
|
||||
return TaskResult.failure(
|
||||
'Timeline contains too few frames: ${data['frame_count']}. Possibly '
|
||||
'trace events are not being captured.',
|
||||
);
|
||||
}
|
||||
|
||||
return new TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
return TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
'average_frame_build_time_millis',
|
||||
'worst_frame_build_time_millis',
|
||||
'missed_frame_build_budget_count',
|
||||
@ -190,14 +190,14 @@ class CompileTest {
|
||||
..addAll(await _compileApp(reportPackageContentSizes: reportPackageContentSizes))
|
||||
..addAll(await _compileDebug());
|
||||
|
||||
return new TaskResult.success(metrics, benchmarkScoreKeys: metrics.keys.toList());
|
||||
return TaskResult.success(metrics, benchmarkScoreKeys: metrics.keys.toList());
|
||||
});
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> _compileAot() async {
|
||||
// Generate blobs instead of assembly.
|
||||
await flutter('clean');
|
||||
final Stopwatch watch = new Stopwatch()..start();
|
||||
final Stopwatch watch = Stopwatch()..start();
|
||||
final List<String> options = <String>[
|
||||
'aot',
|
||||
'-v',
|
||||
@ -218,7 +218,7 @@ class CompileTest {
|
||||
final String compileLog = await evalFlutter('build', options: options);
|
||||
watch.stop();
|
||||
|
||||
final RegExp metricExpression = new RegExp(r'([a-zA-Z]+)\(CodeSize\)\: (\d+)');
|
||||
final RegExp metricExpression = RegExp(r'([a-zA-Z]+)\(CodeSize\)\: (\d+)');
|
||||
final Map<String, dynamic> metrics = <String, dynamic>{};
|
||||
for (Match m in metricExpression.allMatches(compileLog)) {
|
||||
metrics[_sdkNameToMetricName(m.group(1))] = int.parse(m.group(2));
|
||||
@ -233,7 +233,7 @@ class CompileTest {
|
||||
|
||||
static Future<Map<String, dynamic>> _compileApp({ bool reportPackageContentSizes = false }) async {
|
||||
await flutter('clean');
|
||||
final Stopwatch watch = new Stopwatch();
|
||||
final Stopwatch watch = Stopwatch();
|
||||
int releaseSizeInBytes;
|
||||
final List<String> options = <String>['--release'];
|
||||
setLocalEngineOptionIfNecessary(options);
|
||||
@ -281,7 +281,7 @@ class CompileTest {
|
||||
|
||||
static Future<Map<String, dynamic>> _compileDebug() async {
|
||||
await flutter('clean');
|
||||
final Stopwatch watch = new Stopwatch();
|
||||
final Stopwatch watch = Stopwatch();
|
||||
final List<String> options = <String>['--debug'];
|
||||
setLocalEngineOptionIfNecessary(options);
|
||||
switch (deviceOperatingSystem) {
|
||||
@ -327,8 +327,8 @@ class CompileTest {
|
||||
'TARGET_BUILD_DIR': path.dirname(appPath),
|
||||
});
|
||||
|
||||
final File appFramework = new File(path.join(appPath, 'Frameworks', 'App.framework', 'App'));
|
||||
final File flutterFramework = new File(path.join(appPath, 'Frameworks', 'Flutter.framework', 'Flutter'));
|
||||
final File appFramework = File(path.join(appPath, 'Frameworks', 'App.framework', 'App'));
|
||||
final File flutterFramework = File(path.join(appPath, 'Frameworks', 'Flutter.framework', 'Flutter'));
|
||||
|
||||
return <String, dynamic>{
|
||||
'app_framework_uncompressed_bytes': await appFramework.length(),
|
||||
@ -344,7 +344,7 @@ class CompileTest {
|
||||
|
||||
// First three lines are header, last two lines are footer.
|
||||
for (int i = 3; i < lines.length - 2; i++) {
|
||||
final _UnzipListEntry entry = new _UnzipListEntry.fromLine(lines[i]);
|
||||
final _UnzipListEntry entry = _UnzipListEntry.fromLine(lines[i]);
|
||||
fileToMetadata[entry.path] = entry;
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ class MemoryTest {
|
||||
/// when `adb logcat` sees a log line with the given `message`.
|
||||
void prepareForNextMessage(String message) {
|
||||
_nextMessage = message;
|
||||
_receivedNextMessage = new Completer<void>();
|
||||
_receivedNextMessage = Completer<void>();
|
||||
}
|
||||
|
||||
int get iterationCount => 15;
|
||||
@ -427,14 +427,14 @@ class MemoryTest {
|
||||
assert(_diffMemory.length == iteration + 1);
|
||||
print('terminating...');
|
||||
await device.stop(package);
|
||||
await new Future<void>.delayed(const Duration(milliseconds: 10));
|
||||
await Future<void>.delayed(const Duration(milliseconds: 10));
|
||||
}
|
||||
|
||||
await adb.cancel();
|
||||
|
||||
final ListStatistics startMemoryStatistics = new ListStatistics(_startMemory);
|
||||
final ListStatistics endMemoryStatistics = new ListStatistics(_endMemory);
|
||||
final ListStatistics diffMemoryStatistics = new ListStatistics(_diffMemory);
|
||||
final ListStatistics startMemoryStatistics = ListStatistics(_startMemory);
|
||||
final ListStatistics endMemoryStatistics = ListStatistics(_endMemory);
|
||||
final ListStatistics diffMemoryStatistics = ListStatistics(_diffMemory);
|
||||
|
||||
final Map<String, dynamic> memoryUsage = <String, dynamic>{};
|
||||
memoryUsage.addAll(startMemoryStatistics.asMap('start'));
|
||||
@ -446,7 +446,7 @@ class MemoryTest {
|
||||
_endMemory.clear();
|
||||
_diffMemory.clear();
|
||||
|
||||
return new TaskResult.success(memoryUsage, benchmarkScoreKeys: memoryUsage.keys.toList());
|
||||
return TaskResult.success(memoryUsage, benchmarkScoreKeys: memoryUsage.keys.toList());
|
||||
});
|
||||
}
|
||||
|
||||
@ -516,7 +516,7 @@ class ListStatistics {
|
||||
assert(data.isNotEmpty);
|
||||
assert(data.length % 2 == 1);
|
||||
final List<int> sortedData = data.toList()..sort();
|
||||
return new ListStatistics._(
|
||||
return ListStatistics._(
|
||||
sortedData.first,
|
||||
sortedData.last,
|
||||
sortedData[(sortedData.length - 1) ~/ 2],
|
||||
@ -540,9 +540,9 @@ class ListStatistics {
|
||||
|
||||
class _UnzipListEntry {
|
||||
factory _UnzipListEntry.fromLine(String line) {
|
||||
final List<String> data = line.trim().split(new RegExp('\\s+'));
|
||||
final List<String> data = line.trim().split(RegExp('\\s+'));
|
||||
assert(data.length == 8);
|
||||
return new _UnzipListEntry._(
|
||||
return _UnzipListEntry._(
|
||||
uncompressedSize: int.parse(data[0]),
|
||||
compressedSize: int.parse(data[2]),
|
||||
path: data[7],
|
||||
|
@ -19,7 +19,7 @@ TaskFunction combine(List<TaskFunction> tasks) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
};
|
||||
}
|
||||
|
||||
@ -46,9 +46,9 @@ class PluginTest {
|
||||
} finally {
|
||||
await project.delete();
|
||||
}
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
} catch (e) {
|
||||
return new TaskResult.failure(e.toString());
|
||||
return TaskResult.failure(e.toString());
|
||||
} finally {
|
||||
rmTree(tempDir);
|
||||
}
|
||||
@ -68,13 +68,13 @@ class FlutterProject {
|
||||
options: <String>['--org', 'io.flutter.devicelab']..addAll(options)..add('plugintest')
|
||||
);
|
||||
});
|
||||
return new FlutterProject(directory, 'plugintest');
|
||||
return FlutterProject(directory, 'plugintest');
|
||||
}
|
||||
|
||||
String get rootPath => path.join(parent.path, name);
|
||||
|
||||
Future<Null> addPlugin(String plugin) async {
|
||||
final File pubspec = new File(path.join(rootPath, 'pubspec.yaml'));
|
||||
final File pubspec = File(path.join(rootPath, 'pubspec.yaml'));
|
||||
String content = await pubspec.readAsString();
|
||||
content = content.replaceFirst(
|
||||
'\ndependencies:\n',
|
||||
@ -84,7 +84,7 @@ class FlutterProject {
|
||||
}
|
||||
|
||||
Future<Null> build(String target) async {
|
||||
await inDirectory(new Directory(rootPath), () async {
|
||||
await inDirectory(Directory(rootPath), () async {
|
||||
await flutter('build', options: <String>[target]);
|
||||
});
|
||||
}
|
||||
@ -99,7 +99,7 @@ class FlutterProject {
|
||||
canFail: true,
|
||||
);
|
||||
// TODO(ianh): Investigating if flakiness is timing dependent.
|
||||
await new Future<Null>.delayed(const Duration(seconds: 10));
|
||||
await Future<Null>.delayed(const Duration(seconds: 10));
|
||||
}
|
||||
rmTree(parent);
|
||||
}
|
||||
|
@ -44,5 +44,5 @@ Future<TaskResult> samplePageCatalogGenerator(String authorizationToken) async {
|
||||
);
|
||||
});
|
||||
|
||||
return new TaskResult.success(null);
|
||||
return TaskResult.success(null);
|
||||
}
|
||||
|
@ -42,19 +42,19 @@ class Upload {
|
||||
Duration get timeLimit {
|
||||
if (retryCount == 0)
|
||||
return const Duration(milliseconds: 1000);
|
||||
random ??= new math.Random();
|
||||
return new Duration(milliseconds: random.nextInt(1000) + math.pow(2, retryCount) * 1000);
|
||||
random ??= math.Random();
|
||||
return Duration(milliseconds: random.nextInt(1000) + math.pow(2, retryCount) * 1000);
|
||||
}
|
||||
|
||||
Future<bool> save(HttpClient client, String name, List<int> content) async {
|
||||
try {
|
||||
final Uri uri = new Uri.https(uriAuthority, uriPath, <String, String>{
|
||||
final Uri uri = Uri.https(uriAuthority, uriPath, <String, String>{
|
||||
'uploadType': 'media',
|
||||
'name': name,
|
||||
});
|
||||
final HttpClientRequest request = await client.postUrl(uri);
|
||||
request
|
||||
..headers.contentType = new ContentType('image', 'png')
|
||||
..headers.contentType = ContentType('image', 'png')
|
||||
..headers.add('Authorization', 'Bearer $authorizationToken')
|
||||
..add(content);
|
||||
|
||||
@ -77,9 +77,9 @@ class Upload {
|
||||
Future<bool> run(HttpClient client) async {
|
||||
assert(!isComplete);
|
||||
if (retryCount > 2)
|
||||
throw new UploadError('upload of "$fromPath" to "$largeName" and "$smallName" failed after 2 retries');
|
||||
throw UploadError('upload of "$fromPath" to "$largeName" and "$smallName" failed after 2 retries');
|
||||
|
||||
largeImage ??= await new File(fromPath).readAsBytes();
|
||||
largeImage ??= await File(fromPath).readAsBytes();
|
||||
smallImage ??= encodePng(copyResize(decodePng(largeImage), 300));
|
||||
|
||||
if (!largeImageSaved)
|
||||
@ -97,12 +97,12 @@ Future<Null> saveScreenshots(List<String> fromPaths, List<String> largeNames, Li
|
||||
assert(fromPaths.length == largeNames.length);
|
||||
assert(fromPaths.length == smallNames.length);
|
||||
|
||||
List<Upload> uploads = new List<Upload>(fromPaths.length);
|
||||
List<Upload> uploads = List<Upload>(fromPaths.length);
|
||||
for (int index = 0; index < uploads.length; index += 1)
|
||||
uploads[index] = new Upload(fromPaths[index], largeNames[index], smallNames[index]);
|
||||
uploads[index] = Upload(fromPaths[index], largeNames[index], smallNames[index]);
|
||||
|
||||
while (uploads.any(Upload.isNotComplete)) {
|
||||
final HttpClient client = new HttpClient();
|
||||
final HttpClient client = HttpClient();
|
||||
uploads = uploads.where(Upload.isNotComplete).toList();
|
||||
await Future.wait(uploads.map((Upload upload) => upload.run(client)));
|
||||
client.close(force: true);
|
||||
|
@ -17,7 +17,7 @@ void main() {
|
||||
setUp(() {
|
||||
FakeDevice.resetLog();
|
||||
device = null;
|
||||
device = new FakeDevice();
|
||||
device = FakeDevice();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
@ -115,7 +115,7 @@ CommandArgs cmd({
|
||||
List<String> arguments,
|
||||
Map<String, String> environment,
|
||||
}) {
|
||||
return new CommandArgs(
|
||||
return CommandArgs(
|
||||
command: command,
|
||||
arguments: arguments,
|
||||
environment: environment,
|
||||
@ -183,7 +183,7 @@ class FakeDevice extends AndroidDevice {
|
||||
|
||||
@override
|
||||
Future<String> shellEval(String command, List<String> arguments, { Map<String, String> environment }) async {
|
||||
commandLog.add(new CommandArgs(
|
||||
commandLog.add(CommandArgs(
|
||||
command: command,
|
||||
arguments: arguments,
|
||||
environment: environment,
|
||||
@ -193,7 +193,7 @@ class FakeDevice extends AndroidDevice {
|
||||
|
||||
@override
|
||||
Future<Null> shellExec(String command, List<String> arguments, { Map<String, String> environment }) async {
|
||||
commandLog.add(new CommandArgs(
|
||||
commandLog.add(CommandArgs(
|
||||
command: command,
|
||||
arguments: arguments,
|
||||
environment: environment,
|
||||
|
@ -11,4 +11,4 @@ export 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
// TODO(ianh): Remove this file once https://github.com/dart-lang/matcher/issues/98 is fixed
|
||||
|
||||
/// A matcher that compares the type of the actual value to the type argument T.
|
||||
Matcher isInstanceOf<T>() => new test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
Matcher isInstanceOf<T>() => test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
|
@ -20,7 +20,7 @@ void main() {
|
||||
expect(task.requiredAgentCapabilities, <String>['linux/android']);
|
||||
|
||||
for (ManifestTask task in manifest.tasks) {
|
||||
final File taskFile = new File('bin/tasks/${task.name}.dart');
|
||||
final File taskFile = File('bin/tasks/${task.name}.dart');
|
||||
expect(taskFile.existsSync(), true,
|
||||
reason: 'File ${taskFile.path} corresponding to manifest task "${task.name}" not found');
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('understands RegExp', () {
|
||||
expect(grep(new RegExp('^b'), from: 'ab\nba'), <String>['ba']);
|
||||
expect(grep(RegExp('^b'), from: 'ab\nba'), <String>['ba']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const MethodChannel kSemanticsChannel = MethodChannel('semantics');
|
||||
|
||||
Future<String> dataHandler(String message) async {
|
||||
if (message.contains('getSemanticsNode')) {
|
||||
final Completer<String> completer = new Completer<String>();
|
||||
final Completer<String> completer = Completer<String>();
|
||||
final int id = int.tryParse(message.split('#')[1]) ?? 0;
|
||||
Future<void> completeSemantics([Object _]) async {
|
||||
final dynamic result = await kSemanticsChannel.invokeMethod('getSemanticsNode', <String, dynamic>{
|
||||
@ -37,7 +37,7 @@ Future<String> dataHandler(String message) async {
|
||||
completeSemantics();
|
||||
return completer.future;
|
||||
}
|
||||
throw new UnimplementedError();
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
const List<String> routes = <String>[
|
||||
@ -50,18 +50,18 @@ class TestApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
routes: <String, WidgetBuilder>{
|
||||
selectionControlsRoute: (BuildContext context) => new SelectionControlsPage(),
|
||||
textFieldRoute: (BuildContext context) => new TextFieldPage(),
|
||||
selectionControlsRoute: (BuildContext context) => SelectionControlsPage(),
|
||||
textFieldRoute: (BuildContext context) => TextFieldPage(),
|
||||
},
|
||||
home: new Builder(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return new Scaffold(
|
||||
body: new ListView(
|
||||
return Scaffold(
|
||||
body: ListView(
|
||||
children: routes.map((String value) {
|
||||
return new MaterialButton(
|
||||
child: new Text(value),
|
||||
return MaterialButton(
|
||||
child: Text(value),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushNamed(value);
|
||||
},
|
||||
|
@ -51,7 +51,7 @@ class AndroidSemanticsNode {
|
||||
/// ]
|
||||
/// }
|
||||
factory AndroidSemanticsNode.deserialize(String value) {
|
||||
return new AndroidSemanticsNode._(json.decode(value));
|
||||
return AndroidSemanticsNode._(json.decode(value));
|
||||
}
|
||||
|
||||
final Map<String, Object> _values;
|
||||
@ -129,7 +129,7 @@ class AndroidSemanticsNode {
|
||||
Rect getRect() {
|
||||
final Map<String, Object> rawRect = _values['rect'];
|
||||
final Map<String, int> rect = rawRect.cast<String, int>();
|
||||
return new Rect.fromLTRB(
|
||||
return Rect.fromLTRB(
|
||||
rect['left'].toDouble(),
|
||||
rect['top'].toDouble(),
|
||||
rect['right'].toDouble(),
|
||||
@ -140,7 +140,7 @@ class AndroidSemanticsNode {
|
||||
/// Gets a [Size] which defines the size of the semantics node.
|
||||
Size getSize() {
|
||||
final Rect rect = getRect();
|
||||
return new Size(rect.bottom - rect.top, rect.right - rect.left);
|
||||
return Size(rect.bottom - rect.top, rect.right - rect.left);
|
||||
}
|
||||
|
||||
/// Gets a list of [AndroidSemanticsActions] which are defined for the node.
|
||||
|
@ -11,4 +11,4 @@ import 'package:test/test.dart' as test_package show TypeMatcher;
|
||||
export 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
|
||||
/// A matcher that compares the type of the actual value to the type argument T.
|
||||
Matcher isInstanceOf<T>() => new test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
Matcher isInstanceOf<T>() => test_package.TypeMatcher<T>(); // ignore: prefer_const_constructors, https://github.com/dart-lang/sdk/issues/32544
|
||||
|
@ -31,7 +31,7 @@ Matcher hasAndroidSemantics({
|
||||
bool isPassword,
|
||||
bool isLongClickable,
|
||||
}) {
|
||||
return new _AndroidSemanticsMatcher(
|
||||
return _AndroidSemanticsMatcher(
|
||||
text: text,
|
||||
contentDescription: contentDescription,
|
||||
className: className,
|
||||
|
@ -11,7 +11,7 @@ export 'controls_constants.dart';
|
||||
/// A test page with a checkbox, three radio buttons, and a switch.
|
||||
class SelectionControlsPage extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() => new _SelectionControlsPageState();
|
||||
State<StatefulWidget> createState() => _SelectionControlsPageState();
|
||||
}
|
||||
|
||||
class _SelectionControlsPageState extends State<SelectionControlsPage> {
|
||||
@ -53,13 +53,13 @@ class _SelectionControlsPageState extends State<SelectionControlsPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(leading: const BackButton(key: ValueKey<String>('back'))),
|
||||
body: new Material(
|
||||
child: new Column(children: <Widget>[
|
||||
new Row(
|
||||
return Scaffold(
|
||||
appBar: AppBar(leading: const BackButton(key: ValueKey<String>('back'))),
|
||||
body: Material(
|
||||
child: Column(children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
new Checkbox(
|
||||
Checkbox(
|
||||
key: checkbox1Key,
|
||||
value: _isChecked,
|
||||
onChanged: _updateCheckbox,
|
||||
@ -72,23 +72,23 @@ class _SelectionControlsPageState extends State<SelectionControlsPage> {
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
new Row(children: <Widget>[
|
||||
new Radio<int>(key: radio1Key, value: 0, groupValue: _radio, onChanged: _updateRadio),
|
||||
new Radio<int>(key: radio2Key, value: 1, groupValue: _radio, onChanged: _updateRadio),
|
||||
new Radio<int>(key: radio3Key, value: 2, groupValue: _radio, onChanged: _updateRadio),
|
||||
Row(children: <Widget>[
|
||||
Radio<int>(key: radio1Key, value: 0, groupValue: _radio, onChanged: _updateRadio),
|
||||
Radio<int>(key: radio2Key, value: 1, groupValue: _radio, onChanged: _updateRadio),
|
||||
Radio<int>(key: radio3Key, value: 2, groupValue: _radio, onChanged: _updateRadio),
|
||||
]),
|
||||
const Spacer(),
|
||||
new Switch(
|
||||
Switch(
|
||||
key: switchKey,
|
||||
value: _isOn,
|
||||
onChanged: _updateSwitch,
|
||||
),
|
||||
const Spacer(),
|
||||
new MergeSemantics(
|
||||
child: new Row(
|
||||
MergeSemantics(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
const Text(switchLabel),
|
||||
new Switch(
|
||||
Switch(
|
||||
key: labeledSwitchKey,
|
||||
value: _isLabeledOn,
|
||||
onChanged: _updateLabeledSwitch,
|
||||
|
@ -11,28 +11,28 @@ export 'text_field_constants.dart';
|
||||
/// A page with a normal text field and a password field.
|
||||
class TextFieldPage extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() => new _TextFieldPageState();
|
||||
State<StatefulWidget> createState() => _TextFieldPageState();
|
||||
}
|
||||
|
||||
class _TextFieldPageState extends State<TextFieldPage> {
|
||||
final TextEditingController _normalController = new TextEditingController();
|
||||
final TextEditingController _passwordController = new TextEditingController();
|
||||
final TextEditingController _normalController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
final Key normalTextFieldKey = const ValueKey<String>(normalTextFieldKeyValue);
|
||||
final Key passwordTextFieldKey = const ValueKey<String>(passwordTextFieldKeyValue);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(leading: const BackButton(key: ValueKey<String>('back'))),
|
||||
body: new Material(
|
||||
child: new Column(children: <Widget>[
|
||||
new TextField(
|
||||
return Scaffold(
|
||||
appBar: AppBar(leading: const BackButton(key: ValueKey<String>('back'))),
|
||||
body: Material(
|
||||
child: Column(children: <Widget>[
|
||||
TextField(
|
||||
key: normalTextFieldKey,
|
||||
controller: _normalController,
|
||||
autofocus: false,
|
||||
),
|
||||
const Spacer(),
|
||||
new TextField(
|
||||
TextField(
|
||||
key: passwordTextFieldKey,
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
|
@ -17,7 +17,7 @@ void main() {
|
||||
Future<AndroidSemanticsNode> getSemantics(SerializableFinder finder) async {
|
||||
final int id = await driver.getSemanticsId(finder);
|
||||
final String data = await driver.requestData('getSemanticsNode#$id');
|
||||
return new AndroidSemanticsNode.deserialize(data);
|
||||
return AndroidSemanticsNode.deserialize(data);
|
||||
}
|
||||
|
||||
setUpAll(() async {
|
||||
|
@ -23,7 +23,7 @@ const String kEventsFileName = 'touchEvents';
|
||||
/// set by the app in which case the requestData call will only complete once the app is ready
|
||||
/// for it.
|
||||
class FutureDataHandler {
|
||||
final Completer<DataHandler> handlerCompleter = new Completer<DataHandler>();
|
||||
final Completer<DataHandler> handlerCompleter = Completer<DataHandler>();
|
||||
|
||||
Future<String> handleMessage(String message) async {
|
||||
final DataHandler handler = await handlerCompleter.future;
|
||||
@ -31,20 +31,20 @@ class FutureDataHandler {
|
||||
}
|
||||
}
|
||||
|
||||
FutureDataHandler driverDataHandler = new FutureDataHandler();
|
||||
FutureDataHandler driverDataHandler = FutureDataHandler();
|
||||
|
||||
void main() {
|
||||
enableFlutterDriverExtension(handler: driverDataHandler.handleMessage);
|
||||
runApp(new MyApp());
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Android Views Integration Test',
|
||||
home: new Scaffold(
|
||||
body: new PlatformViewPage(),
|
||||
home: Scaffold(
|
||||
body: PlatformViewPage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -52,7 +52,7 @@ class MyApp extends StatelessWidget {
|
||||
|
||||
class PlatformViewPage extends StatefulWidget {
|
||||
@override
|
||||
State createState() => new PlatformViewState();
|
||||
State createState() => PlatformViewState();
|
||||
}
|
||||
|
||||
class PlatformViewState extends State<PlatformViewPage> {
|
||||
@ -68,27 +68,27 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Column(
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
new SizedBox(
|
||||
SizedBox(
|
||||
height: 300.0,
|
||||
child: new AndroidView(
|
||||
child: AndroidView(
|
||||
viewType: 'simple_view',
|
||||
onPlatformViewCreated: onPlatformViewCreated),
|
||||
),
|
||||
new Expanded(
|
||||
child: new ListView.builder(
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemBuilder: buildEventTile,
|
||||
itemCount: flutterViewEvents.length,
|
||||
),
|
||||
),
|
||||
new Row(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
new RaisedButton(
|
||||
RaisedButton(
|
||||
child: const Text('RECORD'),
|
||||
onPressed: listenToFlutterViewEvents,
|
||||
),
|
||||
new RaisedButton(
|
||||
RaisedButton(
|
||||
child: const Text('CLEAR'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
@ -97,7 +97,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
});
|
||||
},
|
||||
),
|
||||
new RaisedButton(
|
||||
RaisedButton(
|
||||
child: const Text('SAVE'),
|
||||
onPressed: () {
|
||||
const StandardMessageCodec codec = StandardMessageCodec();
|
||||
@ -105,7 +105,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
codec.encodeMessage(flutterViewEvents), context);
|
||||
},
|
||||
),
|
||||
new RaisedButton(
|
||||
RaisedButton(
|
||||
key: const ValueKey<String>('play'),
|
||||
child: const Text('PLAY FILE'),
|
||||
onPressed: () { playEventsFile(); },
|
||||
@ -138,7 +138,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
if (flutterViewEvents.length != embeddedViewEvents.length)
|
||||
return 'Synthesized ${flutterViewEvents.length} events but the embedded view received ${embeddedViewEvents.length} events';
|
||||
|
||||
final StringBuffer diff = new StringBuffer();
|
||||
final StringBuffer diff = StringBuffer();
|
||||
for (int i = 0; i < flutterViewEvents.length; ++i) {
|
||||
final String currentDiff = diffMotionEvents(flutterViewEvents[i], embeddedViewEvents[i]);
|
||||
if (currentDiff.isEmpty)
|
||||
@ -168,7 +168,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
try {
|
||||
final Directory outDir = await getExternalStorageDirectory();
|
||||
// This test only runs on Android so we can assume path separator is '/'.
|
||||
final File file = new File('${outDir.path}/$kEventsFileName');
|
||||
final File file = File('${outDir.path}/$kEventsFileName');
|
||||
await file.writeAsBytes(data.buffer.asUint8List(0, data.lengthInBytes), flush: true);
|
||||
showMessage(context, 'Saved original events to ${file.path}');
|
||||
} catch (e) {
|
||||
@ -177,14 +177,14 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
}
|
||||
|
||||
void showMessage(BuildContext context, String message) {
|
||||
Scaffold.of(context).showSnackBar(new SnackBar(
|
||||
content: new Text(message),
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(message),
|
||||
duration: const Duration(seconds: 3),
|
||||
));
|
||||
}
|
||||
|
||||
void onPlatformViewCreated(int id) {
|
||||
viewChannel = new MethodChannel('simple_view/$id');
|
||||
viewChannel = MethodChannel('simple_view/$id');
|
||||
viewChannel.setMethodCallHandler(onViewMethodChannelCall);
|
||||
driverDataHandler.handlerCompleter.complete(handleDriverMessage);
|
||||
}
|
||||
@ -192,7 +192,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
void listenToFlutterViewEvents() {
|
||||
channel.invokeMethod('pipeFlutterViewEvents');
|
||||
viewChannel.invokeMethod('pipeTouchEvents');
|
||||
new Timer(const Duration(seconds: 3), () {
|
||||
Timer(const Duration(seconds: 3), () {
|
||||
channel.invokeMethod('stopFlutterViewEvents');
|
||||
viewChannel.invokeMethod('stopTouchEvents');
|
||||
});
|
||||
@ -216,7 +216,7 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
setState(() {});
|
||||
break;
|
||||
}
|
||||
return new Future<dynamic>.sync(null);
|
||||
return Future<dynamic>.sync(null);
|
||||
}
|
||||
|
||||
Future<dynamic> onViewMethodChannelCall(MethodCall call) {
|
||||
@ -229,14 +229,14 @@ class PlatformViewState extends State<PlatformViewPage> {
|
||||
setState(() {});
|
||||
break;
|
||||
}
|
||||
return new Future<dynamic>.sync(null);
|
||||
return Future<dynamic>.sync(null);
|
||||
}
|
||||
|
||||
Widget buildEventTile(BuildContext context, int index) {
|
||||
if (embeddedViewEvents.length > index)
|
||||
return new TouchEventDiff(
|
||||
return TouchEventDiff(
|
||||
flutterViewEvents[index], embeddedViewEvents[index]);
|
||||
return new Text(
|
||||
return Text(
|
||||
'Unmatched event, action: ${flutterViewEvents[index]['action']}');
|
||||
}
|
||||
}
|
||||
@ -262,23 +262,23 @@ class TouchEventDiff extends StatelessWidget {
|
||||
color = Colors.red;
|
||||
msg = '[$actionName] $diff';
|
||||
}
|
||||
return new GestureDetector(
|
||||
return GestureDetector(
|
||||
onLongPress: () {
|
||||
print('expected:');
|
||||
prettyPrintEvent(originalEvent);
|
||||
print('\nactual:');
|
||||
prettyPrintEvent(synthesizedEvent);
|
||||
},
|
||||
child: new Container(
|
||||
child: Container(
|
||||
color: color,
|
||||
margin: const EdgeInsets.only(bottom: 2.0),
|
||||
child: new Text(msg),
|
||||
child: Text(msg),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void prettyPrintEvent(Map<String, dynamic> event) {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
final StringBuffer buffer = StringBuffer();
|
||||
final int action = event['action'];
|
||||
final int maskedAction = getActionMasked(action);
|
||||
final String actionName = getActionName(maskedAction, action);
|
||||
|
@ -19,7 +19,7 @@ String diffMotionEvents(
|
||||
Map<String, dynamic> originalEvent,
|
||||
Map<String, dynamic> synthesizedEvent,
|
||||
) {
|
||||
final StringBuffer diff = new StringBuffer();
|
||||
final StringBuffer diff = StringBuffer();
|
||||
|
||||
diffMaps(originalEvent, synthesizedEvent, diff, excludeKeys: const <String>[
|
||||
'pointerProperties', // Compared separately.
|
||||
|
@ -12,7 +12,7 @@ Future<void> main() async {
|
||||
|
||||
setUpAll(() async {
|
||||
print('Cloning goldens repository...');
|
||||
final GoldensClient goldensClient = new GoldensClient();
|
||||
final GoldensClient goldensClient = GoldensClient();
|
||||
await goldensClient.prepare();
|
||||
});
|
||||
|
||||
|
@ -15,16 +15,16 @@ import 'src/test_step.dart';
|
||||
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
runApp(new TestApp());
|
||||
runApp(TestApp());
|
||||
}
|
||||
|
||||
class TestApp extends StatefulWidget {
|
||||
@override
|
||||
_TestAppState createState() => new _TestAppState();
|
||||
_TestAppState createState() => _TestAppState();
|
||||
}
|
||||
|
||||
class _TestAppState extends State<TestApp> {
|
||||
static final dynamic anUnknownValue = new DateTime.fromMillisecondsSinceEpoch(1520777802314);
|
||||
static final dynamic anUnknownValue = DateTime.fromMillisecondsSinceEpoch(1520777802314);
|
||||
static final List<dynamic> aList = <dynamic>[
|
||||
false,
|
||||
0,
|
||||
@ -43,24 +43,24 @@ class _TestAppState extends State<TestApp> {
|
||||
<String, dynamic>{'key': 42}
|
||||
],
|
||||
};
|
||||
static final Uint8List someUint8s = new Uint8List.fromList(<int>[
|
||||
static final Uint8List someUint8s = Uint8List.fromList(<int>[
|
||||
0xBA,
|
||||
0x5E,
|
||||
0xBA,
|
||||
0x11,
|
||||
]);
|
||||
static final Int32List someInt32s = new Int32List.fromList(<int>[
|
||||
static final Int32List someInt32s = Int32List.fromList(<int>[
|
||||
-0x7fffffff - 1,
|
||||
0,
|
||||
0x7fffffff,
|
||||
]);
|
||||
static final Int64List someInt64s = new Int64List.fromList(<int>[
|
||||
static final Int64List someInt64s = Int64List.fromList(<int>[
|
||||
-0x7fffffffffffffff - 1,
|
||||
0,
|
||||
0x7fffffffffffffff,
|
||||
]);
|
||||
static final Float64List someFloat64s =
|
||||
new Float64List.fromList(<double>[
|
||||
Float64List.fromList(<double>[
|
||||
double.nan,
|
||||
double.negativeInfinity,
|
||||
-double.maxFinite,
|
||||
@ -73,7 +73,7 @@ class _TestAppState extends State<TestApp> {
|
||||
]);
|
||||
static final dynamic aCompoundUnknownValue = <dynamic>[
|
||||
anUnknownValue,
|
||||
new Pair(anUnknownValue, aList),
|
||||
Pair(anUnknownValue, aList),
|
||||
];
|
||||
static final List<TestStep> steps = <TestStep>[
|
||||
() => methodCallJsonSuccessHandshake(null),
|
||||
@ -97,8 +97,8 @@ class _TestAppState extends State<TestApp> {
|
||||
() => methodCallStandardErrorHandshake('world'),
|
||||
() => methodCallStandardNotImplementedHandshake(),
|
||||
() => basicBinaryHandshake(null),
|
||||
() => basicBinaryHandshake(new ByteData(0)),
|
||||
() => basicBinaryHandshake(new ByteData(4)..setUint32(0, 0x12345678)),
|
||||
() => basicBinaryHandshake(ByteData(0)),
|
||||
() => basicBinaryHandshake(ByteData(4)..setUint32(0, 0x12345678)),
|
||||
() => basicStringHandshake('hello, world'),
|
||||
() => basicStringHandshake('hello \u263A \u{1f602} unicode'),
|
||||
() => basicStringHandshake(''),
|
||||
@ -166,7 +166,7 @@ class _TestAppState extends State<TestApp> {
|
||||
if (_step < steps.length)
|
||||
_result = steps[_step++]();
|
||||
else
|
||||
_result = new Future<TestStepResult>.value(TestStepResult.complete);
|
||||
_result = Future<TestStepResult>.value(TestStepResult.complete);
|
||||
});
|
||||
}
|
||||
|
||||
@ -174,25 +174,25 @@ class _TestAppState extends State<TestApp> {
|
||||
BuildContext context,
|
||||
AsyncSnapshot<TestStepResult> snapshot,
|
||||
) {
|
||||
return new TestStepResult.fromSnapshot(snapshot).asWidget(context);
|
||||
return TestStepResult.fromSnapshot(snapshot).asWidget(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Channels Test',
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Channels Test'),
|
||||
),
|
||||
body: new Padding(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: new FutureBuilder<TestStepResult>(
|
||||
child: FutureBuilder<TestStepResult>(
|
||||
future: _result,
|
||||
builder: _buildTestResultWidget,
|
||||
),
|
||||
),
|
||||
floatingActionButton: new FloatingActionButton(
|
||||
floatingActionButton: FloatingActionButton(
|
||||
key: const ValueKey<String>('step'),
|
||||
onPressed: _executeNextStep,
|
||||
child: const Icon(Icons.navigate_next),
|
||||
|
@ -33,9 +33,9 @@ class ExtendedStandardMessageCodec extends StandardMessageCodec {
|
||||
dynamic readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case _dateTime:
|
||||
return new DateTime.fromMillisecondsSinceEpoch(buffer.getInt64());
|
||||
return DateTime.fromMillisecondsSinceEpoch(buffer.getInt64());
|
||||
case _pair:
|
||||
return new Pair(readValue(buffer), readValue(buffer));
|
||||
return Pair(readValue(buffer), readValue(buffer));
|
||||
default: return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ Future<TestStepResult> _methodCallErrorHandshake(
|
||||
final List<dynamic> received = <dynamic>[];
|
||||
channel.setMethodCallHandler((MethodCall call) async {
|
||||
received.add(call.arguments);
|
||||
throw new PlatformException(
|
||||
throw PlatformException(
|
||||
code: 'error', message: null, details: arguments);
|
||||
});
|
||||
dynamic errorDetails = nothing;
|
||||
@ -118,7 +118,7 @@ Future<TestStepResult> _methodCallNotImplementedHandshake(
|
||||
final List<dynamic> received = <dynamic>[];
|
||||
channel.setMethodCallHandler((MethodCall call) async {
|
||||
received.add(call.arguments);
|
||||
throw new MissingPluginException();
|
||||
throw MissingPluginException();
|
||||
});
|
||||
dynamic result = nothing;
|
||||
dynamic error = nothing;
|
||||
|
@ -72,21 +72,21 @@ class TestStepResult {
|
||||
final dynamic error;
|
||||
|
||||
Widget asWidget(BuildContext context) {
|
||||
return new Column(
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text('Step: $name', style: bold),
|
||||
new Text(description),
|
||||
Text('Step: $name', style: bold),
|
||||
Text(description),
|
||||
const Text(' '),
|
||||
new Text('Msg sent: ${_toString(messageSent)}'),
|
||||
new Text('Msg rvcd: ${_toString(messageReceived)}'),
|
||||
new Text('Reply echo: ${_toString(replyEcho)}'),
|
||||
new Text('Msg echo: ${_toString(messageEcho)}'),
|
||||
new Text('Error: ${_toString(error)}'),
|
||||
Text('Msg sent: ${_toString(messageSent)}'),
|
||||
Text('Msg rvcd: ${_toString(messageReceived)}'),
|
||||
Text('Reply echo: ${_toString(replyEcho)}'),
|
||||
Text('Msg echo: ${_toString(messageEcho)}'),
|
||||
Text('Error: ${_toString(error)}'),
|
||||
const Text(' '),
|
||||
new Text(
|
||||
Text(
|
||||
status.toString().substring('TestStatus.'.length),
|
||||
key: new ValueKey<String>(
|
||||
key: ValueKey<String>(
|
||||
status == TestStatus.pending ? 'nostatus' : 'status'),
|
||||
style: bold,
|
||||
),
|
||||
@ -117,7 +117,7 @@ Future<TestStepResult> resultOfHandshake(
|
||||
} else {
|
||||
status = TestStatus.ok;
|
||||
}
|
||||
return new TestStepResult(
|
||||
return TestStepResult(
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
|
@ -11,12 +11,12 @@ import 'package:flutter_driver/driver_extension.dart';
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
debugPrint('Application starting...');
|
||||
runApp(new MyApp());
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
@override
|
||||
State createState() => new MyAppState();
|
||||
State createState() => MyAppState();
|
||||
}
|
||||
|
||||
const MethodChannel channel = MethodChannel('texture');
|
||||
@ -92,7 +92,7 @@ Widget builds: $_widgetBuilds''';
|
||||
/// Measures Flutter's frame rate.
|
||||
Future<Null> _calibrate() async {
|
||||
debugPrint('Awaiting calm (3 second pause)...');
|
||||
await new Future<Null>.delayed(const Duration(milliseconds: 3000));
|
||||
await Future<Null>.delayed(const Duration(milliseconds: 3000));
|
||||
debugPrint('Calibrating...');
|
||||
DateTime startTime;
|
||||
int tickCount = 0;
|
||||
@ -100,7 +100,7 @@ Widget builds: $_widgetBuilds''';
|
||||
ticker = createTicker((Duration time) {
|
||||
tickCount += 1;
|
||||
if (tickCount == calibrationTickCount) { // about 10 seconds
|
||||
final Duration elapsed = new DateTime.now().difference(startTime);
|
||||
final Duration elapsed = DateTime.now().difference(startTime);
|
||||
ticker.stop();
|
||||
ticker.dispose();
|
||||
setState(() {
|
||||
@ -118,7 +118,7 @@ Press play to produce texture frames.''';
|
||||
}
|
||||
});
|
||||
ticker.start();
|
||||
startTime = new DateTime.now();
|
||||
startTime = DateTime.now();
|
||||
setState(() {
|
||||
_summary = 'Calibrating...';
|
||||
_icon = null;
|
||||
@ -128,23 +128,23 @@ Press play to produce texture frames.''';
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_widgetBuilds += 1;
|
||||
return new MaterialApp(
|
||||
home: new Scaffold(
|
||||
body: new Center(
|
||||
child: new Column(
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
Container(
|
||||
width: 300.0,
|
||||
height: 200.0,
|
||||
child: const Texture(textureId: 0),
|
||||
),
|
||||
new Container(
|
||||
Container(
|
||||
width: 300.0,
|
||||
height: 60.0,
|
||||
color: Colors.grey,
|
||||
child: new Center(
|
||||
child: new Text(
|
||||
child: Center(
|
||||
child: Text(
|
||||
_summary,
|
||||
key: const ValueKey<String>('summary'),
|
||||
),
|
||||
@ -153,9 +153,9 @@ Press play to produce texture frames.''';
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: _icon == null ? null : new FloatingActionButton(
|
||||
floatingActionButton: _icon == null ? null : FloatingActionButton(
|
||||
key: const ValueKey<String>('fab'),
|
||||
child: new Icon(_icon),
|
||||
child: Icon(_icon),
|
||||
onPressed: _nextState,
|
||||
),
|
||||
),
|
||||
|
@ -7,8 +7,8 @@ import 'dart:async';
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
|
||||
final RegExp calibrationRegExp = new RegExp('Flutter frame rate is (.*)fps');
|
||||
final RegExp statsRegExp = new RegExp('Produced: (.*)fps\nConsumed: (.*)fps\nWidget builds: (.*)');
|
||||
final RegExp calibrationRegExp = RegExp('Flutter frame rate is (.*)fps');
|
||||
final RegExp statsRegExp = RegExp('Produced: (.*)fps\nConsumed: (.*)fps\nWidget builds: (.*)');
|
||||
const Duration samplingTime = Duration(seconds: 8);
|
||||
|
||||
Future<Null> main() async {
|
||||
@ -38,7 +38,7 @@ Future<Null> main() async {
|
||||
|
||||
// Texture frame stats at 0.5x Flutter frame rate
|
||||
await driver.tap(fab);
|
||||
await new Future<Null>.delayed(samplingTime);
|
||||
await Future<Null>.delayed(samplingTime);
|
||||
await driver.tap(fab);
|
||||
|
||||
final String statsSlow = await driver.getText(summary);
|
||||
@ -50,7 +50,7 @@ Future<Null> main() async {
|
||||
|
||||
// Texture frame stats at 2.0x Flutter frame rate
|
||||
await driver.tap(fab);
|
||||
await new Future<Null>.delayed(samplingTime);
|
||||
await Future<Null>.delayed(samplingTime);
|
||||
await driver.tap(fab);
|
||||
|
||||
final String statsFast = await driver.getText(summary);
|
||||
|
@ -4,12 +4,12 @@ import 'package:flutter_driver/driver_extension.dart';
|
||||
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
runApp(new Center(child: new Flavor()));
|
||||
runApp(Center(child: Flavor()));
|
||||
}
|
||||
|
||||
class Flavor extends StatefulWidget {
|
||||
@override
|
||||
_FlavorState createState() => new _FlavorState();
|
||||
_FlavorState createState() => _FlavorState();
|
||||
}
|
||||
|
||||
class _FlavorState extends State<Flavor> {
|
||||
@ -27,11 +27,11 @@ class _FlavorState extends State<Flavor> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Directionality(
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: _flavor == null
|
||||
? const Text('Awaiting flavor...')
|
||||
: new Text(_flavor, key: const ValueKey<String>('flavor')),
|
||||
: Text(_flavor, key: const ValueKey<String>('flavor')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,12 @@ import 'src/test_step.dart';
|
||||
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
runApp(new TestApp());
|
||||
runApp(TestApp());
|
||||
}
|
||||
|
||||
class TestApp extends StatefulWidget {
|
||||
@override
|
||||
_TestAppState createState() => new _TestAppState();
|
||||
_TestAppState createState() => _TestAppState();
|
||||
}
|
||||
|
||||
class _TestAppState extends State<TestApp> {
|
||||
@ -37,7 +37,7 @@ class _TestAppState extends State<TestApp> {
|
||||
if (_step < steps.length)
|
||||
_result = steps[_step++]();
|
||||
else
|
||||
_result = new Future<TestStepResult>.value(TestStepResult.complete);
|
||||
_result = Future<TestStepResult>.value(TestStepResult.complete);
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,25 +45,25 @@ class _TestAppState extends State<TestApp> {
|
||||
BuildContext context,
|
||||
AsyncSnapshot<TestStepResult> snapshot,
|
||||
) {
|
||||
return new TestStepResult.fromSnapshot(snapshot).asWidget(context);
|
||||
return TestStepResult.fromSnapshot(snapshot).asWidget(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Platform Interaction Test',
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Platform Interaction Test'),
|
||||
),
|
||||
body: new Padding(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: new FutureBuilder<TestStepResult>(
|
||||
child: FutureBuilder<TestStepResult>(
|
||||
future: _result,
|
||||
builder: _buildTestResultWidget,
|
||||
),
|
||||
),
|
||||
floatingActionButton: new FloatingActionButton(
|
||||
floatingActionButton: FloatingActionButton(
|
||||
key: const ValueKey<String>('step'),
|
||||
onPressed: _executeNextStep,
|
||||
child: const Icon(Icons.navigate_next),
|
||||
|
@ -12,7 +12,7 @@ Future<TestStepResult> systemNavigatorPop() {
|
||||
StringCodec(),
|
||||
);
|
||||
|
||||
final Completer<TestStepResult> completer = new Completer<TestStepResult>();
|
||||
final Completer<TestStepResult> completer = Completer<TestStepResult>();
|
||||
|
||||
channel.setMessageHandler((String message) async {
|
||||
completer.complete(
|
||||
|
@ -46,15 +46,15 @@ class TestStepResult {
|
||||
final TestStatus status;
|
||||
|
||||
Widget asWidget(BuildContext context) {
|
||||
return new Column(
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text('Step: $name', style: bold),
|
||||
new Text(description),
|
||||
Text('Step: $name', style: bold),
|
||||
Text(description),
|
||||
const Text(' '),
|
||||
new Text(
|
||||
Text(
|
||||
status.toString().substring('TestStatus.'.length),
|
||||
key: new ValueKey<String>(
|
||||
key: ValueKey<String>(
|
||||
status == TestStatus.pending ? 'nostatus' : 'status'),
|
||||
style: bold,
|
||||
),
|
||||
|
@ -15,7 +15,7 @@ void main() {
|
||||
await WidgetsBinding.instance.reassembleApplication();
|
||||
return log;
|
||||
});
|
||||
runApp(new MaterialApp(home: const Test()));
|
||||
runApp(MaterialApp(home: const Test()));
|
||||
}
|
||||
|
||||
class Test extends SingleChildRenderObjectWidget {
|
||||
@ -23,7 +23,7 @@ class Test extends SingleChildRenderObjectWidget {
|
||||
|
||||
@override
|
||||
RenderTest createRenderObject(BuildContext context) {
|
||||
return new RenderTest();
|
||||
return RenderTest();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,13 @@ import 'package:flutter_driver/driver_extension.dart';
|
||||
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
runApp(new DriverTestApp());
|
||||
runApp(DriverTestApp());
|
||||
}
|
||||
|
||||
class DriverTestApp extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return new DriverTestAppState();
|
||||
return DriverTestAppState();
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,20 +24,20 @@ class DriverTestAppState extends State<DriverTestApp> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('FlutterDriver test'),
|
||||
),
|
||||
body: new ListView(
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
children: <Widget>[
|
||||
new Row(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new Text(present ? 'present' : 'absent'),
|
||||
Expanded(
|
||||
child: Text(present ? 'present' : 'absent'),
|
||||
),
|
||||
new RaisedButton(
|
||||
RaisedButton(
|
||||
child: const Text(
|
||||
'toggle',
|
||||
key: ValueKey<String>('togglePresent'),
|
||||
@ -50,12 +50,12 @@ class DriverTestAppState extends State<DriverTestApp> {
|
||||
),
|
||||
],
|
||||
),
|
||||
new Row(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
const Expanded(
|
||||
child: Text('hit testability'),
|
||||
),
|
||||
new DropdownButton<Letter>(
|
||||
DropdownButton<Letter>(
|
||||
key: const ValueKey<String>('dropdown'),
|
||||
value: _selectedValue,
|
||||
onChanged: (Letter newValue) {
|
||||
|
@ -12,49 +12,49 @@ void main() {
|
||||
// TODO(cbernaschina): remove when test flakiness is resolved
|
||||
return 'keyboard_resize';
|
||||
});
|
||||
runApp(new MyApp());
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Text Editing',
|
||||
theme: new ThemeData(primarySwatch: Colors.blue),
|
||||
home: new MyHomePage(),
|
||||
theme: ThemeData(primarySwatch: Colors.blue),
|
||||
home: MyHomePage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
@override
|
||||
_MyHomePageState createState() => new _MyHomePageState();
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
final TextEditingController _controller = new TextEditingController();
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TextField textField = new TextField(
|
||||
final TextField textField = TextField(
|
||||
key: const Key(keys.kDefaultTextField),
|
||||
controller: _controller,
|
||||
focusNode: new FocusNode(),
|
||||
focusNode: FocusNode(),
|
||||
);
|
||||
return new Scaffold(
|
||||
body: new Stack(
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: <Widget>[
|
||||
new LayoutBuilder(
|
||||
LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return new Center(child: new Text('${constraints.biggest.height}', key: const Key(keys.kHeightText)));
|
||||
return Center(child: Text('${constraints.biggest.height}', key: const Key(keys.kHeightText)));
|
||||
}
|
||||
),
|
||||
textField,
|
||||
],
|
||||
),
|
||||
floatingActionButton: new FloatingActionButton(
|
||||
floatingActionButton: FloatingActionButton(
|
||||
key: const Key(keys.kUnfocusButton),
|
||||
onPressed: () { textField.focusNode.unfocus(); },
|
||||
tooltip: 'Unfocus',
|
||||
|
@ -10,27 +10,27 @@ import 'keys.dart' as keys;
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
|
||||
runApp(new MyApp());
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Keyboard & TextField',
|
||||
theme: new ThemeData(primarySwatch: Colors.blue),
|
||||
home: new MyHomePage(),
|
||||
theme: ThemeData(primarySwatch: Colors.blue),
|
||||
home: MyHomePage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
@override
|
||||
_MyHomePageState createState() => new _MyHomePageState();
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
final ScrollController _controller = new ScrollController();
|
||||
final ScrollController _controller = ScrollController();
|
||||
double offset = 0.0;
|
||||
|
||||
@override
|
||||
@ -45,18 +45,18 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
body: new Column(
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
new Text('$offset',
|
||||
Text('$offset',
|
||||
key: const ValueKey<String>(keys.kOffsetText),
|
||||
),
|
||||
new Expanded(
|
||||
child: new ListView(
|
||||
Expanded(
|
||||
child: ListView(
|
||||
key: const ValueKey<String>(keys.kListView),
|
||||
controller: _controller,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
),
|
||||
const TextField(
|
||||
|
@ -12,12 +12,12 @@ import 'package:flutter_driver/driver_extension.dart';
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
|
||||
runApp(new Toggler());
|
||||
runApp(Toggler());
|
||||
}
|
||||
|
||||
class Toggler extends StatefulWidget {
|
||||
@override
|
||||
State<Toggler> createState() => new TogglerState();
|
||||
State<Toggler> createState() => TogglerState();
|
||||
}
|
||||
|
||||
class TogglerState extends State<Toggler> {
|
||||
@ -25,15 +25,15 @@ class TogglerState extends State<Toggler> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('FlutterDriver test'),
|
||||
),
|
||||
body: new Material(
|
||||
child: new Column(
|
||||
body: Material(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
new FlatButton(
|
||||
FlatButton(
|
||||
key: const ValueKey<String>('toggle'),
|
||||
child: const Text('Toggle visibility'),
|
||||
onPressed: () {
|
||||
@ -42,8 +42,8 @@ class TogglerState extends State<Toggler> {
|
||||
});
|
||||
},
|
||||
),
|
||||
new Expanded(
|
||||
child: new ListView(
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: _buildRows(_visible ? 10 : 0),
|
||||
),
|
||||
),
|
||||
@ -56,8 +56,8 @@ class TogglerState extends State<Toggler> {
|
||||
}
|
||||
|
||||
List<Widget> _buildRows(int count) {
|
||||
return new List<Widget>.generate(count, (int i) {
|
||||
return new Row(
|
||||
return List<Widget>.generate(count, (int i) {
|
||||
return Row(
|
||||
children: _buildCells(i / count),
|
||||
);
|
||||
});
|
||||
@ -66,12 +66,12 @@ List<Widget> _buildRows(int count) {
|
||||
/// Builds cells that are known to take time to render causing a delay on the
|
||||
/// GPU thread.
|
||||
List<Widget> _buildCells(double epsilon) {
|
||||
return new List<Widget>.generate(15, (int i) {
|
||||
return new Expanded(
|
||||
child: new Material(
|
||||
return List<Widget>.generate(15, (int i) {
|
||||
return Expanded(
|
||||
child: Material(
|
||||
// A magic color that the test will be looking for on the screenshot.
|
||||
color: const Color(0xffff0102),
|
||||
borderRadius: new BorderRadius.all(new Radius.circular(i.toDouble() + epsilon)),
|
||||
borderRadius: BorderRadius.all(Radius.circular(i.toDouble() + epsilon)),
|
||||
elevation: 5.0,
|
||||
child: const SizedBox(height: 10.0, width: 10.0),
|
||||
),
|
||||
|
@ -36,14 +36,14 @@ void main() {
|
||||
|
||||
test('waitForAbsent should resolve when text "present" disappears', () async {
|
||||
// Begin waiting for it to disappear
|
||||
final Completer<Null> whenWaitForAbsentResolves = new Completer<Null>();
|
||||
final Completer<Null> whenWaitForAbsentResolves = Completer<Null>();
|
||||
driver.waitForAbsent(presentText).then(
|
||||
whenWaitForAbsentResolves.complete,
|
||||
onError: whenWaitForAbsentResolves.completeError,
|
||||
);
|
||||
|
||||
// Wait 1 second then make it disappear
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await driver.tap(find.byValueKey('togglePresent'));
|
||||
|
||||
// Ensure waitForAbsent resolves
|
||||
@ -61,14 +61,14 @@ void main() {
|
||||
|
||||
test('waitFor should resolve when text "present" reappears', () async {
|
||||
// Begin waiting for it to reappear
|
||||
final Completer<Null> whenWaitForResolves = new Completer<Null>();
|
||||
final Completer<Null> whenWaitForResolves = Completer<Null>();
|
||||
driver.waitFor(presentText).then(
|
||||
whenWaitForResolves.complete,
|
||||
onError: whenWaitForResolves.completeError,
|
||||
);
|
||||
|
||||
// Wait 1 second then make it appear
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await driver.tap(find.byValueKey('togglePresent'));
|
||||
|
||||
// Ensure waitFor resolves
|
||||
|
@ -33,7 +33,7 @@ void main() {
|
||||
final SerializableFinder defaultTextField = find.byValueKey(keys.kDefaultTextField);
|
||||
await driver.waitFor(defaultTextField);
|
||||
await driver.tap(defaultTextField);
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
|
||||
// Measure the height with keyboard displayed.
|
||||
final String heightWithKeyboardShown = await driver.getText(heightText);
|
||||
@ -43,7 +43,7 @@ void main() {
|
||||
final SerializableFinder unfocusButton = find.byValueKey(keys.kUnfocusButton);
|
||||
await driver.waitFor(unfocusButton);
|
||||
await driver.tap(unfocusButton);
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
|
||||
// Measure the final height.
|
||||
final String endHeight = await driver.getText(heightText);
|
||||
|
@ -41,7 +41,7 @@ void main() {
|
||||
|
||||
// Bring up keyboard
|
||||
await driver.tap(textFieldFinder);
|
||||
await new Future<Null>.delayed(const Duration(seconds: 1));
|
||||
await Future<Null>.delayed(const Duration(seconds: 1));
|
||||
|
||||
// Ensure that TextField is visible again
|
||||
await driver.waitFor(textFieldFinder);
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
||||
class AnimatedIconsTestApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
return MaterialApp(
|
||||
title: 'Animated Icons Test',
|
||||
home: const Scaffold(
|
||||
body: IconsList(),
|
||||
@ -21,8 +21,8 @@ class IconsList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new ListView(
|
||||
children: samples.map((IconSample s) => new IconSampleRow(s)).toList(),
|
||||
return ListView(
|
||||
children: samples.map((IconSample s) => IconSampleRow(s)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ class IconSampleRow extends StatefulWidget {
|
||||
final IconSample sample;
|
||||
|
||||
@override
|
||||
State createState() => new IconSampleRowState();
|
||||
State createState() => IconSampleRowState();
|
||||
}
|
||||
|
||||
class IconSampleRowState extends State<IconSampleRow> with SingleTickerProviderStateMixin {
|
||||
@ -41,17 +41,17 @@ class IconSampleRowState extends State<IconSampleRow> with SingleTickerProviderS
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new ListTile(
|
||||
leading: new InkWell(
|
||||
return ListTile(
|
||||
leading: InkWell(
|
||||
onTap: () { progress.forward(from: 0.0); },
|
||||
child: new AnimatedIcon(
|
||||
child: AnimatedIcon(
|
||||
icon: widget.sample.icon,
|
||||
progress: progress,
|
||||
color: Colors.lightBlue,
|
||||
),
|
||||
),
|
||||
title: new Text(widget.sample.description),
|
||||
subtitle: new Slider(
|
||||
title: Text(widget.sample.description),
|
||||
subtitle: Slider(
|
||||
value: progress.value,
|
||||
onChanged: (double v) { progress.animateTo(v, duration: Duration.zero); },
|
||||
),
|
||||
@ -61,7 +61,7 @@ class IconSampleRowState extends State<IconSampleRow> with SingleTickerProviderS
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
progress = new AnimationController(vsync: this, duration: const Duration(milliseconds: 300));
|
||||
progress = AnimationController(vsync: this, duration: const Duration(milliseconds: 300));
|
||||
progress.addListener(_handleChange);
|
||||
}
|
||||
|
||||
@ -105,4 +105,4 @@ class IconSample {
|
||||
final String description;
|
||||
}
|
||||
|
||||
void main() => runApp(new AnimatedIconsTestApp());
|
||||
void main() => runApp(AnimatedIconsTestApp());
|
||||
|
@ -9,18 +9,18 @@ import 'package:flutter/rendering.dart' show debugDumpRenderTree;
|
||||
|
||||
class CardModel {
|
||||
CardModel(this.value, this.height) {
|
||||
textController = new TextEditingController(text: 'Item $value');
|
||||
textController = TextEditingController(text: 'Item $value');
|
||||
}
|
||||
int value;
|
||||
double height;
|
||||
int get color => ((value % 9) + 1) * 100;
|
||||
TextEditingController textController;
|
||||
Key get key => new ObjectKey(this);
|
||||
Key get key => ObjectKey(this);
|
||||
}
|
||||
|
||||
class CardCollection extends StatefulWidget {
|
||||
@override
|
||||
CardCollectionState createState() => new CardCollectionState();
|
||||
CardCollectionState createState() => CardCollectionState();
|
||||
}
|
||||
|
||||
class CardCollectionState extends State<CardCollection> {
|
||||
@ -51,7 +51,7 @@ class CardCollectionState extends State<CardCollection> {
|
||||
void _updateCardSizes() {
|
||||
if (_fixedSizeCards)
|
||||
return;
|
||||
_cardModels = new List<CardModel>.generate(
|
||||
_cardModels = List<CardModel>.generate(
|
||||
_cardModels.length,
|
||||
(int i) {
|
||||
_cardModels[i].height = _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i];
|
||||
@ -61,17 +61,17 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
void _initVariableSizedCardModels() {
|
||||
_cardModels = new List<CardModel>.generate(
|
||||
_cardModels = List<CardModel>.generate(
|
||||
_cardHeights.length,
|
||||
(int i) => new CardModel(i, _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i])
|
||||
(int i) => CardModel(i, _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i])
|
||||
);
|
||||
}
|
||||
|
||||
void _initFixedSizedCardModels() {
|
||||
const int cardCount = 27;
|
||||
_cardModels = new List<CardModel>.generate(
|
||||
_cardModels = List<CardModel>.generate(
|
||||
cardCount,
|
||||
(int i) => new CardModel(i, kFixedCardHeight),
|
||||
(int i) => CardModel(i, kFixedCardHeight),
|
||||
);
|
||||
}
|
||||
|
||||
@ -97,10 +97,10 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget _buildDrawer() {
|
||||
return new Drawer(
|
||||
child: new IconTheme(
|
||||
return Drawer(
|
||||
child: IconTheme(
|
||||
data: const IconThemeData(color: Colors.black),
|
||||
child: new ListView(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
const DrawerHeader(child: Center(child: Text('Options'))),
|
||||
buildDrawerCheckbox('Make card labels editable', _editable, _toggleEditable),
|
||||
@ -121,7 +121,7 @@ class CardCollectionState extends State<CardCollection> {
|
||||
buildFontRadioItem('Center-align text', TextAlign.center, _textAlign, _changeTextAlign, icon: Icons.format_align_center, enabled: !_editable),
|
||||
buildFontRadioItem('Right-align text', TextAlign.right, _textAlign, _changeTextAlign, icon: Icons.format_align_right, enabled: !_editable),
|
||||
const Divider(),
|
||||
new ListTile(
|
||||
ListTile(
|
||||
leading: const Icon(Icons.dvr),
|
||||
onTap: () { debugDumpApp(); debugDumpRenderTree(); },
|
||||
title: const Text('Dump App to Console'),
|
||||
@ -182,10 +182,10 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget buildDrawerCheckbox(String label, bool value, void callback(), { bool enabled = true }) {
|
||||
return new ListTile(
|
||||
return ListTile(
|
||||
onTap: enabled ? callback : null,
|
||||
title: new Text(label),
|
||||
trailing: new Checkbox(
|
||||
title: Text(label),
|
||||
trailing: Checkbox(
|
||||
value: value,
|
||||
onChanged: enabled ? (_) { callback(); } : null,
|
||||
),
|
||||
@ -193,11 +193,11 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget buildDrawerColorRadioItem(String label, MaterialColor itemValue, MaterialColor currentValue, ValueChanged<MaterialColor> onChanged, { IconData icon, bool enabled = true }) {
|
||||
return new ListTile(
|
||||
leading: new Icon(icon),
|
||||
title: new Text(label),
|
||||
return ListTile(
|
||||
leading: Icon(icon),
|
||||
title: Text(label),
|
||||
onTap: enabled ? () { onChanged(itemValue); } : null,
|
||||
trailing: new Radio<MaterialColor>(
|
||||
trailing: Radio<MaterialColor>(
|
||||
value: itemValue,
|
||||
groupValue: currentValue,
|
||||
onChanged: enabled ? onChanged : null,
|
||||
@ -206,11 +206,11 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { IconData icon, bool enabled = true }) {
|
||||
return new ListTile(
|
||||
leading: new Icon(icon),
|
||||
title: new Text(label),
|
||||
return ListTile(
|
||||
leading: Icon(icon),
|
||||
title: Text(label),
|
||||
onTap: enabled ? () { onChanged(itemValue); } : null,
|
||||
trailing: new Radio<DismissDirection>(
|
||||
trailing: Radio<DismissDirection>(
|
||||
value: itemValue,
|
||||
groupValue: currentValue,
|
||||
onChanged: enabled ? onChanged : null,
|
||||
@ -219,11 +219,11 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget buildFontRadioItem(String label, TextAlign itemValue, TextAlign currentValue, ValueChanged<TextAlign> onChanged, { IconData icon, bool enabled = true }) {
|
||||
return new ListTile(
|
||||
leading: new Icon(icon),
|
||||
title: new Text(label),
|
||||
return ListTile(
|
||||
leading: Icon(icon),
|
||||
title: Text(label),
|
||||
onTap: enabled ? () { onChanged(itemValue); } : null,
|
||||
trailing: new Radio<TextAlign>(
|
||||
trailing: Radio<TextAlign>(
|
||||
value: itemValue,
|
||||
groupValue: currentValue,
|
||||
onChanged: enabled ? onChanged : null,
|
||||
@ -232,34 +232,34 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
Widget _buildAppBar(BuildContext context) {
|
||||
return new AppBar(
|
||||
return AppBar(
|
||||
actions: <Widget>[
|
||||
new Text(_dismissDirectionText(_dismissDirection))
|
||||
Text(_dismissDirectionText(_dismissDirection))
|
||||
],
|
||||
flexibleSpace: new Container(
|
||||
flexibleSpace: Container(
|
||||
padding: const EdgeInsets.only(left: 72.0),
|
||||
height: 128.0,
|
||||
alignment: const Alignment(-1.0, 0.5),
|
||||
child: new Text('Swipe Away: ${_cardModels.length}', style: Theme.of(context).primaryTextTheme.title),
|
||||
child: Text('Swipe Away: ${_cardModels.length}', style: Theme.of(context).primaryTextTheme.title),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCard(BuildContext context, int index) {
|
||||
final CardModel cardModel = _cardModels[index];
|
||||
final Widget card = new Dismissible(
|
||||
key: new ObjectKey(cardModel),
|
||||
final Widget card = Dismissible(
|
||||
key: ObjectKey(cardModel),
|
||||
direction: _dismissDirection,
|
||||
onDismissed: (DismissDirection direction) { dismissCard(cardModel); },
|
||||
child: new Card(
|
||||
child: Card(
|
||||
color: _primaryColor[cardModel.color],
|
||||
child: new Container(
|
||||
child: Container(
|
||||
height: cardModel.height,
|
||||
padding: const EdgeInsets.all(kCardMargins),
|
||||
child: _editable ?
|
||||
new Center(
|
||||
child: new TextField(
|
||||
key: new GlobalObjectKey(cardModel),
|
||||
Center(
|
||||
child: TextField(
|
||||
key: GlobalObjectKey(cardModel),
|
||||
controller: cardModel.textController,
|
||||
),
|
||||
)
|
||||
@ -267,11 +267,11 @@ class CardCollectionState extends State<CardCollection> {
|
||||
style: cardLabelStyle.copyWith(
|
||||
fontSize: _varyFontSizes ? 5.0 + index : null
|
||||
),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(cardModel.textController.text, textAlign: _textAlign),
|
||||
Text(cardModel.textController.text, textAlign: _textAlign),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -297,12 +297,12 @@ class CardCollectionState extends State<CardCollection> {
|
||||
// TODO(abarth): This icon is wrong in RTL.
|
||||
Widget leftArrowIcon = const Icon(Icons.arrow_back, size: 36.0);
|
||||
if (_dismissDirection == DismissDirection.startToEnd)
|
||||
leftArrowIcon = new Opacity(opacity: 0.1, child: leftArrowIcon);
|
||||
leftArrowIcon = Opacity(opacity: 0.1, child: leftArrowIcon);
|
||||
|
||||
// TODO(abarth): This icon is wrong in RTL.
|
||||
Widget rightArrowIcon = const Icon(Icons.arrow_forward, size: 36.0);
|
||||
if (_dismissDirection == DismissDirection.endToStart)
|
||||
rightArrowIcon = new Opacity(opacity: 0.1, child: rightArrowIcon);
|
||||
rightArrowIcon = Opacity(opacity: 0.1, child: rightArrowIcon);
|
||||
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final TextStyle backgroundTextStyle = theme.primaryTextTheme.title;
|
||||
@ -312,18 +312,18 @@ class CardCollectionState extends State<CardCollection> {
|
||||
// size of the background,card Stack will be based only on the card. The
|
||||
// Viewport ensures that when the card's resize animation occurs, the
|
||||
// background (text and icons) will just be clipped, not resized.
|
||||
final Widget background = new Positioned.fill(
|
||||
child: new Container(
|
||||
final Widget background = Positioned.fill(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(4.0),
|
||||
child: new SingleChildScrollView(
|
||||
child: new Container(
|
||||
child: SingleChildScrollView(
|
||||
child: Container(
|
||||
height: cardModel.height,
|
||||
color: theme.primaryColor,
|
||||
child: new Row(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
leftArrowIcon,
|
||||
new Expanded(
|
||||
child: new Text(backgroundMessage,
|
||||
Expanded(
|
||||
child: Text(backgroundMessage,
|
||||
style: backgroundTextStyle,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@ -336,10 +336,10 @@ class CardCollectionState extends State<CardCollection> {
|
||||
),
|
||||
);
|
||||
|
||||
return new IconTheme(
|
||||
return IconTheme(
|
||||
key: cardModel.key,
|
||||
data: const IconThemeData(color: Colors.white),
|
||||
child: new Stack(children: <Widget>[background, card]),
|
||||
child: Stack(children: <Widget>[background, card]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -355,32 +355,32 @@ class CardCollectionState extends State<CardCollection> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget cardCollection = new ListView.builder(
|
||||
Widget cardCollection = ListView.builder(
|
||||
itemExtent: _fixedSizeCards ? kFixedCardHeight : null,
|
||||
itemCount: _cardModels.length,
|
||||
itemBuilder: _buildCard,
|
||||
);
|
||||
|
||||
if (_sunshine) {
|
||||
cardCollection = new Stack(
|
||||
cardCollection = Stack(
|
||||
children: <Widget>[
|
||||
new Column(children: <Widget>[new Image.network(_sunshineURL)]),
|
||||
new ShaderMask(child: cardCollection, shaderCallback: _createShader),
|
||||
Column(children: <Widget>[Image.network(_sunshineURL)]),
|
||||
ShaderMask(child: cardCollection, shaderCallback: _createShader),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final Widget body = new Container(
|
||||
final Widget body = Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
|
||||
color: _primaryColor.shade50,
|
||||
child: cardCollection,
|
||||
);
|
||||
|
||||
return new Theme(
|
||||
data: new ThemeData(
|
||||
return Theme(
|
||||
data: ThemeData(
|
||||
primarySwatch: _primaryColor,
|
||||
),
|
||||
child: new Scaffold(
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
drawer: _buildDrawer(),
|
||||
body: body,
|
||||
@ -390,8 +390,8 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
|
||||
void main() {
|
||||
runApp(new MaterialApp(
|
||||
runApp(MaterialApp(
|
||||
title: 'Cards',
|
||||
home: new CardCollection(),
|
||||
home: CardCollection(),
|
||||
));
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user