Line data Source code
1 : // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 : // for details. All rights reserved. Use of this source code is governed by a
3 : // BSD-style license that can be found in the LICENSE file.
4 :
5 : import 'dart:async';
6 :
7 : import 'package:async/async.dart';
8 :
9 : import '../backend/group.dart';
10 : import '../backend/operating_system.dart';
11 : import '../backend/suite.dart';
12 : import '../backend/test.dart';
13 : import '../backend/test_platform.dart';
14 : import '../utils.dart';
15 : import 'configuration/suite.dart';
16 : import 'environment.dart';
17 :
18 : /// A suite produced and consumed by the test runner that has runner-specific
19 : /// logic and lifecycle management.
20 : ///
21 : /// This is separated from [Suite] because the backend library (which will
22 : /// eventually become its own package) is primarily for test code itself to use,
23 : /// for which the [RunnerSuite] APIs don't make sense.
24 : ///
25 : /// A [RunnerSuite] can be produced and controlled using a
26 : /// [RunnerSuiteController].
27 : class RunnerSuite extends Suite {
28 : final RunnerSuiteController _controller;
29 :
30 : /// The environment in which this suite runs.
31 0 : Environment get environment => _controller._environment;
32 :
33 : /// The configuration for this suite.
34 10 : SuiteConfiguration get config => _controller._config;
35 :
36 : /// Whether the suite is paused for debugging.
37 : ///
38 : /// When using a dev inspector, this may also mean that the entire browser is
39 : /// paused.
40 0 : bool get isDebugging => _controller._isDebugging;
41 :
42 : /// A broadcast stream that emits an event whenever the suite is paused for
43 : /// debugging or resumed afterwards.
44 : ///
45 : /// The event is `true` when debugging starts and `false` when it ends.
46 0 : Stream<bool> get onDebugging => _controller._onDebuggingController.stream;
47 :
48 : /// A shortcut constructor for creating a [RunnerSuite] that never goes into
49 : /// debugging mode.
50 : factory RunnerSuite(
51 : Environment environment, SuiteConfiguration config, Group group,
52 : {String path,
53 : TestPlatform platform,
54 : OperatingSystem os,
55 : AsyncFunction onClose}) {
56 5 : var controller = new RunnerSuiteController(environment, config, group,
57 : path: path, platform: platform, os: os, onClose: onClose);
58 5 : return controller.suite;
59 : }
60 :
61 : RunnerSuite._(this._controller, Group group, String path,
62 : TestPlatform platform, OperatingSystem os)
63 5 : : super(group, path: path, platform: platform, os: os);
64 :
65 : RunnerSuite filter(bool callback(Test test)) {
66 0 : var filtered = group.filter(callback);
67 0 : filtered ??= new Group.root([], metadata: metadata);
68 0 : return new RunnerSuite._(_controller, filtered, path, platform, os);
69 : }
70 :
71 : /// Closes the suite and releases any resources associated with it.
72 10 : Future close() => _controller._close();
73 : }
74 :
75 : /// A class that exposes and controls a [RunnerSuite].
76 : class RunnerSuiteController {
77 : /// The suite controlled by this controller.
78 5 : RunnerSuite get suite => _suite;
79 : RunnerSuite _suite;
80 :
81 : /// The backing value for [suite.environment].
82 : final Environment _environment;
83 :
84 : /// The configuration for this suite.
85 : final SuiteConfiguration _config;
86 :
87 : /// The function to call when the suite is closed.
88 : final AsyncFunction _onClose;
89 :
90 : /// The backing value for [suite.isDebugging].
91 : bool _isDebugging = false;
92 :
93 : /// The controller for [suite.onDebugging].
94 : final _onDebuggingController = new StreamController<bool>.broadcast();
95 :
96 : RunnerSuiteController(this._environment, this._config, Group group,
97 : {String path,
98 : TestPlatform platform,
99 : OperatingSystem os,
100 : AsyncFunction onClose})
101 5 : : _onClose = onClose {
102 10 : _suite = new RunnerSuite._(this, group, path, platform, os);
103 : }
104 :
105 : /// Sets whether the suite is paused for debugging.
106 : ///
107 : /// If this is different than [suite.isDebugging], this will automatically
108 : /// send out an event along [suite.onDebugging].
109 : void setDebugging(bool debugging) {
110 0 : if (debugging == _isDebugging) return;
111 0 : _isDebugging = debugging;
112 0 : _onDebuggingController.add(debugging);
113 : }
114 :
115 : /// The backing function for [suite.close].
116 10 : Future _close() => _closeMemo.runOnce(() async {
117 10 : _onDebuggingController.close();
118 5 : if (_onClose != null) await _onClose();
119 0 : });
120 : final _closeMemo = new AsyncMemoizer();
121 : }
|