| // Copyright 2017 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:flutter_tools/src/base/io.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:test/test.dart'; |
| |
| import '../src/context.dart'; |
| import '../src/mocks.dart'; |
| |
| void main() { |
| group('AppContext', () { |
| test('error', () async { |
| final BufferLogger mockLogger = new BufferLogger(); |
| final VerboseLogger verboseLogger = new VerboseLogger(mockLogger); |
| verboseLogger.supportsColor = false; |
| |
| verboseLogger.printStatus('Hey Hey Hey Hey'); |
| verboseLogger.printTrace('Oooh, I do I do I do'); |
| verboseLogger.printError('Helpless!'); |
| |
| expect(mockLogger.statusText, matches(r'^\[ (?: {0,2}\+[0-9]{1,3} ms| )\] Hey Hey Hey Hey\n' |
| r'\[ (?: {0,2}\+[0-9]{1,3} ms| )\] Oooh, I do I do I do\n$')); |
| expect(mockLogger.traceText, ''); |
| expect(mockLogger.errorText, matches(r'^\[ (?: {0,2}\+[0-9]{1,3} ms| )\] Helpless!\n$')); |
| }); |
| }); |
| |
| group('Spinners', () { |
| MockStdio mockStdio; |
| AnsiSpinner ansiSpinner; |
| AnsiStatus ansiStatus; |
| int called; |
| final RegExp secondDigits = new RegExp(r'[^\b]\b\b\b\b\b[0-9]+[.][0-9]+(?:s|ms)'); |
| |
| setUp(() { |
| mockStdio = new MockStdio(); |
| ansiSpinner = new AnsiSpinner(); |
| called = 0; |
| ansiStatus = new AnsiStatus('Hello world', true, () => called++, 20); |
| }); |
| |
| List<String> outputLines() => mockStdio.writtenToStdout.join('').split('\n'); |
| |
| Future<void> doWhile(bool doThis()) async { |
| return Future.doWhile(() async { |
| // Future.doWhile() isn't enough by itself, because the VM never gets |
| // around to scheduling the other tasks for some reason. |
| await new Future<void>.delayed(const Duration(milliseconds: 0)); |
| return doThis(); |
| }); |
| } |
| |
| testUsingContext('AnsiSpinner works', () async { |
| ansiSpinner.start(); |
| await doWhile(() => ansiSpinner.ticks < 10); |
| List<String> lines = outputLines(); |
| expect(lines[0], startsWith(' \b-\b\\\b|\b/\b-\b\\\b|\b/')); |
| expect(lines[0].endsWith('\n'), isFalse); |
| expect(lines.length, equals(1)); |
| ansiSpinner.stop(); |
| lines = outputLines(); |
| expect(lines[0], endsWith('\b \b')); |
| expect(lines.length, equals(1)); |
| |
| // Verify that stopping multiple times doesn't clear multiple times. |
| ansiSpinner.stop(); |
| lines = outputLines(); |
| expect(lines[0].endsWith('\b \b '), isFalse); |
| expect(lines.length, equals(1)); |
| ansiSpinner.cancel(); |
| lines = outputLines(); |
| expect(lines[0].endsWith('\b \b '), isFalse); |
| expect(lines.length, equals(1)); |
| }, overrides: <Type, Generator>{Stdio: () => mockStdio}); |
| |
| testUsingContext('AnsiStatus works when cancelled', () async { |
| ansiStatus.start(); |
| await doWhile(() => ansiStatus.ticks < 10); |
| List<String> lines = outputLines(); |
| expect(lines[0], startsWith('Hello world \b-\b\\\b|\b/\b-\b\\\b|\b/\b-')); |
| expect(lines[0].endsWith('\n'), isFalse); |
| expect(lines.length, equals(1)); |
| ansiStatus.cancel(); |
| lines = outputLines(); |
| expect(lines[0], endsWith('\b \b')); |
| expect(lines.length, equals(2)); |
| expect(called, equals(1)); |
| ansiStatus.cancel(); |
| lines = outputLines(); |
| expect(lines[0].endsWith('\b \b\b \b'), isFalse); |
| expect(lines.length, equals(2)); |
| expect(called, equals(1)); |
| ansiStatus.stop(); |
| lines = outputLines(); |
| expect(lines[0].endsWith('\b \b\b \b'), isFalse); |
| expect(lines.length, equals(2)); |
| expect(called, equals(1)); |
| }, overrides: <Type, Generator>{Stdio: () => mockStdio}); |
| |
| testUsingContext('AnsiStatus works when stopped', () async { |
| ansiStatus.start(); |
| await doWhile(() => ansiStatus.ticks < 10); |
| List<String> lines = outputLines(); |
| expect(lines[0], startsWith('Hello world \b-\b\\\b|\b/\b-\b\\\b|\b/\b-')); |
| expect(lines.length, equals(1)); |
| |
| // Verify a stop prints the time. |
| ansiStatus.stop(); |
| lines = outputLines(); |
| List<Match> matches = secondDigits.allMatches(lines[0]).toList(); |
| expect(matches, isNotNull); |
| expect(matches, hasLength(1)); |
| Match match = matches.first; |
| expect(lines[0], endsWith(match.group(0))); |
| final String initialTime = match.group(0); |
| expect(called, equals(1)); |
| expect(lines.length, equals(2)); |
| expect(lines[1], equals('')); |
| |
| // Verify stopping more than once generates no additional output. |
| ansiStatus.stop(); |
| lines = outputLines(); |
| matches = secondDigits.allMatches(lines[0]).toList(); |
| expect(matches, hasLength(1)); |
| match = matches.first; |
| expect(lines[0], endsWith(initialTime)); |
| expect(called, equals(1)); |
| expect(lines.length, equals(2)); |
| expect(lines[1], equals('')); |
| }, overrides: <Type, Generator>{Stdio: () => mockStdio}); |
| |
| testUsingContext('AnsiStatus works when cancelled', () async { |
| ansiStatus.start(); |
| await doWhile(() => ansiStatus.ticks < 10); |
| List<String> lines = outputLines(); |
| expect(lines[0], startsWith('Hello world \b-\b\\\b|\b/\b-\b\\\b|\b/\b-')); |
| expect(lines.length, equals(1)); |
| |
| // Verify a cancel does _not_ print the time and prints a newline. |
| ansiStatus.cancel(); |
| lines = outputLines(); |
| List<Match> matches = secondDigits.allMatches(lines[0]).toList(); |
| expect(matches, isEmpty); |
| expect(lines[0], endsWith('\b \b')); |
| expect(called, equals(1)); |
| // TODO(jcollins-g): Consider having status objects print the newline |
| // when canceled, or never printing a newline at all. |
| expect(lines.length, equals(2)); |
| |
| // Verifying calling stop after cancel doesn't print anything weird. |
| ansiStatus.stop(); |
| lines = outputLines(); |
| matches = secondDigits.allMatches(lines[0]).toList(); |
| expect(matches, isEmpty); |
| expect(lines[0], endsWith('\b \b')); |
| expect(called, equals(1)); |
| expect(lines[0], isNot(endsWith('\b \b\b \b'))); |
| expect(lines.length, equals(2)); |
| }, overrides: <Type, Generator>{Stdio: () => mockStdio}); |
| }); |
| } |