blob: 06e89dbd96dd1e60ffe73d6ba25341a36ea1d94f [file] [log] [blame]
// 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.
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/error_handling_file_system.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:path/path.dart' as path; // ignore: package_path_import
import '../../src/common.dart';
class MockFile extends Mock implements File {}
class MockFileSystem extends Mock implements FileSystem {}
class MockPathContext extends Mock implements path.Context {}
class MockDirectory extends Mock implements Directory {}
final Platform windowsPlatform = FakePlatform(
operatingSystem: 'windows',
environment: <String, String>{}
);
final Platform linuxPlatform = FakePlatform(
operatingSystem: 'linux',
environment: <String, String>{}
);
void setupWriteMocks({
FileSystem mockFileSystem,
ErrorHandlingFileSystem fs,
int errorCode,
}) {
final MockFile mockFile = MockFile();
when(mockFileSystem.file(any)).thenReturn(mockFile);
when(mockFile.writeAsBytes(
any,
mode: anyNamed('mode'),
flush: anyNamed('flush'),
)).thenAnswer((_) async {
throw FileSystemException('', '', OSError('', errorCode));
});
when(mockFile.writeAsString(
any,
mode: anyNamed('mode'),
encoding: anyNamed('encoding'),
flush: anyNamed('flush'),
)).thenAnswer((_) async {
throw FileSystemException('', '', OSError('', errorCode));
});
when(mockFile.writeAsBytesSync(
any,
mode: anyNamed('mode'),
flush: anyNamed('flush'),
)).thenThrow(FileSystemException('', '', OSError('', errorCode)));
when(mockFile.writeAsStringSync(
any,
mode: anyNamed('mode'),
encoding: anyNamed('encoding'),
flush: anyNamed('flush'),
)).thenThrow(FileSystemException('', '', OSError('', errorCode)));
}
void setupCreateTempMocks({
FileSystem mockFileSystem,
ErrorHandlingFileSystem fs,
int errorCode,
}) {
final MockDirectory mockDirectory = MockDirectory();
when(mockFileSystem.directory(any)).thenReturn(mockDirectory);
when(mockDirectory.createTemp(any)).thenAnswer((_) async {
throw FileSystemException('', '', OSError('', errorCode));
});
when(mockDirectory.createTempSync(any))
.thenThrow(FileSystemException('', '', OSError('', errorCode)));
}
void main() {
group('throws ToolExit on Windows', () {
const int kDeviceFull = 112;
const int kUserMappedSectionOpened = 1224;
MockFileSystem mockFileSystem;
ErrorHandlingFileSystem fs;
setUp(() {
mockFileSystem = MockFileSystem();
fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: windowsPlatform,
);
when(mockFileSystem.path).thenReturn(MockPathContext());
});
testWithoutContext('when writing to a full device', () async {
setupWriteMocks(
mockFileSystem: mockFileSystem,
fs: fs,
errorCode: kDeviceFull,
);
final File file = fs.file('file');
const String expectedMessage = 'The target device is full';
expect(() async => await file.writeAsBytes(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() async => await file.writeAsString(''),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsBytesSync(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsStringSync(''),
throwsToolExit(message: expectedMessage));
});
testWithoutContext('when the file is being used by another program', () async {
setupWriteMocks(
mockFileSystem: mockFileSystem,
fs: fs,
errorCode: kUserMappedSectionOpened,
);
final File file = fs.file('file');
const String expectedMessage = 'The file is being used by another program';
expect(() async => await file.writeAsBytes(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() async => await file.writeAsString(''),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsBytesSync(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsStringSync(''),
throwsToolExit(message: expectedMessage));
});
testWithoutContext('when creating a temporary dir on a full device', () async {
setupCreateTempMocks(
mockFileSystem: mockFileSystem,
fs: fs,
errorCode: kDeviceFull,
);
final Directory directory = fs.directory('directory');
const String expectedMessage = 'The target device is full';
expect(() async => await directory.createTemp('prefix'),
throwsToolExit(message: expectedMessage));
expect(() => directory.createTempSync('prefix'),
throwsToolExit(message: expectedMessage));
});
});
group('throws ToolExit on Linux', () {
const int enospc= 28;
MockFileSystem mockFileSystem;
ErrorHandlingFileSystem fs;
setUp(() {
mockFileSystem = MockFileSystem();
fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: linuxPlatform,
);
when(mockFileSystem.path).thenReturn(MockPathContext());
});
testWithoutContext('when writing to a full device', () async {
setupWriteMocks(
mockFileSystem: mockFileSystem,
fs: fs,
errorCode: enospc,
);
final File file = fs.file('file');
const String expectedMessage = 'The target device is full';
expect(() async => await file.writeAsBytes(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() async => await file.writeAsString(''),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsBytesSync(<int>[0]),
throwsToolExit(message: expectedMessage));
expect(() => file.writeAsStringSync(''),
throwsToolExit(message: expectedMessage));
});
testWithoutContext('when creating a temporary dir on a full device', () async {
setupCreateTempMocks(
mockFileSystem: mockFileSystem,
fs: fs,
errorCode: enospc,
);
final Directory directory = fs.directory('directory');
const String expectedMessage = 'The target device is full';
expect(() async => await directory.createTemp('prefix'),
throwsToolExit(message: expectedMessage));
expect(() => directory.createTempSync('prefix'),
throwsToolExit(message: expectedMessage));
});
});
testWithoutContext('Caches path context correctly', () {
final MockFileSystem mockFileSystem = MockFileSystem();
final FileSystem fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: const LocalPlatform(),
);
expect(identical(fs.path, fs.path), true);
});
testWithoutContext('Clears cache when CWD changes', () {
final MockFileSystem mockFileSystem = MockFileSystem();
final FileSystem fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: const LocalPlatform(),
);
final Object firstPath = fs.path;
fs.currentDirectory = null;
when(mockFileSystem.path).thenReturn(MockPathContext());
expect(identical(firstPath, fs.path), false);
});
testWithoutContext('Throws type error if Directory type is set to curentDirectory with LocalFileSystem', () {
final FileSystem fs = ErrorHandlingFileSystem(
delegate: const LocalFileSystem(),
platform: const LocalPlatform(),
);
final MockDirectory directory = MockDirectory();
when(directory.path).thenReturn('path');
expect(() => fs.currentDirectory = directory, throwsA(isA<TypeError>()));
});
group('toString() gives toString() of delegate', () {
testWithoutContext('ErrorHandlingFileSystem', () {
final MockFileSystem mockFileSystem = MockFileSystem();
final FileSystem fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: const LocalPlatform(),
);
expect(mockFileSystem.toString(), isNotNull);
expect(fs.toString(), equals(mockFileSystem.toString()));
});
testWithoutContext('ErrorHandlingFile', () {
final MockFileSystem mockFileSystem = MockFileSystem();
final FileSystem fs = ErrorHandlingFileSystem(
delegate: mockFileSystem,
platform: const LocalPlatform(),
);
final MockFile mockFile = MockFile();
when(mockFileSystem.file(any)).thenReturn(mockFile);
expect(mockFile.toString(), isNotNull);
expect(fs.file('file').toString(), equals(mockFile.toString()));
});
});
}