plugin_tests.dart 3.17 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
// Copyright (c) 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 '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 28
/// Defines task that creates new Flutter project, adds a plugin, and then
/// builds the specified [buildTarget].
class PluginTest {
29 30
  PluginTest(this.buildTarget, this.options);

31
  final String buildTarget;
32
  final List<String> options;
33 34 35

  Future<TaskResult> call() async {
    section('Create Flutter project');
36
    final Directory tempDir = Directory.systemTemp.createTempSync('flutter_devicelab_plugin_test.');
37
    try {
38 39 40 41 42 43 44 45 46 47 48
      final FlutterProject project = await FlutterProject.create(tempDir, options);
      try {
        if (buildTarget == 'ios')
          await prepareProvisioningCertificates(project.rootPath);
        section('Add plugin');
        await project.addPlugin('path_provider');
        section('Build');
        await project.build(buildTarget);
      } finally {
        await project.delete();
      }
49
      return TaskResult.success(null);
50
    } catch (e) {
51
      return TaskResult.failure(e.toString());
52
    } finally {
53
      rmTree(tempDir);
54 55 56 57 58 59 60 61 62 63
    }
  }
}

class FlutterProject {
  FlutterProject(this.parent, this.name);

  final Directory parent;
  final String name;

64
  static Future<FlutterProject> create(Directory directory, List<String> options) async {
65
    await inDirectory(directory, () async {
66 67
      await flutter(
        'create',
68
        options: <String>['--template=app', '--org', 'io.flutter.devicelab', ...options, 'plugintest'],
69
      );
70
    });
71
    return FlutterProject(directory, 'plugintest');
72 73 74 75
  }

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

76
  Future<void> addPlugin(String plugin) async {
77
    final File pubspec = File(path.join(rootPath, 'pubspec.yaml'));
78 79 80 81 82 83 84 85
    String content = await pubspec.readAsString();
    content = content.replaceFirst(
      '\ndependencies:\n',
      '\ndependencies:\n  $plugin:\n',
    );
    await pubspec.writeAsString(content, flush: true);
  }

86
  Future<void> build(String target) async {
87
    await inDirectory(Directory(rootPath), () async {
88 89 90 91
      await flutter('build', options: <String>[target]);
    });
  }

92
  Future<void> delete() async {
93 94 95
    if (Platform.isWindows) {
      // A running Gradle daemon might prevent us from deleting the project
      // folder on Windows.
96 97 98 99 100
      await exec(
        path.absolute(path.join(rootPath, 'android', 'gradlew.bat')),
        <String>['--stop'],
        canFail: true,
      );
101
      // TODO(ianh): Investigating if flakiness is timing dependent.
102
      await Future<void>.delayed(const Duration(seconds: 10));
103
    }
104
    rmTree(parent);
105 106
  }
}