plugin_tests.dart 4.4 KB
Newer Older
1
// Copyright 2018 The Chromium Authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/ios.dart';
import 'package:flutter_devicelab/framework/utils.dart';

13 14 15 16 17 18 19 20 21
/// Combines several TaskFunctions with trivial success value into one.
TaskFunction combine(List<TaskFunction> tasks) {
  return () async {
    for (TaskFunction task in tasks) {
      final TaskResult result = await task();
      if (result.failed) {
        return result;
      }
    }
22
    return TaskResult.success(null);
23 24 25
  };
}

26 27
/// Defines task that creates new Flutter project, adds a local and remote
/// plugin, and then builds the specified [buildTarget].
28
class PluginTest {
29
  PluginTest(this.buildTarget, this.options, { this.pluginCreateEnvironment, this.appCreateEnvironment });
30

31
  final String buildTarget;
32
  final List<String> options;
33 34
  final Map<String, String> pluginCreateEnvironment;
  final Map<String, String> appCreateEnvironment;
35 36

  Future<TaskResult> call() async {
37 38
    final Directory tempDir =
        Directory.systemTemp.createTempSync('flutter_devicelab_plugin_test.');
39
    try {
40 41 42
      section('Create plugin');
      final _FlutterProject plugin = await _FlutterProject.create(
          tempDir, options,
43
          name: 'plugintest', template: 'plugin', environment: pluginCreateEnvironment);
44 45 46 47
      section('Test plugin');
      await plugin.test();
      section('Create Flutter app');
      final _FlutterProject app = await _FlutterProject.create(tempDir, options,
48
          name: 'plugintestapp', template: 'app', environment: appCreateEnvironment);
49 50
      try {
        if (buildTarget == 'ios')
51 52 53 54 55 56 57 58 59
          await prepareProvisioningCertificates(app.rootPath);
        section('Add plugins');
        await app.addPlugin('plugintest',
            pluginPath: path.join('..', 'plugintest'));
        await app.addPlugin('path_provider');
        section('Build app');
        await app.build(buildTarget);
        section('Test app');
        await app.test();
60
      } finally {
61 62
        await plugin.delete();
        await app.delete();
63
      }
64
      return TaskResult.success(null);
65
    } catch (e) {
66
      return TaskResult.failure(e.toString());
67
    } finally {
68
      rmTree(tempDir);
69 70 71 72
    }
  }
}

73 74
class _FlutterProject {
  _FlutterProject(this.parent, this.name);
75 76 77 78 79 80

  final Directory parent;
  final String name;

  String get rootPath => path.join(parent.path, name);

81
  Future<void> addPlugin(String plugin, {String pluginPath}) async {
82
    final File pubspec = File(path.join(rootPath, 'pubspec.yaml'));
83
    String content = await pubspec.readAsString();
84 85
    final String dependency =
        pluginPath != null ? '$plugin:\n    path: $pluginPath' : '$plugin:';
86 87
    content = content.replaceFirst(
      '\ndependencies:\n',
88
      '\ndependencies:\n  $dependency\n',
89 90 91 92
    );
    await pubspec.writeAsString(content, flush: true);
  }

93 94 95 96 97 98 99
  Future<void> test() async {
    await inDirectory(Directory(rootPath), () async {
      await flutter('test');
    });
  }

  static Future<_FlutterProject> create(
100 101 102 103 104 105 106
      Directory directory,
      List<String> options,
      {
        String name,
        String template,
        Map<String, String> environment,
      }) async {
107 108 109 110 111 112 113 114
    await inDirectory(directory, () async {
      await flutter(
        'create',
        options: <String>[
          '--template=$template',
          '--org',
          'io.flutter.devicelab',
          ...options,
115
          name,
116
        ],
117
        environment: environment,
118 119 120 121 122
      );
    });
    return _FlutterProject(directory, name);
  }

123
  Future<void> build(String target) async {
124
    await inDirectory(Directory(rootPath), () async {
125 126 127 128
      await flutter('build', options: <String>[target]);
    });
  }

129
  Future<void> delete() async {
130 131 132
    if (Platform.isWindows) {
      // A running Gradle daemon might prevent us from deleting the project
      // folder on Windows.
133 134 135 136 137
      final String wrapperPath =
          path.absolute(path.join(rootPath, 'android', 'gradlew.bat'));
      if (File(wrapperPath).existsSync()) {
        await exec(wrapperPath, <String>['--stop'], canFail: true);
      }
138
      // TODO(ianh): Investigating if flakiness is timing dependent.
139
      await Future<void>.delayed(const Duration(seconds: 10));
140
    }
141
    rmTree(parent);
142 143
  }
}