"Fossies" - the Fresh Open Source Software Archive

Member "flutter-1.22.4/dev/bots/flutter_compact_formatter.dart" (13 Nov 2020, 8771 Bytes) of package /linux/misc/flutter-1.22.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Dart source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2014 The Flutter Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 import 'dart:convert';
    6 import 'dart:io';
    7 
    8 import 'package:meta/meta.dart';
    9 
   10 final Stopwatch _stopwatch = Stopwatch();
   11 
   12 /// A wrapper around package:test's JSON reporter.
   13 ///
   14 /// This class behaves similarly to the compact reporter, but suppresses all
   15 /// output except for progress until the end of testing. In other words, errors,
   16 /// [print] calls, and skipped test messages will not be printed during the run
   17 /// of the suite.
   18 ///
   19 /// It also processes the JSON data into a collection of [TestResult]s for any
   20 /// other post processing needs, e.g. sending data to analytics.
   21 class FlutterCompactFormatter {
   22   FlutterCompactFormatter() {
   23     _stopwatch.start();
   24   }
   25 
   26   /// Whether to use color escape codes in writing to stdout.
   27   final bool useColor = stdout.supportsAnsiEscapes;
   28 
   29   /// The terminal escape for green text, or the empty string if this is Windows
   30   /// or not outputting to a terminal.
   31   String get _green => useColor ? '\u001b[32m' : '';
   32 
   33   /// The terminal escape for red text, or the empty string if this is Windows
   34   /// or not outputting to a terminal.
   35   String get _red => useColor ? '\u001b[31m' : '';
   36 
   37   /// The terminal escape for yellow text, or the empty string if this is
   38   /// Windows or not outputting to a terminal.
   39   String get _yellow => useColor ? '\u001b[33m' : '';
   40 
   41   /// The terminal escape for gray text, or the empty string if this is
   42   /// Windows or not outputting to a terminal.
   43   String get _gray => useColor ? '\u001b[1;30m' : '';
   44 
   45   /// The terminal escape for bold text, or the empty string if this is
   46   /// Windows or not outputting to a terminal.
   47   String get _bold => useColor ? '\u001b[1m' : '';
   48 
   49   /// The terminal escape for removing test coloring, or the empty string if
   50   /// this is Windows or not outputting to a terminal.
   51   String get _noColor => useColor ? '\u001b[0m' : '';
   52 
   53   /// The terminal escape for clearing the line, or a carriage return if
   54   /// this is Windows or not outputting to a terminal.
   55   String get _clearLine => useColor ? '\x1b[2K\r' : '\r';
   56 
   57   final Map<int, TestResult> _tests = <int, TestResult>{};
   58 
   59   /// The test results from this run.
   60   Iterable<TestResult> get tests => _tests.values;
   61 
   62   /// The number of tests that were started.
   63   int started = 0;
   64 
   65   /// The number of test failures.
   66   int failures = 0;
   67 
   68   /// The number of skipped tests.
   69   int skips = 0;
   70 
   71   /// The number of successful tests.
   72   int successes = 0;
   73 
   74   /// Process a single line of JSON output from the JSON test reporter.
   75   ///
   76   /// Callers are responsible for splitting multiple lines before calling this
   77   /// method.
   78   TestResult processRawOutput(String raw) {
   79     assert(raw != null);
   80     // We might be getting messages from Flutter Tool about updating/building.
   81     if (!raw.startsWith('{')) {
   82       print(raw);
   83       return null;
   84     }
   85     final Map<String, dynamic> decoded = json.decode(raw) as Map<String, dynamic>;
   86     final TestResult originalResult = _tests[decoded['testID']];
   87     switch (decoded['type'] as String) {
   88       case 'done':
   89         stdout.write(_clearLine);
   90         stdout.write('$_bold${_stopwatch.elapsed}$_noColor ');
   91         stdout.writeln(
   92             '$_green+$successes $_yellow~$skips $_red-$failures:$_bold$_gray Done.$_noColor');
   93         break;
   94       case 'testStart':
   95         final Map<String, dynamic> testData = decoded['test'] as Map<String, dynamic>;
   96         if (testData['url'] == null) {
   97           started += 1;
   98           stdout.write(_clearLine);
   99           stdout.write('$_bold${_stopwatch.elapsed}$_noColor ');
  100           stdout.write(
  101               '$_green+$successes $_yellow~$skips $_red-$failures: $_gray${testData['name']}$_noColor');
  102           break;
  103         }
  104         _tests[testData['id'] as int] = TestResult(
  105           id: testData['id'] as int,
  106           name: testData['name'] as String,
  107           line: testData['root_line'] as int ?? testData['line'] as int,
  108           column: testData['root_column'] as int ?? testData['column'] as int,
  109           path: testData['root_url'] as String ?? testData['url'] as String,
  110           startTime: decoded['time'] as int,
  111         );
  112         break;
  113       case 'testDone':
  114         if (originalResult == null) {
  115           break;
  116         }
  117         originalResult.endTime = decoded['time'] as int;
  118         if (decoded['skipped'] == true) {
  119           skips += 1;
  120           originalResult.status = TestStatus.skipped;
  121         } else {
  122           if (decoded['result'] == 'success') {
  123             originalResult.status =TestStatus.succeeded;
  124             successes += 1;
  125           } else {
  126             originalResult.status = TestStatus.failed;
  127             failures += 1;
  128           }
  129         }
  130         break;
  131       case 'error':
  132         final String error = decoded['error'] as String;
  133         final String stackTrace = decoded['stackTrace'] as String;
  134         if (originalResult != null) {
  135           originalResult.errorMessage = error;
  136           originalResult.stackTrace = stackTrace;
  137         } else {
  138           if (error != null)
  139             stderr.writeln(error);
  140           if (stackTrace != null)
  141             stderr.writeln(stackTrace);
  142         }
  143         break;
  144       case 'print':
  145         if (originalResult != null) {
  146           originalResult.messages.add(decoded['message'] as String);
  147         }
  148         break;
  149       case 'group':
  150       case 'allSuites':
  151       case 'start':
  152       case 'suite':
  153       default:
  154         break;
  155     }
  156     return originalResult;
  157   }
  158 
  159   /// Print summary of test results.
  160   void finish() {
  161     final List<String> skipped = <String>[];
  162     final List<String> failed = <String>[];
  163     for (final TestResult result in _tests.values) {
  164       switch (result.status) {
  165         case TestStatus.started:
  166           failed.add('${_red}Unexpectedly failed to complete a test!');
  167           failed.add(result.toString() + _noColor);
  168           break;
  169         case TestStatus.skipped:
  170           skipped.add(
  171               '${_yellow}Skipped ${result.name} (${result.pathLineColumn}).$_noColor');
  172           break;
  173         case TestStatus.failed:
  174           failed.addAll(<String>[
  175             '$_bold${_red}Failed ${result.name} (${result.pathLineColumn}):',
  176             result.errorMessage,
  177             _noColor + _red,
  178             result.stackTrace,
  179           ]);
  180           failed.addAll(result.messages);
  181           failed.add(_noColor);
  182           break;
  183         case TestStatus.succeeded:
  184           break;
  185       }
  186     }
  187     skipped.forEach(print);
  188     failed.forEach(print);
  189     if (failed.isEmpty) {
  190       print('${_green}Completed, $successes test(s) passing ($skips skipped).$_noColor');
  191     } else {
  192       print('$_gray$failures test(s) failed.$_noColor');
  193     }
  194   }
  195 }
  196 
  197 /// The state of a test received from the JSON reporter.
  198 enum TestStatus {
  199   /// Test execution has started.
  200   started,
  201   /// Test completed successfully.
  202   succeeded,
  203   /// Test failed.
  204   failed,
  205   /// Test was skipped.
  206   skipped,
  207 }
  208 
  209 /// The detailed status of a test run.
  210 class TestResult {
  211   TestResult({
  212     @required this.id,
  213     @required this.name,
  214     @required this.line,
  215     @required this.column,
  216     @required this.path,
  217     @required this.startTime,
  218     this.status = TestStatus.started,
  219   })  : assert(id != null),
  220         assert(name != null),
  221         assert(line != null),
  222         assert(column != null),
  223         assert(path != null),
  224         assert(startTime != null),
  225         assert(status != null),
  226         messages = <String>[];
  227 
  228   /// The state of the test.
  229   TestStatus status;
  230 
  231   /// The internal ID of the test used by the JSON reporter.
  232   final int id;
  233 
  234   /// The name of the test, specified via the `test` method.
  235   final String name;
  236 
  237   /// The line number from the original file.
  238   final int line;
  239 
  240   /// The column from the original file.
  241   final int column;
  242 
  243   /// The path of the original test file.
  244   final String path;
  245 
  246   /// A friendly print out of the [path], [line], and [column] of the test.
  247   String get pathLineColumn => '$path:$line:$column';
  248 
  249   /// The start time of the test, in milliseconds relative to suite startup.
  250   final int startTime;
  251 
  252   /// The stdout of the test.
  253   final List<String> messages;
  254 
  255   /// The error message from the test, from an `expect`, an [Exception] or
  256   /// [Error].
  257   String errorMessage;
  258 
  259   /// The stacktrace from a test failure.
  260   String stackTrace;
  261 
  262   /// The time, in milliseconds relative to suite startup, that the test ended.
  263   int endTime;
  264 
  265   /// The total time, in milliseconds, that the test took.
  266   int get totalTime => (endTime ?? _stopwatch.elapsedMilliseconds) - startTime;
  267 
  268   @override
  269   String toString() => '{$runtimeType: {$id, $name, ${totalTime}ms, $pathLineColumn}}';
  270 }