mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
1523 lines
51 KiB
Dart
1523 lines
51 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// @dart = 2.8
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:file/file.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:file_testing/file_testing.dart';
|
|
import 'package:flutter_tools/src/base/io.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/base/signals.dart';
|
|
import 'package:flutter_tools/src/base/terminal.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/compile.dart';
|
|
import 'package:flutter_tools/src/convert.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/resident_devtools_handler.dart';
|
|
import 'package:flutter_tools/src/resident_runner.dart';
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
|
import 'package:test/fake.dart';
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
|
|
|
import '../src/common.dart';
|
|
import '../src/fake_vm_services.dart';
|
|
|
|
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
|
|
id: '1',
|
|
pauseEvent: vm_service.Event(
|
|
kind: vm_service.EventKind.kResume,
|
|
timestamp: 0
|
|
),
|
|
breakpoints: <vm_service.Breakpoint>[],
|
|
exceptionPauseMode: null,
|
|
extensionRPCs: <String>[],
|
|
libraries: <vm_service.LibraryRef>[
|
|
vm_service.LibraryRef(
|
|
id: '1',
|
|
uri: 'file:///hello_world/main.dart',
|
|
name: '',
|
|
),
|
|
],
|
|
livePorts: 0,
|
|
name: 'test',
|
|
number: '1',
|
|
pauseOnExit: false,
|
|
runnable: true,
|
|
startTime: 0,
|
|
isSystemIsolate: false,
|
|
isolateFlags: <vm_service.IsolateFlag>[],
|
|
);
|
|
|
|
final vm_service.VM fakeVM = vm_service.VM(
|
|
isolates: <vm_service.IsolateRef>[fakeUnpausedIsolate],
|
|
pid: 1,
|
|
hostCPU: '',
|
|
isolateGroups: <vm_service.IsolateGroupRef>[],
|
|
targetCPU: '',
|
|
startTime: 0,
|
|
name: 'dart',
|
|
architectureBits: 64,
|
|
operatingSystem: '',
|
|
version: '',
|
|
systemIsolateGroups: <vm_service.IsolateGroupRef>[],
|
|
systemIsolates: <vm_service.IsolateRef>[],
|
|
);
|
|
|
|
final FlutterView fakeFlutterView = FlutterView(
|
|
id: 'a',
|
|
uiIsolate: fakeUnpausedIsolate,
|
|
);
|
|
|
|
final FakeVmServiceRequest listViews = FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[
|
|
fakeFlutterView.toJson(),
|
|
],
|
|
},
|
|
);
|
|
|
|
void main() {
|
|
testWithoutContext('keyboard input handling single help character', () async {
|
|
final TestRunner testRunner = TestRunner();
|
|
final Logger logger = BufferLogger.test();
|
|
final Signals signals = Signals.test();
|
|
final Terminal terminal = Terminal.test();
|
|
final MemoryFileSystem fs = MemoryFileSystem.test();
|
|
final ProcessInfo processInfo = ProcessInfo.test(fs);
|
|
final TerminalHandler terminalHandler = TerminalHandler(
|
|
testRunner,
|
|
logger: logger,
|
|
signals: signals,
|
|
terminal: terminal,
|
|
processInfo: processInfo,
|
|
reportReady: false,
|
|
);
|
|
|
|
expect(testRunner.hasHelpBeenPrinted, false);
|
|
await terminalHandler.processTerminalInput('h');
|
|
expect(testRunner.hasHelpBeenPrinted, true);
|
|
});
|
|
|
|
testWithoutContext('keyboard input handling help character surrounded with newlines', () async {
|
|
final TestRunner testRunner = TestRunner();
|
|
final Logger logger = BufferLogger.test();
|
|
final Signals signals = Signals.test();
|
|
final Terminal terminal = Terminal.test();
|
|
final MemoryFileSystem fs = MemoryFileSystem.test();
|
|
final ProcessInfo processInfo = ProcessInfo.test(fs);
|
|
final TerminalHandler terminalHandler = TerminalHandler(
|
|
testRunner,
|
|
logger: logger,
|
|
signals: signals,
|
|
terminal: terminal,
|
|
processInfo: processInfo,
|
|
reportReady: false,
|
|
);
|
|
|
|
expect(testRunner.hasHelpBeenPrinted, false);
|
|
await terminalHandler.processTerminalInput('\nh\n');
|
|
expect(testRunner.hasHelpBeenPrinted, true);
|
|
});
|
|
|
|
group('keycode verification, brought to you by the letter', () {
|
|
testWithoutContext('a, can handle trailing newlines', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('a\n');
|
|
|
|
expect(terminalHandler.lastReceivedCommand, 'a');
|
|
});
|
|
|
|
testWithoutContext('n, can handle trailing only newlines', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
await terminalHandler.processTerminalInput('\n\n');
|
|
|
|
expect(terminalHandler.lastReceivedCommand, '');
|
|
});
|
|
|
|
testWithoutContext('a - debugToggleProfileWidgetBuilds', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.profileWidgetBuilds',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'enabled': 'false'
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.profileWidgetBuilds',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'enabled': 'true'
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'enabled': 'true'
|
|
},
|
|
),
|
|
]);
|
|
|
|
await terminalHandler.processTerminalInput('a');
|
|
});
|
|
|
|
testWithoutContext('a - debugToggleProfileWidgetBuilds with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.profileWidgetBuilds',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'enabled': 'false'
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.profileWidgetBuilds',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'enabled': 'true'
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'enabled': 'true'
|
|
},
|
|
),
|
|
], web: true);
|
|
|
|
await terminalHandler.processTerminalInput('a');
|
|
});
|
|
|
|
testWithoutContext('a - debugToggleProfileWidgetBuilds without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
|
|
await terminalHandler.processTerminalInput('a');
|
|
});
|
|
|
|
testWithoutContext('b - debugToggleBrightness', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.brightnessOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'Brightness.light',
|
|
}
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.brightnessOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'Brightness.dark',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'Brightness.dark',
|
|
}
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('b');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('Changed brightness to Brightness.dark'));
|
|
});
|
|
|
|
testWithoutContext('b - debugToggleBrightness with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.brightnessOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'Brightness.light',
|
|
}
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.brightnessOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'Brightness.dark',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'Brightness.dark',
|
|
}
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('b');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('Changed brightness to Brightness.dark'));
|
|
});
|
|
|
|
testWithoutContext('b - debugToggleBrightness without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
|
|
await terminalHandler.processTerminalInput('b');
|
|
});
|
|
|
|
testWithoutContext('d,D - detach', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
await terminalHandler.processTerminalInput('d');
|
|
|
|
expect(runner.calledDetach, true);
|
|
runner.calledDetach = false;
|
|
|
|
await terminalHandler.processTerminalInput('D');
|
|
|
|
expect(runner.calledDetach, true);
|
|
});
|
|
|
|
testWithoutContext('h,H,? - printHelp', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
await terminalHandler.processTerminalInput('h');
|
|
|
|
expect(runner.calledPrintWithDetails, true);
|
|
runner.calledPrintWithDetails = false;
|
|
|
|
await terminalHandler.processTerminalInput('H');
|
|
|
|
expect(runner.calledPrintWithDetails, true);
|
|
runner.calledPrintWithDetails = false;
|
|
|
|
await terminalHandler.processTerminalInput('?');
|
|
|
|
expect(runner.calledPrintWithDetails, true);
|
|
});
|
|
|
|
testWithoutContext('i - debugToggleWidgetInspector', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.inspector.show',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
]);
|
|
|
|
await terminalHandler.processTerminalInput('i');
|
|
});
|
|
|
|
testWithoutContext('i - debugToggleWidgetInspector with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.inspector.show',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
], web: true);
|
|
|
|
await terminalHandler.processTerminalInput('i');
|
|
});
|
|
|
|
testWithoutContext('i - debugToggleWidgetInspector without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
|
|
await terminalHandler.processTerminalInput('i');
|
|
});
|
|
|
|
testWithoutContext('I - debugToggleInvertOversizedImages', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.invertOversizedImages',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('I');
|
|
});
|
|
|
|
testWithoutContext('I - debugToggleInvertOversizedImages with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.invertOversizedImages',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('I');
|
|
});
|
|
|
|
testWithoutContext('I - debugToggleInvertOversizedImages without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('I');
|
|
});
|
|
|
|
testWithoutContext('I - debugToggleInvertOversizedImages in profile mode is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], buildMode: BuildMode.profile);
|
|
await terminalHandler.processTerminalInput('I');
|
|
});
|
|
|
|
testWithoutContext('L - debugDumpLayerTree', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpLayerTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'LAYER TREE',
|
|
}
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('L');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('LAYER TREE'));
|
|
});
|
|
|
|
testWithoutContext('L - debugDumpLayerTree with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpLayerTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'LAYER TREE',
|
|
}
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('L');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('LAYER TREE'));
|
|
});
|
|
|
|
testWithoutContext('L - debugDumpLayerTree with service protocol and profile mode is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], buildMode: BuildMode.profile);
|
|
await terminalHandler.processTerminalInput('L');
|
|
});
|
|
|
|
testWithoutContext('L - debugDumpLayerTree without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('L');
|
|
});
|
|
|
|
testWithoutContext('o,O - debugTogglePlatform', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
// Request 1.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'iOS'
|
|
},
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'fuchsia',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'fuchsia'
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'android'
|
|
},
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'iOS',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'iOS'
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('o');
|
|
await terminalHandler.processTerminalInput('O');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('Switched operating system to fuchsia'));
|
|
expect(terminalHandler.logger.statusText, contains('Switched operating system to iOS'));
|
|
});
|
|
|
|
testWithoutContext('o,O - debugTogglePlatform with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
// Request 1.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'iOS'
|
|
},
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'fuchsia',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'fuchsia'
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'android'
|
|
},
|
|
),
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.platformOverride',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
'value': 'iOS',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'value': 'iOS'
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('o');
|
|
await terminalHandler.processTerminalInput('O');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('Switched operating system to fuchsia'));
|
|
expect(terminalHandler.logger.statusText, contains('Switched operating system to iOS'));
|
|
});
|
|
|
|
testWithoutContext('o,O - debugTogglePlatform without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('o');
|
|
await terminalHandler.processTerminalInput('O');
|
|
});
|
|
|
|
testWithoutContext('p - debugToggleDebugPaintSizeEnabled', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugPaint',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('p');
|
|
});
|
|
|
|
testWithoutContext('p - debugToggleDebugPaintSizeEnabled with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugPaint',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('p');
|
|
});
|
|
|
|
testWithoutContext('p - debugToggleDebugPaintSizeEnabled without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('p');
|
|
});
|
|
|
|
testWithoutContext('P - debugTogglePerformanceOverlayOverride', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.showPerformanceOverlay',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('P');
|
|
});
|
|
|
|
testWithoutContext('P - debugTogglePerformanceOverlayOverride with web target is skipped ', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], web: true);
|
|
await terminalHandler.processTerminalInput('P');
|
|
});
|
|
|
|
testWithoutContext('P - debugTogglePerformanceOverlayOverride without service protocol is skipped ', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('P');
|
|
});
|
|
|
|
testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'SEMANTICS DATA',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('S');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
|
|
});
|
|
|
|
testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'SEMANTICS DATA',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('S');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
|
|
});
|
|
|
|
testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('S');
|
|
});
|
|
|
|
testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'SEMANTICS DATA',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('U');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
|
|
});
|
|
|
|
testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'SEMANTICS DATA',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('U');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
|
|
});
|
|
|
|
testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('U');
|
|
});
|
|
|
|
testWithoutContext('t,T - debugDumpRenderTree', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpRenderTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'RENDER DATA 1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpRenderTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'RENDER DATA 2',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('t');
|
|
await terminalHandler.processTerminalInput('T');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('RENDER DATA 1'));
|
|
expect(terminalHandler.logger.statusText, contains('RENDER DATA 2'));
|
|
});
|
|
|
|
testWithoutContext('t,T - debugDumpRenderTree with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpRenderTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'RENDER DATA 1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpRenderTree',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'RENDER DATA 2',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('t');
|
|
await terminalHandler.processTerminalInput('T');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('RENDER DATA 1'));
|
|
expect(terminalHandler.logger.statusText, contains('RENDER DATA 2'));
|
|
});
|
|
|
|
testWithoutContext('t,T - debugDumpRenderTree without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('t');
|
|
await terminalHandler.processTerminalInput('T');
|
|
});
|
|
|
|
testWithoutContext('w,W - debugDumpApp', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpApp',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'WIDGET DATA 1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpApp',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'WIDGET DATA 2',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('w');
|
|
await terminalHandler.processTerminalInput('W');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('WIDGET DATA 1'));
|
|
expect(terminalHandler.logger.statusText, contains('WIDGET DATA 2'));
|
|
});
|
|
|
|
testWithoutContext('w,W - debugDumpApp with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpApp',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'WIDGET DATA 1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugDumpApp',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
jsonResponse: <String, Object>{
|
|
'data': 'WIDGET DATA 2',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('w');
|
|
await terminalHandler.processTerminalInput('W');
|
|
|
|
expect(terminalHandler.logger.statusText, contains('WIDGET DATA 1'));
|
|
expect(terminalHandler.logger.statusText, contains('WIDGET DATA 2'));
|
|
});
|
|
|
|
testWithoutContext('v - launchDevToolsInBrowser', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[],
|
|
supportsServiceProtocol: true);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
final FakeResidentDevtoolsHandler devtoolsHandler = runner.residentDevtoolsHandler as FakeResidentDevtoolsHandler;
|
|
|
|
expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isFalse);
|
|
await terminalHandler.processTerminalInput('v');
|
|
expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isTrue);
|
|
});
|
|
|
|
testWithoutContext('w,W - debugDumpApp without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('w');
|
|
await terminalHandler.processTerminalInput('W');
|
|
});
|
|
|
|
testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugCheckElevationsEnabled',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugCheckElevationsEnabled',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
]);
|
|
await terminalHandler.processTerminalInput('z');
|
|
await terminalHandler.processTerminalInput('Z');
|
|
});
|
|
|
|
testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled with web target', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugCheckElevationsEnabled',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
// Request 2.
|
|
listViews,
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugCheckElevationsEnabled',
|
|
args: <String, Object>{
|
|
'isolateId': '1',
|
|
},
|
|
),
|
|
], web: true);
|
|
await terminalHandler.processTerminalInput('z');
|
|
await terminalHandler.processTerminalInput('Z');
|
|
});
|
|
|
|
testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled without service protocol is skipped', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
|
|
await terminalHandler.processTerminalInput('z');
|
|
await terminalHandler.processTerminalInput('Z');
|
|
});
|
|
|
|
testWithoutContext('q,Q - exit', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
await terminalHandler.processTerminalInput('q');
|
|
|
|
expect(runner.calledExit, true);
|
|
runner.calledExit = false;
|
|
|
|
await terminalHandler.processTerminalInput('Q');
|
|
|
|
expect(runner.calledExit, true);
|
|
});
|
|
|
|
testWithoutContext('r - hotReload unsupported', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsHotReload: false);
|
|
await terminalHandler.processTerminalInput('r');
|
|
});
|
|
|
|
testWithoutContext('R - hotRestart unsupported', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsRestart: false);
|
|
await terminalHandler.processTerminalInput('R');
|
|
});
|
|
|
|
testWithoutContext('r - hotReload', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await terminalHandler.processTerminalInput('r');
|
|
|
|
expect(runner.calledReload, true);
|
|
expect(runner.calledRestart, false);
|
|
});
|
|
|
|
testWithoutContext('R - hotRestart', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await terminalHandler.processTerminalInput('R');
|
|
|
|
expect(runner.calledReload, false);
|
|
expect(runner.calledRestart, true);
|
|
});
|
|
|
|
testWithoutContext('r - hotReload with non-fatal error', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await terminalHandler.processTerminalInput('r');
|
|
|
|
expect(runner.calledReload, true);
|
|
expect(runner.calledRestart, false);
|
|
expect(terminalHandler.logger.statusText, contains('Try again after fixing the above error(s).'));
|
|
});
|
|
|
|
testWithoutContext('R - hotRestart with non-fatal error', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await terminalHandler.processTerminalInput('R');
|
|
|
|
expect(runner.calledReload, false);
|
|
expect(runner.calledRestart, true);
|
|
expect(terminalHandler.logger.statusText, contains('Try again after fixing the above error(s).'));
|
|
});
|
|
|
|
testWithoutContext('r - hotReload with fatal error', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await expectLater(() => terminalHandler.processTerminalInput('r'), throwsToolExit());
|
|
|
|
expect(runner.calledReload, true);
|
|
expect(runner.calledRestart, false);
|
|
});
|
|
|
|
testWithoutContext('R - hotRestart with fatal error', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
|
|
final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
|
|
|
|
await expectLater(() => terminalHandler.processTerminalInput('R'), throwsToolExit());
|
|
|
|
expect(runner.calledReload, false);
|
|
expect(runner.calledRestart, true);
|
|
});
|
|
});
|
|
|
|
testWithoutContext('ResidentRunner clears the screen when it should', () async {
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
|
|
const String message = 'This should be cleared';
|
|
|
|
expect(terminalHandler.logger.statusText, equals(''));
|
|
terminalHandler.logger.printStatus(message);
|
|
expect(terminalHandler.logger.statusText, equals(message + '\n')); // printStatus makes a newline
|
|
|
|
await terminalHandler.processTerminalInput('c');
|
|
expect(terminalHandler.logger.statusText, equals(''));
|
|
});
|
|
|
|
testWithoutContext('s, can take screenshot on debug device that supports screenshot', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
)
|
|
], logger: logger, supportsScreenshot: true);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
|
|
});
|
|
|
|
testWithoutContext('s, can take screenshot on debug device that does not support screenshot', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: '_flutter.screenshot',
|
|
args: <String, Object>{},
|
|
jsonResponse: <String, Object>{
|
|
'screenshot': base64.encode(<int>[1, 2, 3, 4]),
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
)
|
|
], logger: logger, supportsScreenshot: false, fileSystem: fileSystem);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
|
|
expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
|
|
});
|
|
|
|
testWithoutContext('s, can take screenshot on debug web device that does not support screenshot', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.dwds.screenshot',
|
|
args: <String, Object>{},
|
|
jsonResponse: <String, Object>{
|
|
'data': base64.encode(<int>[1, 2, 3, 4]),
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
)
|
|
], logger: logger, supportsScreenshot: false, web: true, fileSystem: fileSystem);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
|
|
expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
|
|
});
|
|
|
|
testWithoutContext('s, can take screenshot on device that does not support service protocol', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[],
|
|
logger: logger,
|
|
supportsScreenshot: true,
|
|
supportsServiceProtocol: false,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
|
|
expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
|
|
});
|
|
|
|
testWithoutContext('s, does not take a screenshot on a device that does not support screenshot or the service protocol', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[],
|
|
logger: logger,
|
|
supportsScreenshot: false,
|
|
supportsServiceProtocol: false,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, '\n');
|
|
expect(fileSystem.currentDirectory.childFile('flutter_01.png'), isNot(exists));
|
|
});
|
|
|
|
testWithoutContext('s, does not take a screenshot on a web device that does not support screenshot or the service protocol', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[],
|
|
logger: logger,
|
|
supportsScreenshot: false,
|
|
supportsServiceProtocol: false,
|
|
web: true,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.statusText, '\n');
|
|
expect(fileSystem.currentDirectory.childFile('flutter_01.png'), isNot(exists));
|
|
});
|
|
|
|
testWithoutContext('s, bails taking screenshot on debug device if debugAllowBanner throws RpcError', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
// Failed response,
|
|
errorCode: RPCErrorCodes.kInternalError,
|
|
),
|
|
],
|
|
logger: logger,
|
|
supportsScreenshot: false,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.errorText, contains('Error'));
|
|
});
|
|
|
|
testWithoutContext('s, bails taking screenshot on debug device if flutter.screenshot throws RpcError, restoring banner', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: '_flutter.screenshot',
|
|
// Failed response,
|
|
errorCode: RPCErrorCodes.kInternalError,
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
),
|
|
],
|
|
logger: logger,
|
|
supportsScreenshot: false,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.errorText, contains('Error'));
|
|
});
|
|
|
|
testWithoutContext('s, bails taking screenshot on debug device if dwds.screenshot throws RpcError, restoring banner', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: 'ext.dwds.screenshot',
|
|
// Failed response,
|
|
errorCode: RPCErrorCodes.kInternalError,
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
),
|
|
],
|
|
logger: logger,
|
|
supportsScreenshot: false,
|
|
web: true,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.errorText, contains('Error'));
|
|
});
|
|
|
|
testWithoutContext('s, bails taking screenshot on debug device if debugAllowBanner during second request', () async {
|
|
final BufferLogger logger = BufferLogger.test();
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
final TerminalHandler terminalHandler = setUpTerminalHandler(
|
|
<FakeVmServiceRequest>[
|
|
listViews,
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'false',
|
|
},
|
|
),
|
|
FakeVmServiceRequest(
|
|
method: 'ext.flutter.debugAllowBanner',
|
|
args: <String, Object>{
|
|
'isolateId': fakeUnpausedIsolate.id,
|
|
'enabled': 'true',
|
|
},
|
|
// Failed response,
|
|
errorCode: RPCErrorCodes.kInternalError,
|
|
),
|
|
],
|
|
logger: logger,
|
|
supportsScreenshot: true,
|
|
fileSystem: fileSystem,
|
|
);
|
|
|
|
await terminalHandler.processTerminalInput('s');
|
|
|
|
expect(logger.errorText, contains('Error'));
|
|
});
|
|
|
|
testWithoutContext('pidfile creation', () {
|
|
final BufferLogger testLogger = BufferLogger.test();
|
|
final Signals signals = _TestSignals(Signals.defaultExitSignals);
|
|
final Terminal terminal = Terminal.test();
|
|
final MemoryFileSystem fs = MemoryFileSystem.test();
|
|
final ProcessInfo processInfo = ProcessInfo.test(fs);
|
|
final FakeResidentRunner residentRunner = FakeResidentRunner(
|
|
FlutterDevice(FakeDevice(), buildInfo: BuildInfo.debug, generator: FakeResidentCompiler()),
|
|
testLogger,
|
|
fs,
|
|
);
|
|
residentRunner
|
|
..supportsRestart = true
|
|
..supportsServiceProtocol = true
|
|
..stayResident = true;
|
|
|
|
const String filename = 'test.pid';
|
|
final TerminalHandler terminalHandler = TerminalHandler(
|
|
residentRunner,
|
|
logger: testLogger,
|
|
signals: signals,
|
|
terminal: terminal,
|
|
processInfo: processInfo,
|
|
reportReady: false,
|
|
pidFile: filename,
|
|
);
|
|
|
|
expect(fs.file(filename), isNot(exists));
|
|
terminalHandler.setupTerminal();
|
|
terminalHandler.registerSignalHandlers();
|
|
expect(fs.file(filename), exists);
|
|
terminalHandler.stop();
|
|
expect(fs.file(filename), isNot(exists));
|
|
});
|
|
}
|
|
|
|
class FakeResidentRunner extends ResidentHandlers {
|
|
FakeResidentRunner(FlutterDevice device, this.logger, this.fileSystem) : flutterDevices = <FlutterDevice>[device];
|
|
|
|
bool calledDetach = false;
|
|
bool calledPrint = false;
|
|
bool calledExit = false;
|
|
bool calledPrintWithDetails = false;
|
|
bool calledReload = false;
|
|
bool calledRestart = false;
|
|
int reloadExitCode = 0;
|
|
bool fatalReloadError = false;
|
|
|
|
@override
|
|
final Logger logger;
|
|
|
|
@override
|
|
final FileSystem fileSystem;
|
|
|
|
@override
|
|
final List<FlutterDevice> flutterDevices;
|
|
|
|
@override
|
|
bool canHotReload = true;
|
|
|
|
@override
|
|
bool hotMode = true;
|
|
|
|
@override
|
|
bool isRunningDebug = true;
|
|
|
|
@override
|
|
bool isRunningProfile = false;
|
|
|
|
@override
|
|
bool isRunningRelease = false;
|
|
|
|
@override
|
|
bool stayResident = true;
|
|
|
|
@override
|
|
bool supportsRestart = true;
|
|
|
|
@override
|
|
bool supportsServiceProtocol = true;
|
|
|
|
@override
|
|
bool supportsWriteSkSL = true;
|
|
|
|
@override
|
|
Future<void> cleanupAfterSignal() async { }
|
|
|
|
@override
|
|
Future<void> detach() async {
|
|
calledDetach = true;
|
|
}
|
|
|
|
@override
|
|
Future<void> exit() async {
|
|
calledExit = true;
|
|
}
|
|
|
|
@override
|
|
void printHelp({bool details}) {
|
|
if (details) {
|
|
calledPrintWithDetails = true;
|
|
} else {
|
|
calledPrint = true;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> runSourceGenerators() async { }
|
|
|
|
@override
|
|
Future<OperationResult> restart({bool fullRestart = false, bool pause = false, String reason}) async {
|
|
if (fullRestart && !supportsRestart) {
|
|
throw StateError('illegal restart');
|
|
}
|
|
if (!fullRestart && !canHotReload) {
|
|
throw StateError('illegal reload');
|
|
}
|
|
if (fullRestart) {
|
|
calledRestart = true;
|
|
} else {
|
|
calledReload = true;
|
|
}
|
|
return OperationResult(reloadExitCode, '', fatal: fatalReloadError);
|
|
}
|
|
|
|
@override
|
|
ResidentDevtoolsHandler get residentDevtoolsHandler => _residentDevtoolsHandler;
|
|
final ResidentDevtoolsHandler _residentDevtoolsHandler = FakeResidentDevtoolsHandler();
|
|
}
|
|
|
|
class FakeResidentDevtoolsHandler extends Fake implements ResidentDevtoolsHandler {
|
|
bool calledLaunchDevToolsInBrowser = false;
|
|
|
|
@override
|
|
bool launchDevToolsInBrowser({List<FlutterDevice> flutterDevices}) {
|
|
return calledLaunchDevToolsInBrowser = true;
|
|
}
|
|
}
|
|
|
|
class FakeDevice extends Fake implements Device {
|
|
@override
|
|
bool isSupported() => true;
|
|
|
|
@override
|
|
bool supportsScreenshot = false;
|
|
|
|
@override
|
|
String get name => 'Fake Device';
|
|
|
|
@override
|
|
Future<void> takeScreenshot(File file) async {
|
|
if (!supportsScreenshot) {
|
|
throw StateError('illegal screenshot attempt');
|
|
}
|
|
file.writeAsBytesSync(<int>[1, 2, 3, 4]);
|
|
}
|
|
|
|
}
|
|
|
|
TerminalHandler setUpTerminalHandler(List<FakeVmServiceRequest> requests, {
|
|
bool supportsRestart = true,
|
|
bool supportsServiceProtocol = true,
|
|
bool supportsHotReload = true,
|
|
bool web = false,
|
|
bool fatalReloadError = false,
|
|
bool supportsScreenshot = false,
|
|
int reloadExitCode = 0,
|
|
BuildMode buildMode = BuildMode.debug,
|
|
Logger logger,
|
|
FileSystem fileSystem,
|
|
}) {
|
|
final Logger testLogger = logger ?? BufferLogger.test();
|
|
final Signals signals = Signals.test();
|
|
final Terminal terminal = Terminal.test();
|
|
final FileSystem localFileSystem = fileSystem ?? MemoryFileSystem.test();
|
|
final ProcessInfo processInfo = ProcessInfo.test(MemoryFileSystem.test());
|
|
final FlutterDevice device = FlutterDevice(
|
|
FakeDevice()..supportsScreenshot = supportsScreenshot,
|
|
buildInfo: BuildInfo(buildMode, '', treeShakeIcons: false),
|
|
generator: FakeResidentCompiler(),
|
|
targetPlatform: web
|
|
? TargetPlatform.web_javascript
|
|
: TargetPlatform.android_arm,
|
|
);
|
|
device.vmService = FakeVmServiceHost(requests: requests).vmService;
|
|
final FakeResidentRunner residentRunner = FakeResidentRunner(device, testLogger, localFileSystem)
|
|
..supportsServiceProtocol = supportsServiceProtocol
|
|
..supportsRestart = supportsRestart
|
|
..canHotReload = supportsHotReload
|
|
..fatalReloadError = fatalReloadError
|
|
..reloadExitCode = reloadExitCode;
|
|
|
|
switch (buildMode) {
|
|
case BuildMode.debug:
|
|
residentRunner
|
|
..isRunningDebug = true
|
|
..isRunningProfile = false
|
|
..isRunningRelease = false;
|
|
break;
|
|
case BuildMode.profile:
|
|
residentRunner
|
|
..isRunningDebug = false
|
|
..isRunningProfile = true
|
|
..isRunningRelease = false;
|
|
break;
|
|
case BuildMode.release:
|
|
residentRunner
|
|
..isRunningDebug = false
|
|
..isRunningProfile = false
|
|
..isRunningRelease = true;
|
|
break;
|
|
}
|
|
return TerminalHandler(
|
|
residentRunner,
|
|
logger: testLogger,
|
|
signals: signals,
|
|
terminal: terminal,
|
|
processInfo: processInfo,
|
|
reportReady: false,
|
|
);
|
|
}
|
|
|
|
class FakeResidentCompiler extends Fake implements ResidentCompiler {}
|
|
|
|
class TestRunner extends Fake implements ResidentRunner {
|
|
bool hasHelpBeenPrinted = false;
|
|
String receivedCommand;
|
|
|
|
@override
|
|
Future<void> cleanupAfterSignal() async { }
|
|
|
|
@override
|
|
Future<void> cleanupAtFinish() async { }
|
|
|
|
@override
|
|
void printHelp({ bool details }) {
|
|
hasHelpBeenPrinted = true;
|
|
}
|
|
|
|
@override
|
|
Future<int> run({
|
|
Completer<DebugConnectionInfo> connectionInfoCompleter,
|
|
Completer<void> appStartedCompleter,
|
|
bool enableDevTools = false,
|
|
String route,
|
|
}) async => null;
|
|
|
|
@override
|
|
Future<int> attach({
|
|
Completer<DebugConnectionInfo> connectionInfoCompleter,
|
|
Completer<void> appStartedCompleter,
|
|
bool allowExistingDdsInstance = false,
|
|
bool enableDevTools = false,
|
|
}) async => null;
|
|
}
|
|
|
|
class _TestSignals implements Signals {
|
|
_TestSignals(this.exitSignals);
|
|
|
|
final List<ProcessSignal> exitSignals;
|
|
|
|
final Map<ProcessSignal, Map<Object, SignalHandler>> _handlersTable =
|
|
<ProcessSignal, Map<Object, SignalHandler>>{};
|
|
|
|
@override
|
|
Object addHandler(ProcessSignal signal, SignalHandler handler) {
|
|
final Object token = Object();
|
|
_handlersTable.putIfAbsent(signal, () => <Object, SignalHandler>{})[token] = handler;
|
|
return token;
|
|
}
|
|
|
|
@override
|
|
Future<bool> removeHandler(ProcessSignal signal, Object token) async {
|
|
if (!_handlersTable.containsKey(signal)) {
|
|
return false;
|
|
}
|
|
if (!_handlersTable[signal].containsKey(token)) {
|
|
return false;
|
|
}
|
|
_handlersTable[signal].remove(token);
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Stream<Object> get errors => _errors.stream;
|
|
final StreamController<Object> _errors = StreamController<Object>();
|
|
}
|