analyze_continuously_test.dart 8.16 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
import 'dart:async';

9
import 'package:file/memory.dart';
10 11
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
12
import 'package:flutter_tools/src/base/file_system.dart';
13 14
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
15
import 'package:flutter_tools/src/base/platform.dart';
16
import 'package:flutter_tools/src/base/terminal.dart';
17
import 'package:flutter_tools/src/cache.dart';
18
import 'package:flutter_tools/src/commands/analyze.dart';
19
import 'package:flutter_tools/src/dart/analysis.dart';
20
import 'package:flutter_tools/src/dart/pub.dart';
21
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
22
import 'package:process/process.dart';
23

24 25
import '../../src/common.dart';
import '../../src/context.dart';
26
import '../../src/fake_process_manager.dart';
27
import '../../src/test_flutter_command_runner.dart';
28 29

void main() {
30 31 32 33
  setUpAll(() {
    Cache.flutterRoot = getFlutterRoot();
  });

34 35
  AnalysisServer server;
  Directory tempDir;
36 37 38 39 40
  FileSystem fileSystem;
  Platform platform;
  ProcessManager processManager;
  AnsiTerminal terminal;
  Logger logger;
41 42

  setUp(() {
43
    fileSystem = globals.localFileSystem;
44
    platform = const LocalPlatform();
45
    processManager = const LocalProcessManager();
46 47 48
    terminal = AnsiTerminal(platform: platform, stdio: Stdio());
    logger = BufferLogger(outputPreferences: OutputPreferences.test(), terminal: terminal);
    tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analysis_test.');
49 50 51
  });

  tearDown(() {
52
    tryToDelete(tempDir);
53 54 55
    return server?.dispose();
  });

56 57 58 59 60

  void _createSampleProject(Directory directory, { bool brokenCode = false }) {
    final File pubspecFile = fileSystem.file(fileSystem.path.join(directory.path, 'pubspec.yaml'));
    pubspecFile.writeAsStringSync('''
  name: foo_project
61 62
  environment:
    sdk: '>=2.10.0 <3.0.0'
63 64 65 66 67 68 69 70 71 72 73 74
  ''');

    final File dartFile = fileSystem.file(fileSystem.path.join(directory.path, 'lib', 'main.dart'));
    dartFile.parent.createSync();
    dartFile.writeAsStringSync('''
  void main() {
    print('hello world');
    ${brokenCode ? 'prints("hello world");' : ''}
  }
  ''');
  }

75
  group('analyze --watch', () {
76 77
    testUsingContext('AnalysisServer success', () async {
      _createSampleProject(tempDir);
78

79 80 81 82 83 84 85 86
      final Pub pub = Pub(
        fileSystem: fileSystem,
        logger: logger,
        processManager: processManager,
        platform: const LocalPlatform(),
        botDetector: globals.botDetector,
        usage: globals.flutterUsage,
      );
87 88 89 90 91
      await pub.get(
        context: PubContext.flutterTests,
        directory: tempDir.path,
        generateSyntheticPackage: false,
      );
92

93
      server = AnalysisServer(
94
        globals.artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path,
95
        <String>[tempDir.path],
96 97 98 99 100 101
        fileSystem: fileSystem,
        platform: platform,
        processManager: processManager,
        logger: logger,
        terminal: terminal,
      );
102 103 104 105

      int errorCount = 0;
      final Future<bool> onDone = server.onAnalyzing.where((bool analyzing) => analyzing == false).first;
      server.onErrors.listen((FileAnalysisErrors errors) => errorCount += errors.errors.length);
106

107 108 109 110
      await server.start();
      await onDone;

      expect(errorCount, 0);
111
    });
112
  });
113

114 115 116
  testUsingContext('AnalysisServer errors', () async {
    _createSampleProject(tempDir, brokenCode: true);

117 118 119 120 121 122 123
    final Pub pub = Pub(
      fileSystem: fileSystem,
      logger: logger,
      processManager: processManager,
      platform: const LocalPlatform(),
      usage: globals.flutterUsage,
      botDetector: globals.botDetector,
124 125 126 127 128
    );
    await pub.get(
      context: PubContext.flutterTests,
      directory: tempDir.path,
      generateSyntheticPackage: false,
129
    );
130

131
      server = AnalysisServer(
132
        globals.artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path,
133 134 135 136 137 138 139
        <String>[tempDir.path],
        fileSystem: fileSystem,
        platform: platform,
        processManager: processManager,
        logger: logger,
        terminal: terminal,
      );
140 141 142 143 144

    int errorCount = 0;
    final Future<bool> onDone = server.onAnalyzing.where((bool analyzing) => analyzing == false).first;
    server.onErrors.listen((FileAnalysisErrors errors) {
      errorCount += errors.errors.length;
145
    });
146 147 148 149 150

    await server.start();
    await onDone;

    expect(errorCount, greaterThan(0));
151
  });
152

153
  testUsingContext('Returns no errors when source is error-free', () async {
154
    const String contents = "StringBuffer bar = StringBuffer('baz');";
155
    tempDir.childFile('main.dart').writeAsStringSync(contents);
156
    server = AnalysisServer(
157
      globals.artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path,
158
      <String>[tempDir.path],
159 160 161 162 163 164
      fileSystem: fileSystem,
      platform: platform,
      processManager: processManager,
      logger: logger,
      terminal: terminal,
    );
165

166 167 168 169 170 171 172 173 174
    int errorCount = 0;
    final Future<bool> onDone = server.onAnalyzing.where((bool analyzing) => analyzing == false).first;
    server.onErrors.listen((FileAnalysisErrors errors) {
      errorCount += errors.errors.length;
    });
    await server.start();
    await onDone;
    expect(errorCount, 0);
  });
175 176 177 178 179 180 181 182

  testUsingContext('Can run AnalysisService with customized cache location', () async {
    final Completer<void> completer = Completer<void>();
    final StreamController<List<int>> stdin = StreamController<List<int>>();
    final FakeProcessManager processManager = FakeProcessManager.list(
      <FakeCommand>[
        FakeCommand(
          command: const <String>[
183
            'HostArtifact.engineDartSdkPath/bin/dart',
184
            '--disable-dart-dev',
185
            'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
186 187 188
            '--disable-server-feature-completion',
            '--disable-server-feature-search',
            '--sdk',
189
            'HostArtifact.engineDartSdkPath',
190 191 192 193 194 195
          ],
          completer: completer,
          stdin: IOSink(stdin.sink),
        ),
      ]);

196
    final Artifacts artifacts = Artifacts.test();
197 198 199 200 201 202 203 204 205 206 207 208 209 210
    final AnalyzeCommand command = AnalyzeCommand(
      terminal: Terminal.test(),
      artifacts: artifacts,
      logger: BufferLogger.test(),
      platform: FakePlatform(operatingSystem: 'linux'),
      fileSystem: MemoryFileSystem.test(),
      processManager: processManager,
    );

    final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
    commandRunner.addCommand(command);
    unawaited(commandRunner.run(<String>['analyze', '--watch']));
    await stdin.stream.first;

211
    expect(processManager, hasNoRemainingExpectations);
212 213 214 215 216 217 218 219 220
  });

  testUsingContext('Can run AnalysisService with customized cache location --watch', () async {
    final Completer<void> completer = Completer<void>();
    final StreamController<List<int>> stdin = StreamController<List<int>>();
    final FakeProcessManager processManager = FakeProcessManager.list(
      <FakeCommand>[
        FakeCommand(
          command: const <String>[
221
            'HostArtifact.engineDartSdkPath/bin/dart',
222
            '--disable-dart-dev',
223
            'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
224 225 226
            '--disable-server-feature-completion',
            '--disable-server-feature-search',
            '--sdk',
227
            'HostArtifact.engineDartSdkPath',
228 229 230 231 232 233
          ],
          completer: completer,
          stdin: IOSink(stdin.sink),
        ),
      ]);

234
    final Artifacts artifacts = Artifacts.test();
235 236 237 238 239 240 241 242 243 244 245 246 247 248
    final AnalyzeCommand command = AnalyzeCommand(
      terminal: Terminal.test(),
      artifacts: artifacts,
      logger: BufferLogger.test(),
      platform: FakePlatform(operatingSystem: 'linux'),
      fileSystem: MemoryFileSystem.test(),
      processManager: processManager,
    );

    final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
    commandRunner.addCommand(command);
    unawaited(commandRunner.run(<String>['analyze', '--watch']));
    await stdin.stream.first;

249
    expect(processManager, hasNoRemainingExpectations);
250
  });
251
}