file_system_test.dart 6.67 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 7
import 'dart:async';
import 'dart:io' as io;

8 9
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
10
import 'package:flutter_tools/src/base/io.dart';
11
import 'package:flutter_tools/src/base/platform.dart';
12
import 'package:flutter_tools/src/base/signals.dart';
13
import 'package:mockito/mockito.dart';
14

15
import '../../src/common.dart';
16
import '../../src/context.dart';
17 18

class MockPlatform extends Mock implements Platform {}
19

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

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

33 34
    testWithoutContext('recursively creates a directory if it does not exist', () async {
      fsUtils.ensureDirectoryExists('foo/bar/baz.flx');
35
      expect(fs.isDirectorySync('foo/bar'), true);
36
    });
37

38
    testWithoutContext('throws tool exit on failure to create', () async {
39
      fs.file('foo').createSync();
40
      expect(() => fsUtils.ensureDirectoryExists('foo/bar.flx'), throwsToolExit());
41
    });
42 43 44
  });

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

      // Copy to another memory file system instance.
58
      final MemoryFileSystem targetMemoryFs = MemoryFileSystem();
59
      const String targetPath = '/some/non-existent/target';
60
      final Directory targetDirectory = targetMemoryFs.directory(targetPath);
61 62 63 64 65 66

      final FileSystemUtils fsUtils = FileSystemUtils(
        fileSystem: sourceMemoryFs,
        platform: MockPlatform(),
      );
      fsUtils.copyDirectorySync(sourceDirectory, targetDirectory);
67

68 69 70 71 72 73 74 75 76 77 78
      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);
    });
79

80 81 82 83 84 85 86
    testWithoutContext('Skip files if shouldCopyFile returns false', () {
      final MemoryFileSystem fileSystem = MemoryFileSystem();
      final FileSystemUtils fsUtils = FileSystemUtils(
        fileSystem: fileSystem,
        platform: MockPlatform(),
      );
      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 94
      final Directory destination = fileSystem.directory('/destination');
      fsUtils.copyDirectorySync(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 109 110 111 112 113
    testWithoutContext('on Windows', () {
      final MemoryFileSystem fileSystem = MemoryFileSystem();
      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 120 121 122 123 124 125 126
    testWithoutContext('on Linux', () {
      final MemoryFileSystem fileSystem = MemoryFileSystem();
      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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

  group('LocalFileSystem', () {
    MockIoProcessSignal mockSignal;
    ProcessSignal signalUnderTest;
    StreamController<io.ProcessSignal> controller;

    setUp(() {
      mockSignal = MockIoProcessSignal();
      signalUnderTest = ProcessSignal(mockSignal);
      controller = StreamController<io.ProcessSignal>();
      when(mockSignal.watch()).thenAnswer((Invocation invocation) => controller.stream);
    });

    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);

      controller.add(mockSignal);
      await completer.future;

      expect(temp.existsSync(), isFalse);
    });
  });
164
}
165 166

class MockIoProcessSignal extends Mock implements io.ProcessSignal {}