asset_server_test.dart 7.13 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:flutter_tools/src/artifacts.dart';
6
import 'package:flutter_tools/src/base/file_system.dart';
7
import 'package:flutter_tools/src/base/io.dart';
8
import 'package:flutter_tools/src/build_runner/web_fs.dart';
9
import 'package:flutter_tools/src/globals.dart' as globals;
10 11 12 13 14 15
import 'package:flutter_tools/src/project.dart';
import 'package:shelf/shelf.dart';

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

16 17 18 19 20 21 22 23
const List<int> kTransparentImage = <int>[
  0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
  0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
  0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
  0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
  0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
];

24 25 26 27 28 29 30
void main() {
  Testbed testbed;
  AssetServer assetServer;

  setUp(() {
    testbed = Testbed(
      setup: () {
31
        globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
32
          .createSync(recursive: true);
33
        globals.fs.file(globals.fs.path.join('web', 'index.html'))
34 35
          ..createSync(recursive: true)
          ..writeAsStringSync('hello');
36
        globals.fs.file(globals.fs.path.join('build', 'flutter_assets', 'foo.png'))
37 38
          ..createSync(recursive: true)
          ..writeAsBytesSync(kTransparentImage);
39
        globals.fs.file(globals.fs.path.join('build', 'flutter_assets', 'bar'))
40 41
          ..createSync(recursive: true)
          ..writeAsBytesSync(<int>[1, 2, 3]);
42
        assetServer = DebugAssetServer(FlutterProject.current(), globals.fs.path.join('main'));
43 44 45 46 47 48 49 50 51 52
      }
    );
  });

  test('can serve an html file from the web directory', () => testbed.run(() async {
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/index.html')));

    expect(response.headers, <String, String>{
      'Content-Type': 'text/html',
53
      'content-length': '5',
54 55 56 57
    });
    expect(await response.readAsString(), 'hello');
  }));

58
  test('can serve a sourcemap from dart:ui', () => testbed.run(() async {
59 60
    final String flutterWebSdkPath = globals.artifacts.getArtifactPath(Artifact.flutterWebSdk);
    final File windowSourceFile = globals.fs.file(globals.fs.path.join(flutterWebSdkPath, 'lib', 'ui', 'src', 'ui', 'window.dart'))
61 62 63 64 65 66 67 68 69 70 71 72
      ..createSync(recursive: true)
      ..writeAsStringSync('test');
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/packages/build_web_compilers/lib/ui/src/ui/window.dart')));

    expect(response.headers, <String, String>{
      'content-length': windowSourceFile.lengthSync().toString(),
    });
    expect(await response.readAsString(), 'test');
  }));

  test('can serve a sourcemap from the dart:sdk', () => testbed.run(() async {
73 74
    final String dartSdkPath = globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath);
    final File listSourceFile = globals.fs.file(globals.fs.path.join(dartSdkPath, 'lib', 'core', 'list.dart'))
75 76 77 78 79 80 81 82 83 84 85 86
      ..createSync(recursive: true)
      ..writeAsStringSync('test');

    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/packages/dart-sdk/lib/core/list.dart')));

    expect(response.headers, <String, String>{
      'content-length': listSourceFile.lengthSync().toString(),
    });
    expect(await response.readAsString(), 'test');
  }));

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  test('can serve an asset with a png content type', () => testbed.run(() async {
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/assets/foo.png')));

    expect(response.headers, <String, String>{
      'Content-Type': 'image/png',
      'content-length': '64',
    });
  }));

  test('can fallback to application/octet-stream', () => testbed.run(() async {
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/assets/bar')));

    expect(response.headers, <String, String>{
      'Content-Type': 'application/octet-stream',
      'content-length': '3',
    });
  }));

107 108 109 110 111 112
  test('handles a missing html file from the web directory', () => testbed.run(() async {
    final Response response = await assetServer
        .handle(Request('GET', Uri.parse('http://localhost:8080/foobar.html')));

    expect(response.statusCode, 404);
  }));
113 114 115

  test('release asset server serves correct mime type and content length for png', () => testbed.run(() async {
    assetServer = ReleaseAssetServer();
116
    globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.png'))
117 118 119 120 121 122 123 124 125 126 127 128 129
      ..createSync(recursive: true)
      ..writeAsBytesSync(kTransparentImage);
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/assets/foo.png')));

    expect(response.headers, <String, String>{
      'Content-Type': 'image/png',
      'content-length': '64',
    });
  }));

  test('release asset server serves correct mime type and content length for JavaScript', () => testbed.run(() async {
    assetServer = ReleaseAssetServer();
130
    globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.js'))
131 132 133 134 135 136 137 138 139 140 141 142 143
      ..createSync(recursive: true)
      ..writeAsStringSync('function main() {}');
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/assets/foo.js')));

    expect(response.headers, <String, String>{
      'Content-Type': 'application/javascript',
      'content-length': '18',
    });
  }));

  test('release asset server serves correct mime type and content length for html', () => testbed.run(() async {
    assetServer = ReleaseAssetServer();
144
    globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.html'))
145 146 147 148 149 150 151 152 153 154
      ..createSync(recursive: true)
      ..writeAsStringSync('<!doctype html><html></html>');
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/assets/foo.html')));

    expect(response.headers, <String, String>{
      'Content-Type': 'text/html',
      'content-length': '28',
    });
  }));
155 156 157

  test('release asset server serves content from flutter root', () => testbed.run(() async {
    assetServer = ReleaseAssetServer();
158
    globals.fs.file(globals.fs.path.join('flutter', 'bar.dart'))
159 160 161 162 163 164 165 166 167 168
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() { }');
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/flutter/bar.dart')));

    expect(response.statusCode, HttpStatus.ok);
  }));

  test('release asset server serves content from project directory', () => testbed.run(() async {
    assetServer = ReleaseAssetServer();
169
    globals.fs.file(globals.fs.path.join('lib', 'bar.dart'))
170 171 172 173 174 175 176
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() { }');
    final Response response = await assetServer
      .handle(Request('GET', Uri.parse('http://localhost:8080/bar.dart')));

    expect(response.statusCode, HttpStatus.ok);
  }));
177
}