// 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 'dart:async'; import 'dart:io' as io; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:test/fake.dart'; import '../../src/common.dart'; import '../../src/io.dart'; void main() { testWithoutContext('IOOverrides can inject a memory file system', () async { final MemoryFileSystem memoryFileSystem = MemoryFileSystem.test(); final FlutterIOOverrides flutterIOOverrides = FlutterIOOverrides(fileSystem: memoryFileSystem); await io.IOOverrides.runWithIOOverrides(() async { // statics delegate correctly. expect(io.FileSystemEntity.isWatchSupported, memoryFileSystem.isWatchSupported); expect(io.Directory.systemTemp.path, memoryFileSystem.systemTempDirectory.path); // can create and write to files/directories sync. final io.File file = io.File('abc'); file.writeAsStringSync('def'); final io.Directory directory = io.Directory('foobar'); directory.createSync(); expect(memoryFileSystem.file('abc').existsSync(), true); expect(memoryFileSystem.file('abc').readAsStringSync(), 'def'); expect(memoryFileSystem.directory('foobar').existsSync(), true); // can create and write to files/directories async. final io.File fileB = io.File('xyz'); await fileB.writeAsString('def'); final io.Directory directoryB = io.Directory('barfoo'); await directoryB.create(); expect(memoryFileSystem.file('xyz').existsSync(), true); expect(memoryFileSystem.file('xyz').readAsStringSync(), 'def'); expect(memoryFileSystem.directory('barfoo').existsSync(), true); // Links final io.Link linkA = io.Link('hhh'); final io.Link linkB = io.Link('ggg'); io.File('jjj').createSync(); io.File('lll').createSync(); await linkA.create('jjj'); linkB.createSync('lll'); expect(await memoryFileSystem.link('hhh').resolveSymbolicLinks(), await linkA.resolveSymbolicLinks()); expect(memoryFileSystem.link('ggg').resolveSymbolicLinksSync(), linkB.resolveSymbolicLinksSync()); }, flutterIOOverrides); }); testWithoutContext('ProcessSignal signals are properly delegated', () async { final FakeProcessSignal signal = FakeProcessSignal(); final ProcessSignal signalUnderTest = ProcessSignal(signal); signal.controller.add(signal); expect(signalUnderTest, await signalUnderTest.watch().first); }); testWithoutContext('ProcessSignal toString() works', () async { expect(io.ProcessSignal.sigint.toString(), ProcessSignal.sigint.toString()); }); testWithoutContext('exit throws a StateError if called without being overridden', () { expect(() => exit(0), throwsAssertionError); }); testWithoutContext('exit does not throw a StateError if overridden', () { try { setExitFunctionForTests((int value) {}); expect(() => exit(0), returnsNormally); } finally { restoreExitFunction(); } }); testWithoutContext('test_api defines the Declarer in a known place', () { expect(Zone.current[#test.declarer], isNotNull); }); testWithoutContext('listNetworkInterfaces() uses overrides', () async { setNetworkInterfaceLister( ({ bool? includeLoopback, bool? includeLinkLocal, InternetAddressType? type, }) async => <NetworkInterface>[], ); expect(await listNetworkInterfaces(), isEmpty); resetNetworkInterfaceLister(); }); testWithoutContext('Does not listen to Posix process signals on windows', () async { final FakePlatform windows = FakePlatform(operatingSystem: 'windows'); final FakePlatform linux = FakePlatform(); final FakeProcessSignal fakeSignalA = FakeProcessSignal(); final FakeProcessSignal fakeSignalB = FakeProcessSignal(); fakeSignalA.controller.add(fakeSignalA); fakeSignalB.controller.add(fakeSignalB); expect(await PosixProcessSignal(fakeSignalA, platform: windows).watch().isEmpty, true); expect(await PosixProcessSignal(fakeSignalB, platform: linux).watch().first, isNotNull); }); } class FakeProcessSignal extends Fake implements io.ProcessSignal { final StreamController<io.ProcessSignal> controller = StreamController<io.ProcessSignal>(); @override Stream<io.ProcessSignal> watch() => controller.stream; }