file_system_test.dart 6.71 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7 8 9
import 'dart:async';
import 'dart:io' as io;

10 11
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
12
import 'package:flutter_tools/src/base/io.dart';
13
import 'package:flutter_tools/src/base/platform.dart';
14
import 'package:flutter_tools/src/base/signals.dart';
15
import 'package:test/fake.dart';
16

17
import '../../src/common.dart';
18
import '../../src/context.dart';
19

20
void main() {
21
  group('fsUtils', () {
22
    MemoryFileSystem fs;
23
    FileSystemUtils fsUtils;
24 25

    setUp(() {
26
      fs = MemoryFileSystem.test();
27 28
      fsUtils = FileSystemUtils(
        fileSystem: fs,
29
        platform: FakePlatform(),
30
      );
31 32
    });

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    testWithoutContext('getUniqueFile creates a unique file name', () async {
      final File fileA = fsUtils.getUniqueFile(fs.currentDirectory, 'foo', 'json')
        ..createSync();
      final File fileB = fsUtils.getUniqueFile(fs.currentDirectory, 'foo', 'json');

      expect(fileA.path, '/foo_01.json');
      expect(fileB.path, '/foo_02.json');
    });

    testWithoutContext('getUniqueDirectory creates a unique directory name', () async {
      final Directory directoryA = fsUtils.getUniqueDirectory(fs.currentDirectory, 'foo')
        ..createSync();
      final Directory directoryB = fsUtils.getUniqueDirectory(fs.currentDirectory, 'foo');

      expect(directoryA.path, '/foo_01');
      expect(directoryB.path, '/foo_02');
    });
50 51 52
  });

  group('copyDirectorySync', () {
53 54
    /// Test file_systems.copyDirectorySync() using MemoryFileSystem.
    /// Copies between 2 instances of file systems which is also supported by copyDirectorySync().
55
    testWithoutContext('test directory copy', () async {
56
      final MemoryFileSystem sourceMemoryFs = MemoryFileSystem.test();
57
      const String sourcePath = '/some/origin';
58
      final Directory sourceDirectory = await sourceMemoryFs.directory(sourcePath).create(recursive: true);
59
      sourceMemoryFs.currentDirectory = sourcePath;
60 61
      final File sourceFile1 = sourceMemoryFs.file('some_file.txt')..writeAsStringSync('bleh');
      final DateTime writeTime = sourceFile1.lastModifiedSync();
62 63 64 65
      sourceMemoryFs.file('sub_dir/another_file.txt').createSync(recursive: true);
      sourceMemoryFs.directory('empty_directory').createSync();

      // Copy to another memory file system instance.
66
      final MemoryFileSystem targetMemoryFs = MemoryFileSystem.test();
67
      const String targetPath = '/some/non-existent/target';
68
      final Directory targetDirectory = targetMemoryFs.directory(targetPath);
69

70
      copyDirectory(sourceDirectory, targetDirectory);
71

72 73 74 75 76 77 78 79 80 81 82
      expect(targetDirectory.existsSync(), true);
      targetMemoryFs.currentDirectory = targetPath;
      expect(targetMemoryFs.directory('empty_directory').existsSync(), true);
      expect(targetMemoryFs.file('sub_dir/another_file.txt').existsSync(), true);
      expect(targetMemoryFs.file('some_file.txt').readAsStringSync(), 'bleh');

      // Assert that the copy operation hasn't modified the original file in some way.
      expect(sourceMemoryFs.file('some_file.txt').lastModifiedSync(), writeTime);
      // There's still 3 things in the original directory as there were initially.
      expect(sourceMemoryFs.directory(sourcePath).listSync().length, 3);
    });
83

84
    testWithoutContext('Skip files if shouldCopyFile returns false', () {
85
      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
86
      final Directory origin = fileSystem.directory('/origin');
87
      origin.createSync();
88 89 90 91
      fileSystem.file(fileSystem.path.join('origin', 'a.txt')).writeAsStringSync('irrelevant');
      fileSystem.directory('/origin/nested').createSync();
      fileSystem.file(fileSystem.path.join('origin', 'nested', 'a.txt')).writeAsStringSync('irrelevant');
      fileSystem.file(fileSystem.path.join('origin', 'nested', 'b.txt')).writeAsStringSync('irrelevant');
92

93
      final Directory destination = fileSystem.directory('/destination');
94
      copyDirectory(origin, destination, shouldCopyFile: (File origin, File dest) {
95 96 97 98 99 100 101 102 103 104
        return origin.basename == 'b.txt';
      });

      expect(destination.existsSync(), isTrue);
      expect(destination.childDirectory('nested').existsSync(), isTrue);
      expect(destination.childDirectory('nested').childFile('b.txt').existsSync(), isTrue);

      expect(destination.childFile('a.txt').existsSync(), isFalse);
      expect(destination.childDirectory('nested').childFile('a.txt').existsSync(), isFalse);
    });
105
  });
106

107
  group('escapePath', () {
108
    testWithoutContext('on Windows', () {
109
      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
110 111 112 113
      final FileSystemUtils fsUtils = FileSystemUtils(
        fileSystem: fileSystem,
        platform: FakePlatform(operatingSystem: 'windows'),
      );
114 115
      expect(fsUtils.escapePath(r'C:\foo\bar\cool.dart'), r'C:\\foo\\bar\\cool.dart');
      expect(fsUtils.escapePath(r'foo\bar\cool.dart'), r'foo\\bar\\cool.dart');
116
      expect(fsUtils.escapePath('C:/foo/bar/cool.dart'), 'C:/foo/bar/cool.dart');
117 118
    });

119
    testWithoutContext('on Linux', () {
120
      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
121 122 123 124 125 126
      final FileSystemUtils fsUtils = FileSystemUtils(
        fileSystem: fileSystem,
        platform: FakePlatform(operatingSystem: 'linux'),
      );
      expect(fsUtils.escapePath('/foo/bar/cool.dart'), '/foo/bar/cool.dart');
      expect(fsUtils.escapePath('foo/bar/cool.dart'), 'foo/bar/cool.dart');
127
      expect(fsUtils.escapePath(r'foo\cool.dart'), r'foo\cool.dart');
128 129
    });
  });
130 131

  group('LocalFileSystem', () {
132
    FakeProcessSignal fakeSignal;
133 134 135
    ProcessSignal signalUnderTest;

    setUp(() {
136 137
      fakeSignal = FakeProcessSignal();
      signalUnderTest = ProcessSignal(fakeSignal);
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    });

    testUsingContext('deletes system temp entry on a fatal signal', () async {
      final Completer<void> completer = Completer<void>();
      final Signals signals = Signals.test();
      final LocalFileSystem localFileSystem = LocalFileSystem.test(
        signals: signals,
        fatalSignals: <ProcessSignal>[signalUnderTest],
      );
      final Directory temp = localFileSystem.systemTempDirectory;

      signals.addHandler(signalUnderTest, (ProcessSignal s) {
        completer.complete();
      });

      expect(temp.existsSync(), isTrue);

155
      fakeSignal.controller.add(fakeSignal);
156 157 158 159 160
      await completer.future;

      expect(temp.existsSync(), isFalse);
    });
  });
161
}
162

163 164 165 166 167 168 169
class FakeProcessSignal extends Fake implements io.ProcessSignal {
  final StreamController<io.ProcessSignal> controller = StreamController<io.ProcessSignal>();

  @override
  Stream<io.ProcessSignal> watch() => controller.stream;
}
class FakeFile extends Fake implements File {}