macos_project_migration_test.dart 5.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/project_migrator.dart';
import 'package:flutter_tools/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
11
import 'package:flutter_tools/src/xcode_project.dart';
12
import 'package:test/fake.dart';
13 14 15 16

import '../../src/common.dart';

void main() {
17 18 19 20 21
  late TestUsage testUsage;
  late MemoryFileSystem memoryFileSystem;
  late BufferLogger testLogger;
  late FakeMacOSProject macOSProject;
  late File xcodeProjectInfoFile;
22 23

  setUp(() {
24
    testUsage = TestUsage();
25 26
    memoryFileSystem = MemoryFileSystem.test();
    xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj');
27 28 29
    testLogger = BufferLogger.test();
    macOSProject = FakeMacOSProject();
    macOSProject.xcodeProjectInfoFile = xcodeProjectInfoFile;
30 31 32 33 34
  });

  testWithoutContext('skipped if files are missing', () {
    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
35
      macOSProject,
36
      testLogger,
37
      testUsage,
38 39
    );
    expect(macosProjectMigration.migrate(), isTrue);
40
    expect(testUsage.events, isEmpty);
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

    expect(xcodeProjectInfoFile.existsSync(), isFalse);

    expect(
        testLogger.traceText,
        contains(
            'Xcode project not found, skipping framework link and embedding migration'));
    expect(testLogger.statusText, isEmpty);
  });

  testWithoutContext('skipped if nothing to upgrade', () {
    const String contents = 'Nothing to upgrade';
    xcodeProjectInfoFile.writeAsStringSync(contents);
    final DateTime projectLastModified =
        xcodeProjectInfoFile.lastModifiedSync();

    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
59
      macOSProject,
60
      testLogger,
61
      testUsage,
62 63
    );
    expect(macosProjectMigration.migrate(), isTrue);
64
    expect(testUsage.events, isEmpty);
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

    expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
    expect(xcodeProjectInfoFile.readAsStringSync(), contents);

    expect(testLogger.statusText, isEmpty);
  });

  testWithoutContext('skips migrating script with embed', () {
    const String contents = r'''
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
			''';
    xcodeProjectInfoFile.writeAsStringSync(contents);

    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
80
      macOSProject,
81
      testLogger,
82
      testUsage,
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    );
    expect(macosProjectMigration.migrate(), isTrue);
    expect(xcodeProjectInfoFile.readAsStringSync(), contents);
    expect(testLogger.statusText, isEmpty);
  });

  testWithoutContext('Xcode project is migrated', () {
    xcodeProjectInfoFile.writeAsStringSync(r'''
prefix D73912F022F37F9E000D13A0
D73912F222F3801D000D13A0 suffix
D73912EF22F37F9E000D13A0
keep this 1
  33D1A10422148B71006C7A3E spaces
33D1A10522148B93006C7A3E
			shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
keep this 2
''');

    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
103
      macOSProject,
104
      testLogger,
105
      testUsage,
106 107
    );
    expect(macosProjectMigration.migrate(), isTrue);
108
    expect(testUsage.events, isEmpty);
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

    expect(xcodeProjectInfoFile.readAsStringSync(), r'''
keep this 1
			shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
keep this 2
''');
    expect(testLogger.statusText, contains('Upgrading project.pbxproj'));
  });

  testWithoutContext('migration fails with leftover App.framework reference',
      () {
    xcodeProjectInfoFile.writeAsStringSync('''
		D73912F022F37F9bogus /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912F022F37F9bogus /* App.framework */; };
''');

    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
126
      macOSProject,
127
      testLogger,
128
      testUsage,
129 130 131 132
    );

    expect(macosProjectMigration.migrate,
        throwsToolExit(message: 'Your Xcode project requires migration'));
133 134 135
    expect(testUsage.events, contains(
      const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'),
    ));
136 137 138 139 140 141 142 143 144 145
  });

  testWithoutContext(
      'migration fails with leftover FlutterMacOS.framework reference', () {
    xcodeProjectInfoFile.writeAsStringSync('''
				33D1A10522148B93bogus /* FlutterMacOS.framework in Bundle Framework */,
''');

    final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
        RemoveMacOSFrameworkLinkAndEmbeddingMigration(
146
      macOSProject,
147
      testLogger,
148
      testUsage,
149 150 151
    );
    expect(macosProjectMigration.migrate,
        throwsToolExit(message: 'Your Xcode project requires migration'));
152 153 154
    expect(testUsage.events, contains(
      const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'),
    ));
155 156 157
  });
}

158 159
class FakeMacOSProject extends Fake implements MacOSProject {
  @override
160
  File xcodeProjectInfoFile = MemoryFileSystem.test().file('xcodeProjectInfoFile');
161
}
162 163

class FakeMacOSMigrator extends ProjectMigrator {
164
  FakeMacOSMigrator({required this.succeeds}) : super(BufferLogger.test());
165 166 167 168 169 170 171 172 173 174 175 176 177

  final bool succeeds;

  @override
  bool migrate() {
    return succeeds;
  }

  @override
  String migrateLine(String line) {
    return line;
  }
}