clean_test.dart 6.14 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/memory.dart';
6 7
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
8
import 'package:flutter_tools/src/base/platform.dart';
9
import 'package:flutter_tools/src/commands/clean.dart';
10 11 12
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:flutter_tools/src/project.dart';
13
import 'package:mockito/mockito.dart';
14
import 'package:process/process.dart';
15

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

void main() {
20 21 22 23
  group('clean command', () {
    MockXcode mockXcode;
    setUp(() {
      mockXcode = MockXcode();
24 25
    });

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
    group('general', () {
      MemoryFileSystem fs;
      MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
      Directory buildDirectory;
      FlutterProject projectUnderTest;

      setUp(() {
        fs = MemoryFileSystem();
        mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();

        final Directory currentDirectory = fs.currentDirectory;
        buildDirectory = currentDirectory.childDirectory('build');
        buildDirectory.createSync(recursive: true);

        projectUnderTest = FlutterProject.fromDirectory(currentDirectory);
        projectUnderTest.ios.xcodeWorkspace.createSync(recursive: true);
        projectUnderTest.macos.xcodeWorkspace.createSync(recursive: true);

        projectUnderTest.dartTool.createSync(recursive: true);
        projectUnderTest.android.ephemeralDirectory.createSync(recursive: true);
46

47
        projectUnderTest.ios.ephemeralDirectory.createSync(recursive: true);
48 49 50 51
        projectUnderTest.ios.generatedXcodePropertiesFile.createSync(recursive: true);
        projectUnderTest.ios.generatedEnvironmentVariableExportScript.createSync(recursive: true);
        projectUnderTest.ios.compiledDartFramework.createSync(recursive: true);

52 53 54 55 56 57 58 59 60 61 62 63
        projectUnderTest.linux.ephemeralDirectory.createSync(recursive: true);
        projectUnderTest.macos.ephemeralDirectory.createSync(recursive: true);
        projectUnderTest.windows.ephemeralDirectory.createSync(recursive: true);
      });

      testUsingContext('$CleanCommand removes build and .dart_tool and ephemeral directories, cleans Xcode', () async {
        when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
        await CleanCommand().runCommand();

        expect(buildDirectory.existsSync(), isFalse);
        expect(projectUnderTest.dartTool.existsSync(), isFalse);
        expect(projectUnderTest.android.ephemeralDirectory.existsSync(), isFalse);
64

65
        expect(projectUnderTest.ios.ephemeralDirectory.existsSync(), isFalse);
66 67 68 69
        expect(projectUnderTest.ios.generatedXcodePropertiesFile.existsSync(), isFalse);
        expect(projectUnderTest.ios.generatedEnvironmentVariableExportScript.existsSync(), isFalse);
        expect(projectUnderTest.ios.compiledDartFramework.existsSync(), isFalse);

70 71 72 73
        expect(projectUnderTest.linux.ephemeralDirectory.existsSync(), isFalse);
        expect(projectUnderTest.macos.ephemeralDirectory.existsSync(), isFalse);
        expect(projectUnderTest.windows.ephemeralDirectory.existsSync(), isFalse);

74 75 76 77 78 79 80 81 82 83 84 85
        verify(mockXcodeProjectInterpreter.cleanWorkspace(any, 'Runner', verbose: false)).called(2);
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
        Xcode: () => mockXcode,
        XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
      });

      testUsingContext('$CleanCommand cleans Xcode verbosely', () async {
        when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
        await CleanCommand(verbose: true).runCommand();
        verify(mockXcodeProjectInterpreter.cleanWorkspace(any, 'Runner', verbose: true)).called(2);
86 87 88 89 90 91
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
        Xcode: () => mockXcode,
        XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
      });
92
    });
93

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    group('Windows', () {
      MockPlatform windowsPlatform;
      setUp(() {
        windowsPlatform = MockPlatform();
      });

      testUsingContext('$CleanCommand prints a helpful error message on Windows', () async {
        when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
        when(windowsPlatform.isWindows).thenReturn(true);

        final MockFile mockFile = MockFile();
        when(mockFile.existsSync()).thenReturn(true);

        when(mockFile.deleteSync(recursive: true)).thenThrow(const FileSystemException('Deletion failed'));
        final CleanCommand command = CleanCommand();
        command.deleteFile(mockFile);
        expect(testLogger.errorText, contains('A program may still be using a file'));
        verify(mockFile.deleteSync(recursive: true)).called(1);
      }, overrides: <Type, Generator>{
        Platform: () => windowsPlatform,
        Xcode: () => mockXcode,
      });

      testUsingContext('$CleanCommand handles missing permissions;', () async {
        when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);

        final MockFile mockFile = MockFile();
        when(mockFile.existsSync()).thenThrow(const FileSystemException('OS error: Access Denied'));
        when(mockFile.path).thenReturn('foo.dart');

        final CleanCommand command = CleanCommand();
        command.deleteFile(mockFile);
        expect(testLogger.errorText, contains('Cannot clean foo.dart'));
        verifyNever(mockFile.deleteSync(recursive: true));
      }, overrides: <Type, Generator>{
        Platform: () => windowsPlatform,
        Xcode: () => mockXcode,
      });
132
    });
133
  });
134 135 136
}

class MockFile extends Mock implements File {}
137
class MockPlatform extends Mock implements Platform {}
138 139 140 141
class MockXcode extends Mock implements Xcode {}

class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {
  @override
142
  Future<XcodeProjectInfo> getInfo(String projectPath, {String projectFilename}) async {
143 144 145
    return XcodeProjectInfo(null, null, <String>['Runner']);
  }
}