template_test.dart 6.9 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
import 'dart:typed_data';

7
import 'package:file/memory.dart';
8
import 'package:file_testing/file_testing.dart';
9
import 'package:flutter_tools/src/base/file_system.dart';
10 11
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/template.dart';
12 13
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
14
import 'package:flutter_tools/src/template.dart';
15
import '../src/common.dart';
16
import '../src/context.dart';
17 18

void main() {
19 20 21 22 23 24 25 26 27 28 29 30 31
  testWithoutContext('Template constructor throws ToolExit when source directory is missing', () {
    final FileExceptionHandler handler = FileExceptionHandler();
    final MemoryFileSystem fileSystem = MemoryFileSystem.test(opHandle: handler.opHandle);

    expect(() => Template(
      fileSystem.directory('doesNotExist'),
      fileSystem.currentDirectory,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      templateRenderer: FakeTemplateRenderer(),
    ), throwsToolExit());
  });

32
  testWithoutContext('Template.render throws ToolExit when FileSystem exception is raised', () {
33 34
    final FileExceptionHandler handler = FileExceptionHandler();
    final MemoryFileSystem fileSystem = MemoryFileSystem.test(opHandle: handler.opHandle);
35
    final Template template = Template(
36
      fileSystem.directory('examples')..createSync(recursive: true),
37
      fileSystem.currentDirectory,
38 39 40
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      templateRenderer: FakeTemplateRenderer(),
41
    );
42 43
    final Directory directory = fileSystem.directory('foo');
    handler.addError(directory, FileSystemOp.create, const FileSystemException());
44

45 46
    expect(() => template.render(directory, <String, Object>{}),
      throwsToolExit());
47
  });
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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
  group('template image directory', () {
    final Map<Type, Generator> overrides = <Type, Generator>{
      FileSystem: () => MemoryFileSystem.test(),
      ProcessManager: () => FakeProcessManager.any(),
    };

    testUsingContext('templateImageDirectory returns parent template directory if passed null name', () async {
      final String packageConfigPath = globals.fs.path.join(
        Cache.flutterRoot!,
        'packages',
        'flutter_tools',
        '.dart_tool',
        'package_config.json',
      );

      globals.fs.file(packageConfigPath)
        ..createSync(recursive: true)
        ..writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "flutter_template_images",
      "rootUri": "/flutter_template_images",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''');
      expect(
          (await templateImageDirectory(null, globals.fs, globals.logger)).path,
          globals.fs.path.absolute(
            'flutter_template_images',
            'templates',
          ),
      );
    }, overrides: overrides);

    testUsingContext('templateImageDirectory returns the directory containing the `name` template directory', () async {
      final String packageConfigPath = globals.fs.path.join(
        Cache.flutterRoot!,
        'packages',
        'flutter_tools',
        '.dart_tool',
        'package_config.json',
      );
      globals.fs.file(packageConfigPath)
        ..createSync(recursive: true)
        ..writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "flutter_template_images",
      "rootUri": "/flutter_template_images",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''');
      expect(
        (await templateImageDirectory('app_shared', globals.fs, globals.logger)).path,
        globals.fs.path.absolute(
          'flutter_template_images',
          'templates',
          'app_shared',
        ),
      );
    }, overrides: overrides);
  });

122 123
  group('renders template', () {
    late Directory destination;
124
    const String imageName = 'some_image.png';
125 126 127
    late File sourceImage;
    late BufferLogger logger;
    late Template template;
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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    setUp(() {
      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
      final Directory templateDir = fileSystem.directory('templates');
      final Directory imageSourceDir = fileSystem.directory('template_images');
      destination = fileSystem.directory('target');
      templateDir.childFile('$imageName.img.tmpl').createSync(recursive: true);
      sourceImage = imageSourceDir.childFile(imageName);
      sourceImage.createSync(recursive: true);
      sourceImage.writeAsStringSync("Ceci n'est pas une pipe");

      logger = BufferLogger.test();
      template = Template(
        templateDir,
        imageSourceDir,
        fileSystem: fileSystem,
        logger: logger,
        templateRenderer: FakeTemplateRenderer(),
      );
    });

    testWithoutContext('overwrites .img.tmpl files with files from the image source', () {
      expect(template.render(destination, <String, Object>{}), 1);

      final File destinationImage = destination.childFile(imageName);
      final Uint8List sourceImageBytes = sourceImage.readAsBytesSync();
      expect(destinationImage, exists);
      expect(destinationImage.readAsBytesSync(), equals(sourceImageBytes));

      expect(logger.errorText, isEmpty);
      expect(logger.statusText, contains('${destinationImage.path} (created)'));
      logger.clear();

      // Run it again to overwrite (returns 1 file updated).
      expect(template.render(destination, <String, Object>{}), 1);

      expect(destinationImage.readAsBytesSync(), equals(sourceImageBytes));
      expect(logger.errorText, isEmpty);
      expect(logger.statusText, contains('${destinationImage.path} (overwritten)'));
    });

    testWithoutContext('does not overwrite .img.tmpl files with files from the image source', () {
      expect(template.render(destination, <String, Object>{}), 1);

      final File destinationImage = destination.childFile(imageName);
      expect(destinationImage, exists);

      expect(logger.errorText, isEmpty);
      expect(logger.statusText, contains('${destinationImage.path} (created)'));
      logger.clear();

      // Run it again, do not overwrite (returns 0 files updated).
      expect(template.render(destination, <String, Object>{}, overwriteExisting: false), 0);

      expect(destinationImage, exists);
      expect(logger.errorText, isEmpty);
      expect(logger.statusText, isEmpty);
    });

    testWithoutContext('can suppress file printing', () {
      template.render(destination, <String, Object>{}, printStatusWhenWriting: false);

      final File destinationImage = destination.childFile(imageName);
      expect(destinationImage, exists);
192

193 194 195
      expect(logger.errorText, isEmpty);
      expect(logger.statusText, isEmpty);
    });
196
  });
197 198
}

199 200 201 202 203 204
class FakeTemplateRenderer extends TemplateRenderer {
  @override
  String renderString(String template, dynamic context, {bool htmlEscapeValues = false}) {
    return '';
  }
}