forbidden_imports_test.dart 10.2 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
import 'package:file/file.dart';
6

7
import '../src/common.dart';
8
import 'test_utils.dart';
9

10
void main() {
11
  final String flutterTools = fileSystem.path.join(getFlutterRoot(), 'packages', 'flutter_tools');
12

13 14
  test('no imports of commands/* or test/* in lib/src/*', () {
    final List<String> skippedPaths = <String> [
15 16
      fileSystem.path.join(flutterTools, 'lib', 'src', 'commands'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'test'),
17 18 19
    ];
    bool _isNotSkipped(FileSystemEntity entity) => skippedPaths.every((String path) => !entity.path.startsWith(path));

20
    final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, 'lib', 'src'))
21 22 23 24
      .listSync(recursive: true)
      .where(_isDartFile)
      .where(_isNotSkipped)
      .map(_asFile);
25 26
    for (final File file in files) {
      for (final String line in file.readAsLinesSync()) {
27 28 29 30 31
        if (line.startsWith(RegExp(r'import.*package:'))) {
          continue;
        }
        if (line.startsWith(RegExp(r'import.*commands/'))
         || line.startsWith(RegExp(r'import.*test/'))) {
32
          final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
33 34 35 36 37 38 39
          fail('$relativePath imports $line. This import introduces a layering violation. '
               'Please find another way to access the information you are using.');
        }
      }
    }
  });

40 41 42 43
  test('no imports of globals without a global prefix', () {
    final List<String> skippedPaths = <String> [];
    bool _isNotSkipped(FileSystemEntity entity) => skippedPaths.every((String path) => !entity.path.startsWith(path));

44
    final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, 'lib', 'src'))
45
      .listSync(recursive: true)
46
      .followedBy(fileSystem.directory(fileSystem.path.join(flutterTools, 'test',)).listSync(recursive: true))
47 48 49
      .where(_isDartFile)
      .where(_isNotSkipped)
      .map(_asFile);
50 51
    for (final File file in files) {
      for (final String line in file.readAsLinesSync()) {
52 53
        if (line.startsWith(RegExp(r'import.*globals.dart'))
         && !line.contains(r'as globals')) {
54
          final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
55 56 57 58 59 60
          fail('$relativePath imports globals.dart without a globals prefix.');
        }
      }
    }
  });

61
  test('no unauthorized imports of dart:io', () {
62
    final List<String> allowedPaths = <String>[
63 64 65
      fileSystem.path.join(flutterTools, 'lib', 'src', 'base', 'io.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'base', 'platform.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'base', 'error_handling_io.dart'),
66
    ];
67
    bool _isNotAllowed(FileSystemEntity entity) => allowedPaths.every((String path) => path != entity.path);
68

69
    for (final String dirName in <String>['lib', 'bin']) {
70
      final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
71 72
        .listSync(recursive: true)
        .where(_isDartFile)
73
        .where(_isNotAllowed)
74
        .map(_asFile);
75 76
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
77
          if (line.startsWith(RegExp(r'import.*dart:io')) &&
78
              !line.contains('ignore: dart_io_import')) {
79
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
80
            fail("$relativePath imports 'dart:io'; import 'lib/src/base/io.dart' instead");
81 82
          }
        }
83
      }
84 85 86
    }
  });

87
  test('no unauthorized imports of test_api', () {
88
    final List<String> allowedPaths = <String>[
89 90 91 92
      fileSystem.path.join(flutterTools, 'lib', 'src', 'build_runner', 'build_script.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'test', 'flutter_platform.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'test', 'flutter_web_platform.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'test', 'test_wrapper.dart'),
93
    ];
94
    bool _isNotAllowed(FileSystemEntity entity) => allowedPaths.every((String path) => path != entity.path);
95

96
    for (final String dirName in <String>['lib']) {
97
      final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
98 99
        .listSync(recursive: true)
        .where(_isDartFile)
100
        .where(_isNotAllowed)
101
        .map(_asFile);
102 103
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
104 105
          if (line.startsWith(RegExp(r'import.*package:test_api')) &&
              !line.contains('ignore: test_api_import')) {
106
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
107 108 109 110 111 112 113
            fail("$relativePath imports 'package:test_api/test_api.dart';");
          }
        }
      }
    }
  });

