io_test.dart 4.43 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7
// 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;

8
import 'package:file/memory.dart';
9
import 'package:flutter_tools/src/base/io.dart';
10
import 'package:flutter_tools/src/base/platform.dart';
11
import 'package:test/fake.dart';
12

13
import '../../src/common.dart';
14
import '../../src/io.dart';
15 16

void main() {
17
  testWithoutContext('IOOverrides can inject a memory file system', () async {
18
    final MemoryFileSystem memoryFileSystem = MemoryFileSystem.test();
19 20 21 22 23
    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);
24

25 26 27 28 29
      // 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();
30

31 32 33
      expect(memoryFileSystem.file('abc').existsSync(), true);
      expect(memoryFileSystem.file('abc').readAsStringSync(), 'def');
      expect(memoryFileSystem.directory('foobar').existsSync(), true);
34

35 36 37 38 39
      // 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();
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
      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);
  });
57 58

  testWithoutContext('ProcessSignal signals are properly delegated', () async {
59 60
    final FakeProcessSignal signal = FakeProcessSignal();
    final ProcessSignal signalUnderTest = ProcessSignal(signal);
61

62
    signal.controller.add(signal);
63 64 65 66

    expect(signalUnderTest, await signalUnderTest.watch().first);
  });

67
  testWithoutContext('ProcessSignal toString() works', () async {
68
    expect(io.ProcessSignal.sigint.toString(), ProcessSignal.sigint.toString());
69
  });
70

71
  testWithoutContext('exit throws a StateError if called without being overridden', () {
Dan Field's avatar
Dan Field committed
72
    expect(() => exit(0), throwsAssertionError);
73 74
  });

75
  testWithoutContext('exit does not throw a StateError if overridden', () {
Dan Field's avatar
Dan Field committed
76 77
    try {
      setExitFunctionForTests((int value) {});
78

Dan Field's avatar
Dan Field committed
79 80 81 82
      expect(() => exit(0), returnsNormally);
    } finally {
      restoreExitFunction();
    }
83
  });
84

85
  testWithoutContext('test_api defines the Declarer in a known place', () {
86 87
    expect(Zone.current[#test.declarer], isNotNull);
  });
88

89
  testWithoutContext('listNetworkInterfaces() uses overrides', () async {
90 91
    setNetworkInterfaceLister(
      ({
92 93 94
        bool? includeLoopback,
        bool? includeLinkLocal,
        InternetAddressType? type,
95 96 97 98 99 100 101
      }) async => <NetworkInterface>[],
    );

    expect(await listNetworkInterfaces(), isEmpty);

    resetNetworkInterfaceLister();
  });
102 103 104

  testWithoutContext('Does not listen to Posix process signals on windows', () async {
    final FakePlatform windows = FakePlatform(operatingSystem: 'windows');
105
    final FakePlatform linux = FakePlatform();
106 107 108 109 110 111 112 113
    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);
  });
114 115
}

116 117 118 119 120 121
class FakeProcessSignal extends Fake implements io.ProcessSignal {
  final StreamController<io.ProcessSignal> controller = StreamController<io.ProcessSignal>();

  @override
  Stream<io.ProcessSignal> watch() => controller.stream;
}