mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
373 lines
13 KiB
Dart
373 lines
13 KiB
Dart
// Copyright 2016 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/utils.dart';
|
|
import 'package:flutter_tools/src/base/version.dart';
|
|
import 'package:flutter_tools/src/base/terminal.dart';
|
|
|
|
import 'src/common.dart';
|
|
import 'src/context.dart';
|
|
|
|
void main() {
|
|
group('SettingsFile', () {
|
|
test('parse', () {
|
|
final SettingsFile file = SettingsFile.parse('''
|
|
# ignore comment
|
|
foo=bar
|
|
baz=qux
|
|
''');
|
|
expect(file.values['foo'], 'bar');
|
|
expect(file.values['baz'], 'qux');
|
|
expect(file.values, hasLength(2));
|
|
});
|
|
});
|
|
|
|
group('uuid', () {
|
|
// xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
test('simple', () {
|
|
final Uuid uuid = Uuid();
|
|
final String result = uuid.generateV4();
|
|
expect(result.length, 36);
|
|
expect(result[8], '-');
|
|
expect(result[13], '-');
|
|
expect(result[18], '-');
|
|
expect(result[23], '-');
|
|
});
|
|
|
|
test('can parse', () {
|
|
final Uuid uuid = Uuid();
|
|
final String result = uuid.generateV4();
|
|
expect(int.parse(result.substring(0, 8), radix: 16), isNotNull);
|
|
expect(int.parse(result.substring(9, 13), radix: 16), isNotNull);
|
|
expect(int.parse(result.substring(14, 18), radix: 16), isNotNull);
|
|
expect(int.parse(result.substring(19, 23), radix: 16), isNotNull);
|
|
expect(int.parse(result.substring(24, 36), radix: 16), isNotNull);
|
|
});
|
|
|
|
test('special bits', () {
|
|
final Uuid uuid = Uuid();
|
|
String result = uuid.generateV4();
|
|
expect(result[14], '4');
|
|
expect(result[19].toLowerCase(), isIn('89ab'));
|
|
|
|
result = uuid.generateV4();
|
|
expect(result[19].toLowerCase(), isIn('89ab'));
|
|
|
|
result = uuid.generateV4();
|
|
expect(result[19].toLowerCase(), isIn('89ab'));
|
|
});
|
|
|
|
test('is pretty random', () {
|
|
final Set<String> set = <String>{};
|
|
|
|
Uuid uuid = Uuid();
|
|
for (int i = 0; i < 64; i++) {
|
|
final String val = uuid.generateV4();
|
|
expect(set, isNot(contains(val)));
|
|
set.add(val);
|
|
}
|
|
|
|
uuid = Uuid();
|
|
for (int i = 0; i < 64; i++) {
|
|
final String val = uuid.generateV4();
|
|
expect(set, isNot(contains(val)));
|
|
set.add(val);
|
|
}
|
|
|
|
uuid = Uuid();
|
|
for (int i = 0; i < 64; i++) {
|
|
final String val = uuid.generateV4();
|
|
expect(set, isNot(contains(val)));
|
|
set.add(val);
|
|
}
|
|
});
|
|
});
|
|
|
|
group('Version', () {
|
|
test('can parse and compare', () {
|
|
expect(Version.unknown.toString(), equals('unknown'));
|
|
expect(Version(null, null, null).toString(), equals('0'));
|
|
|
|
final Version v1 = Version.parse('1');
|
|
expect(v1.major, equals(1));
|
|
expect(v1.minor, equals(0));
|
|
expect(v1.patch, equals(0));
|
|
|
|
expect(v1, greaterThan(Version.unknown));
|
|
|
|
final Version v2 = Version.parse('1.2');
|
|
expect(v2.major, equals(1));
|
|
expect(v2.minor, equals(2));
|
|
expect(v2.patch, equals(0));
|
|
|
|
final Version v3 = Version.parse('1.2.3');
|
|
expect(v3.major, equals(1));
|
|
expect(v3.minor, equals(2));
|
|
expect(v3.patch, equals(3));
|
|
|
|
final Version v4 = Version.parse('1.12');
|
|
expect(v4, greaterThan(v2));
|
|
|
|
expect(v3, greaterThan(v2));
|
|
expect(v2, greaterThan(v1));
|
|
|
|
final Version v5 = Version(1, 2, 0, text: 'foo');
|
|
expect(v5, equals(v2));
|
|
|
|
expect(Version.parse('Preview2.2'), isNull);
|
|
});
|
|
});
|
|
|
|
group('Poller', () {
|
|
const Duration kShortDelay = Duration(milliseconds: 100);
|
|
|
|
Poller poller;
|
|
|
|
tearDown(() {
|
|
poller?.cancel();
|
|
});
|
|
|
|
test('fires at start', () async {
|
|
bool called = false;
|
|
poller = Poller(() async {
|
|
called = true;
|
|
}, const Duration(seconds: 1));
|
|
expect(called, false);
|
|
await Future<void>.delayed(kShortDelay);
|
|
expect(called, true);
|
|
});
|
|
|
|
test('runs periodically', () async {
|
|
// Ensure we get the first (no-delay) callback, and one of the periodic callbacks.
|
|
int callCount = 0;
|
|
poller = Poller(() async {
|
|
callCount++;
|
|
}, Duration(milliseconds: kShortDelay.inMilliseconds ~/ 2));
|
|
expect(callCount, 0);
|
|
await Future<void>.delayed(kShortDelay);
|
|
expect(callCount, greaterThanOrEqualTo(2));
|
|
});
|
|
|
|
test('no quicker then the periodic delay', () async {
|
|
// Make sure that the poller polls at delay + the time it took to run the callback.
|
|
final Completer<Duration> completer = Completer<Duration>();
|
|
DateTime firstTime;
|
|
poller = Poller(() async {
|
|
if (firstTime == null)
|
|
firstTime = DateTime.now();
|
|
else
|
|
completer.complete(DateTime.now().difference(firstTime));
|
|
|
|
// introduce a delay
|
|
await Future<void>.delayed(kShortDelay);
|
|
}, kShortDelay);
|
|
final Duration duration = await completer.future;
|
|
expect(
|
|
duration, greaterThanOrEqualTo(Duration(milliseconds: kShortDelay.inMilliseconds * 2)));
|
|
});
|
|
});
|
|
|
|
group('Misc', () {
|
|
test('snakeCase', () async {
|
|
expect(snakeCase('abc'), equals('abc'));
|
|
expect(snakeCase('abC'), equals('ab_c'));
|
|
expect(snakeCase('aBc'), equals('a_bc'));
|
|
expect(snakeCase('aBC'), equals('a_b_c'));
|
|
expect(snakeCase('Abc'), equals('abc'));
|
|
expect(snakeCase('AbC'), equals('ab_c'));
|
|
expect(snakeCase('ABc'), equals('a_bc'));
|
|
expect(snakeCase('ABC'), equals('a_b_c'));
|
|
});
|
|
});
|
|
|
|
group('text wrapping', () {
|
|
const int _lineLength = 40;
|
|
const String _longLine = 'This is a long line that needs to be wrapped.';
|
|
final String _longLineWithNewlines = 'This is a long line with newlines that\n'
|
|
'needs to be wrapped.\n\n' +
|
|
'0123456789' * 5;
|
|
final String _longAnsiLineWithNewlines = '${AnsiTerminal.red}This${AnsiTerminal.resetAll} is a long line with newlines that\n'
|
|
'needs to be wrapped.\n\n'
|
|
'${AnsiTerminal.green}0123456789${AnsiTerminal.resetAll}' +
|
|
'0123456789' * 3 +
|
|
'${AnsiTerminal.green}0123456789${AnsiTerminal.resetAll}';
|
|
const String _onlyAnsiSequences = '${AnsiTerminal.red}${AnsiTerminal.resetAll}';
|
|
final String _indentedLongLineWithNewlines = ' This is an indented long line with newlines that\n'
|
|
'needs to be wrapped.\n\tAnd preserves tabs.\n \n ' +
|
|
'0123456789' * 5;
|
|
const String _shortLine = 'Short line.';
|
|
const String _indentedLongLine = ' This is an indented long line that needs to be '
|
|
'wrapped and indentation preserved.';
|
|
final FakeStdio fakeStdio = FakeStdio();
|
|
|
|
void testWrap(String description, Function body) {
|
|
testUsingContext(description, body, overrides: <Type, Generator>{
|
|
OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: _lineLength),
|
|
});
|
|
}
|
|
|
|
void testNoWrap(String description, Function body) {
|
|
testUsingContext(description, body, overrides: <Type, Generator>{
|
|
OutputPreferences: () => OutputPreferences(wrapText: false),
|
|
});
|
|
}
|
|
|
|
test('does not wrap by default in tests', () {
|
|
expect(wrapText(_longLine), equals(_longLine));
|
|
});
|
|
testNoWrap('can override wrap preference if preference is off', () {
|
|
expect(wrapText(_longLine, columnWidth: _lineLength, shouldWrap: true), equals('''
|
|
This is a long line that needs to be
|
|
wrapped.'''));
|
|
});
|
|
testWrap('can override wrap preference if preference is on', () {
|
|
expect(wrapText(_longLine, shouldWrap: false), equals(_longLine));
|
|
});
|
|
testNoWrap('does not wrap at all if not told to wrap', () {
|
|
expect(wrapText(_longLine), equals(_longLine));
|
|
});
|
|
testWrap('does not wrap short lines.', () {
|
|
expect(wrapText(_shortLine, columnWidth: _lineLength), equals(_shortLine));
|
|
});
|
|
testWrap('able to wrap long lines', () {
|
|
expect(wrapText(_longLine, columnWidth: _lineLength), equals('''
|
|
This is a long line that needs to be
|
|
wrapped.'''));
|
|
});
|
|
testUsingContext('able to handle dynamically changing terminal column size', () {
|
|
fakeStdio.currentColumnSize = 20;
|
|
expect(wrapText(_longLine), equals('''
|
|
This is a long line
|
|
that needs to be
|
|
wrapped.'''));
|
|
fakeStdio.currentColumnSize = _lineLength;
|
|
expect(wrapText(_longLine), equals('''
|
|
This is a long line that needs to be
|
|
wrapped.'''));
|
|
}, overrides: <Type, Generator>{
|
|
OutputPreferences: () => OutputPreferences(wrapText: true),
|
|
Stdio: () => fakeStdio,
|
|
});
|
|
testWrap('wrap long lines with no whitespace', () {
|
|
expect(wrapText('0123456789' * 5, columnWidth: _lineLength), equals('''
|
|
0123456789012345678901234567890123456789
|
|
0123456789'''));
|
|
});
|
|
testWrap('refuses to wrap to a column smaller than 10 characters', () {
|
|
expect(wrapText('$_longLine ' + '0123456789' * 4, columnWidth: 1), equals('''
|
|
This is a
|
|
long line
|
|
that needs
|
|
to be
|
|
wrapped.
|
|
0123456789
|
|
0123456789
|
|
0123456789
|
|
0123456789'''));
|
|
});
|
|
testWrap('preserves indentation', () {
|
|
expect(wrapText(_indentedLongLine, columnWidth: _lineLength), equals('''
|
|
This is an indented long line that
|
|
needs to be wrapped and indentation
|
|
preserved.'''));
|
|
});
|
|
testWrap('preserves indentation and stripping trailing whitespace', () {
|
|
expect(wrapText('$_indentedLongLine ', columnWidth: _lineLength), equals('''
|
|
This is an indented long line that
|
|
needs to be wrapped and indentation
|
|
preserved.'''));
|
|
});
|
|
testWrap('wraps text with newlines', () {
|
|
expect(wrapText(_longLineWithNewlines, columnWidth: _lineLength), equals('''
|
|
This is a long line with newlines that
|
|
needs to be wrapped.
|
|
|
|
0123456789012345678901234567890123456789
|
|
0123456789'''));
|
|
});
|
|
testWrap('wraps text with ANSI sequences embedded', () {
|
|
expect(wrapText(_longAnsiLineWithNewlines, columnWidth: _lineLength), equals('''
|
|
${AnsiTerminal.red}This${AnsiTerminal.resetAll} is a long line with newlines that
|
|
needs to be wrapped.
|
|
|
|
${AnsiTerminal.green}0123456789${AnsiTerminal.resetAll}012345678901234567890123456789
|
|
${AnsiTerminal.green}0123456789${AnsiTerminal.resetAll}'''));
|
|
});
|
|
testWrap('wraps text with only ANSI sequences', () {
|
|
expect(wrapText(_onlyAnsiSequences, columnWidth: _lineLength),
|
|
equals('${AnsiTerminal.red}${AnsiTerminal.resetAll}'));
|
|
});
|
|
testWrap('preserves indentation in the presence of newlines', () {
|
|
expect(wrapText(_indentedLongLineWithNewlines, columnWidth: _lineLength), equals('''
|
|
This is an indented long line with
|
|
newlines that
|
|
needs to be wrapped.
|
|
\tAnd preserves tabs.
|
|
|
|
01234567890123456789012345678901234567
|
|
890123456789'''));
|
|
});
|
|
testWrap('removes trailing whitespace when wrapping', () {
|
|
expect(wrapText('$_longLine \t', columnWidth: _lineLength), equals('''
|
|
This is a long line that needs to be
|
|
wrapped.'''));
|
|
});
|
|
testWrap('honors hangingIndent parameter', () {
|
|
expect(wrapText(_longLine, columnWidth: _lineLength, hangingIndent: 6), equals('''
|
|
This is a long line that needs to be
|
|
wrapped.'''));
|
|
});
|
|
testWrap('handles hangingIndent with a single unwrapped line.', () {
|
|
expect(wrapText(_shortLine, columnWidth: _lineLength, hangingIndent: 6), equals('''
|
|
Short line.'''));
|
|
});
|
|
testWrap('handles hangingIndent with two unwrapped lines and the second is empty.', () {
|
|
expect(wrapText('$_shortLine\n', columnWidth: _lineLength, hangingIndent: 6), equals('''
|
|
Short line.
|
|
'''));
|
|
});
|
|
testWrap('honors hangingIndent parameter on already indented line.', () {
|
|
expect(wrapText(_indentedLongLine, columnWidth: _lineLength, hangingIndent: 6), equals('''
|
|
This is an indented long line that
|
|
needs to be wrapped and
|
|
indentation preserved.'''));
|
|
});
|
|
testWrap('honors hangingIndent and indent parameters at the same time.', () {
|
|
expect(wrapText(_indentedLongLine, columnWidth: _lineLength, indent: 6, hangingIndent: 6), equals('''
|
|
This is an indented long line
|
|
that needs to be wrapped
|
|
and indentation
|
|
preserved.'''));
|
|
});
|
|
testWrap('honors indent parameter on already indented line.', () {
|
|
expect(wrapText(_indentedLongLine, columnWidth: _lineLength, indent: 6), equals('''
|
|
This is an indented long line
|
|
that needs to be wrapped and
|
|
indentation preserved.'''));
|
|
});
|
|
testWrap('honors hangingIndent parameter on already indented line.', () {
|
|
expect(wrapText(_indentedLongLineWithNewlines, columnWidth: _lineLength, hangingIndent: 6), equals('''
|
|
This is an indented long line with
|
|
newlines that
|
|
needs to be wrapped.
|
|
And preserves tabs.
|
|
|
|
01234567890123456789012345678901234567
|
|
890123456789'''));
|
|
});
|
|
});
|
|
}
|
|
|
|
class FakeStdio extends Stdio {
|
|
FakeStdio();
|
|
|
|
int currentColumnSize = 20;
|
|
|
|
@override
|
|
int get terminalColumns => currentColumnSize;
|
|
}
|