114
  test('no unauthorized imports of package:path', () {
115
    final List<String> allowedPath = <String>[
116 117
      fileSystem.path.join(flutterTools, 'lib', 'src', 'build_runner', 'web_compilation_delegate.dart'),
      fileSystem.path.join(flutterTools, 'test', 'general.shard', 'platform_plugins_test.dart'),
118
    ];
119
    for (final String dirName in <String>['lib', 'bin', 'test']) {
120
      final Iterable<File> files =  fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
121 122
        .listSync(recursive: true)
        .where(_isDartFile)
123
        .where((FileSystemEntity entity) => !allowedPath.contains(entity.path))
124
        .map(_asFile);
125 126
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
127
          if (line.startsWith(RegExp(r'import.*package:path/path.dart')) &&
128
              !line.contains('ignore: package_path_import')) {
129 130
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
            fail("$relativePath imports 'package:path/path.dart'; use 'fileSystem.path' instead");
131 132
          }
        }
133
      }
134 135
    }
  });
136

137
  test('no unauthorized imports of package:file/local.dart', () {
138
    final List<String> allowedPath = <String>[
139 140
      fileSystem.path.join(flutterTools, 'test', 'integration.shard', 'test_utils.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'base', 'file_system.dart'),
141 142
    ];
    for (final String dirName in <String>['lib', 'bin', 'test']) {
143
      final Iterable<File> files =  fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
144 145
        .listSync(recursive: true)
        .where(_isDartFile)
146
        .where((FileSystemEntity entity) => !allowedPath.contains(entity.path))
147 148 149 150
        .map(_asFile);
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
          if (line.startsWith(RegExp(r'import.*package:file/local.dart'))) {
151
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
152 153 154 155 156 157 158
            fail("$relativePath imports 'package:file/local.dart'; use 'lib/src/base/file_system.dart' instead");
          }
        }
      }
    }
  });

159
  test('no unauthorized imports of dart:convert', () {
160
    final List<String> allowedPaths = <String>[
161 162
      fileSystem.path.join(flutterTools, 'lib', 'src', 'convert.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'base', 'error_handling_io.dart'),
163
    ];
164
    bool _isNotAllowed(FileSystemEntity entity) => allowedPaths.every((String path) => path != entity.path);
165

166
    for (final String dirName in <String>['lib']) {
167
      final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
168 169
        .listSync(recursive: true)
        .where(_isDartFile)
170
        .where(_isNotAllowed)
171
        .map(_asFile);
172 173
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
174
          if (line.startsWith(RegExp(r'import.*dart:convert')) &&
175
              !line.contains('ignore: dart_convert_import')) {
176
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
177 178 179 180 181 182
            fail("$relativePath imports 'dart:convert'; import 'lib/src/convert.dart' instead");
          }
        }
      }
    }
  });
183

184
  test('no unauthorized imports of build_runner or dwds', () {
185
    final List<String> allowedPaths = <String>[
186 187 188 189 190
      fileSystem.path.join(flutterTools, 'test', 'src', 'build_runner'),
      fileSystem.path.join(flutterTools, 'lib', 'src', 'build_runner'),
      fileSystem.path.join(flutterTools, 'lib', 'executable.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'devfs_web.dart'),
      fileSystem.path.join(flutterTools, 'lib', 'resident_web_runner.dart'),
191
    ];
192
    bool _isNotAllowed(FileSystemEntity entity) => allowedPaths.every((String path) => !entity.path.contains(path));
193

194
    for (final String dirName in <String>['lib']) {
195
      final Iterable<File> files = fileSystem.directory(fileSystem.path.join(flutterTools, dirName))
196 197
        .listSync(recursive: true)
        .where(_isDartFile)
198
        .where(_isNotAllowed)
199
        .map(_asFile);
200 201
      for (final File file in files) {
        for (final String line in file.readAsLinesSync()) {
202 203 204
          if (line.startsWith(RegExp(r'import.*package:build_runner_core/build_runner_core.dart')) ||
              line.startsWith(RegExp(r'import.*package:build_runner/build_runner.dart')) ||
              line.startsWith(RegExp(r'import.*package:build_config/build_config.dart')) ||
205
              line.startsWith(RegExp(r'import.*dwds:*.dart')) ||
206
              line.startsWith(RegExp(r'import.*build_runner/.*.dart'))) {
207
            final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
208 209 210 211 212 213
            fail('$relativePath imports a build_runner package');
          }
        }
      }
    }
  });
214 215

  test('no import of packages in tool_backend.dart', () {
216
    final File file = fileSystem.file(fileSystem.path.join(flutterTools, 'bin', 'tool_backend.dart'));
217 218
    for (final String line in file.readAsLinesSync()) {
      if (line.startsWith(RegExp(r'import.*package:.*'))) {
219
        final String relativePath = fileSystem.path.relative(file.path, from:flutterTools);
220 221 222 223
        fail('$relativePath imports a package');
      }
    }
  });
224
}
225

226
bool _isDartFile(FileSystemEntity entity) => entity is File && entity.path.endsWith('.dart');
227

228
File _asFile(FileSystemEntity entity) => entity as File;