// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'package:file/file.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:test/test.dart'; import 'package:vm_service_client/vm_service_client.dart'; import '../src/context.dart'; import 'flutter_test_driver.dart'; import 'util.dart'; Directory _tempDir; FlutterTestDriver _flutter; void main() { setUp(() async { _tempDir = await fs.systemTempDirectory.createTemp('test_app'); await _setupSampleProject(); _flutter = new FlutterTestDriver(_tempDir); }); tearDown(() async { try { await _flutter.stop(); _tempDir?.deleteSync(recursive: true); _tempDir = null; } catch (e) { // Don't fail tests if we failed to clean up temp folder. } }); Future<VMIsolate> breakInBuildMethod(FlutterTestDriver flutter) async { return _flutter.breakAt( fs.path.join(_tempDir.path, 'lib', 'main.dart'), 9 ); } Future<VMIsolate> breakInTopLevelFunction(FlutterTestDriver flutter) async { return _flutter.breakAt( fs.path.join(_tempDir.path, 'lib', 'main.dart'), 17 ); } group('FlutterTesterDevice', () { testUsingContext('can hot reload', () async { await _flutter.run(); await _flutter.hotReload(); }, skip: true); // https://github.com/flutter/flutter/issues/17833 testUsingContext('can hit breakpoints with file:// prefixes after reload', () async { await _flutter.run(withDebugger: true); // Add the breakpoint using a file:// URI. await _flutter.addBreakpoint( // Test currently passes with a FS path, but not with file:// URI. // fs.path.join(_tempDir.path, 'lib', 'main.dart'), new Uri.file(fs.path.join(_tempDir.path, 'lib', 'main.dart')).toString(), 9 ); await _flutter.hotReload(); // Ensure we hit the breakpoint. final VMIsolate isolate = await _flutter.waitForBreakpointHit(); expect(isolate.pauseEvent, const isInstanceOf<VMPauseBreakpointEvent>()); }, skip: true); // https://github.com/flutter/flutter/issues/18441 Future<void> evaluateTrivialExpressions() async { VMInstanceRef res; res = await _flutter.evaluateExpression('"test"'); expect(res is VMStringInstanceRef && res.value == 'test', isTrue); res = await _flutter.evaluateExpression('"test"'); expect(res is VMIntInstanceRef && res.value == 1, isTrue); res = await _flutter.evaluateExpression('"test"'); expect(res is VMBoolInstanceRef && res.value == true, isTrue); } Future<void> evaluateComplexExpressions() async { final VMInstanceRef res = await _flutter.evaluateExpression('new DateTime.now().year'); expect(res is VMIntInstanceRef && res.value == new DateTime.now().year, isTrue); } Future<void> evaluateComplexReturningExpressions() async { final DateTime now = new DateTime.now(); final VMInstanceRef resp = await _flutter.evaluateExpression('new DateTime.now()'); expect(resp.klass.name, equals('DateTime')); final DateTime value = await resp.getValue(); // Ensure we got a reasonable approximation. The more accurate we try to // make this, the more likely it'll fail due to differences in the time // in the remote VM and the local VM. expect('${value.year}-${value.month}-${value.day}', equals('${now.year}-${now.month}-${now.day}')); } testUsingContext('can evaluate trivial expressions in top level function', () async { await _flutter.run(withDebugger: true); await breakInTopLevelFunction(_flutter); await evaluateTrivialExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 testUsingContext('can evaluate trivial expressions in build method', () async { await _flutter.run(withDebugger: true); await breakInBuildMethod(_flutter); await evaluateTrivialExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 testUsingContext('can evaluate complex expressions in top level function', () async { await _flutter.run(withDebugger: true); await breakInTopLevelFunction(_flutter); await evaluateTrivialExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 testUsingContext('can evaluate complex expressions in build method', () async { await _flutter.run(withDebugger: true); await breakInBuildMethod(_flutter); await evaluateComplexExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 testUsingContext('can evaluate expressions returning complex objects in top level function', () async { await _flutter.run(withDebugger: true); await breakInTopLevelFunction(_flutter); await evaluateComplexReturningExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 testUsingContext('can evaluate expressions returning complex objects in build method', () async { await _flutter.run(withDebugger: true); await breakInBuildMethod(_flutter); await evaluateComplexReturningExpressions(); }, skip: true); // https://github.com/flutter/flutter/issues/18678 }, timeout: const Timeout.factor(3)); } Future<void> _setupSampleProject() async { writePubspec(_tempDir.path); writePackages(_tempDir.path); await getPackages(_tempDir.path); final String mainPath = fs.path.join(_tempDir.path, 'lib', 'main.dart'); writeFile(mainPath, r''' import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { topLevelFunction(); return new MaterialApp( title: 'Flutter Demo', home: new Container(), ); } } topLevelFunction() { print("test"); } '''); }