blob: c25958a4b2c2483208a3d72a0b7f721081239866 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library polymer.test.build.import_inliner_test;
import 'dart:convert';
import 'package:polymer/src/build/common.dart';
import 'package:polymer/src/build/import_inliner.dart';
import 'package:unittest/compact_vm_config.dart';
import 'package:unittest/unittest.dart';
import 'common.dart';
part 'code_extractor.dart';
final phases = [[new ImportInliner(new TransformOptions())]];
void main() {
useCompactVMConfiguration();
group('rel=import', importTests);
group('rel=stylesheet', stylesheetTests);
group('script type=dart', codeExtractorTests);
group('url attributes', urlAttributeTests);
group('deep entrypoints', entryPointTests);
}
void importTests() {
testPhases('no changes', phases, {
'a|web/test.html': '<!DOCTYPE html><html></html>',
}, {
'a|web/test.html': '<!DOCTYPE html><html></html>',
'a|web/test.html._data': EMPTY_DATA,
});
testPhases('empty import', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="">' // empty href
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import">' // no href
'</head></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body></body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body></body></html>',
'a|web/test2.html._data': EMPTY_DATA,
});
testPhases('shallow, no elements', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body></body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head></html>',
'a|web/test2.html._data': EMPTY_DATA,
});
testPhases('shallow, elements, one import', phases,
{
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'</body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/test2.html._data': EMPTY_DATA,
});
testPhases('preserves order of scripts', phases,
{
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<script type="text/javascript">/*first*/</script>'
'<script src="second.js"></script>'
'<link rel="import" href="test2.html">'
'<script>/*forth*/</script>'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head><script>/*third*/</script>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/second.js': '/*second*/'
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<script type="text/javascript">/*first*/</script>'
'<script src="second.js"></script>'
'<script>/*third*/</script>'
'<polymer-element>2</polymer-element>'
'<script>/*forth*/</script>'
'</body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head><script>/*third*/</script>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/test2.html._data': EMPTY_DATA,
'a|web/second.js': '/*second*/'
});
testPhases('preserves order of scripts, extract Dart scripts', phases,
{
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<script type="text/javascript">/*first*/</script>'
'<script src="second.js"></script>'
'<link rel="import" href="test2.html">'
'<script type="application/dart">/*fifth*/</script>'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head><script>/*third*/</script>'
'<script type="application/dart">/*forth*/</script>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/second.js': '/*second*/'
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<script type="text/javascript">/*first*/</script>'
'<script src="second.js"></script>'
'<script>/*third*/</script>'
'<polymer-element>2</polymer-element>'
'</body></html>',
'a|web/test.html._data': expectedData([
'web/test.html.1.dart','web/test.html.0.dart']),
'a|web/test.html.1.dart': 'library a.web.test2_html_0;\n/*forth*/',
'a|web/test.html.0.dart': 'library a.web.test_html_0;\n/*fifth*/',
'a|web/test2.html':
'<!DOCTYPE html><html><head></head><body><script>/*third*/</script>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test2.html._data': expectedData(['web/test2.html.0.dart']),
'a|web/test2.html.0.dart': 'library a.web.test2_html_0;\n/*forth*/',
'a|web/second.js': '/*second*/'
});
final cspPhases = [[new ImportInliner(
new TransformOptions(contentSecurityPolicy: true))]];
testPhases('extract Js scripts in CSP mode', cspPhases,
{
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<script type="text/javascript">/*first*/</script>'
'<script src="second.js"></script>'
'<link rel="import" href="test2.html">'
'<script type="application/dart">/*fifth*/</script>'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head><script>/*third*/</script>'
'<script type="application/dart">/*forth*/</script>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/second.js': '/*second*/'
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<script type="text/javascript" src="test.html.0.js"></script>'
'<script src="second.js"></script>'
'<script src="test.html.2.js"></script>'
'<polymer-element>2</polymer-element>'
'</body></html>',
'a|web/test.html._data': expectedData([
'web/test.html.3.dart','web/test.html.1.dart']),
'a|web/test.html.3.dart': 'library a.web.test2_html_0;\n/*forth*/',
'a|web/test.html.1.dart': 'library a.web.test_html_0;\n/*fifth*/',
'a|web/test.html.0.js': '/*first*/',
'a|web/test.html.2.js': '/*third*/',
'a|web/test2.html':
'<!DOCTYPE html><html><head></head><body>'
'<script src="test2.html.0.js"></script>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test2.html._data': expectedData(['web/test2.html.1.dart']),
'a|web/test2.html.0.js': '/*third*/',
'a|web/test2.html.1.dart': 'library a.web.test2_html_0;\n/*forth*/',
'a|web/second.js': '/*second*/'
});
testPhases('Cleans library names generated from file paths.', phases,
{
'a|web/01_test.html':
'<!DOCTYPE html><html><head>'
'<script type="application/dart">/*1*/</script>'
'</head></html>',
'a|web/foo_02_test.html':
'<!DOCTYPE html><html><head>'
'<script type="application/dart">/*2*/</script>'
'</head></html>',
'a|web/test_03.html':
'<!DOCTYPE html><html><head>'
'<script type="application/dart">/*3*/</script>'
'</head></html>',
'a|web/*test_%foo_04!.html':
'<!DOCTYPE html><html><head>'
'<script type="application/dart">/*4*/</script>'
'</head></html>',
'a|web/%05_test.html':
'<!DOCTYPE html><html><head>'
'<script type="application/dart">/*5*/</script>'
'</head></html>',
}, {
'a|web/01_test.html.0.dart':
'library a.web._01_test_html_0;\n/*1*/', // Appends an _ if it starts with a number.
'a|web/foo_02_test.html.0.dart':
'library a.web.foo_02_test_html_0;\n/*2*/', // Allows numbers in the middle.
'a|web/test_03.html.0.dart':
'library a.web.test_03_html_0;\n/*3*/', // Allows numbers at the end.
'a|web/*test_%foo_04!.html.0.dart':
'library a.web._test__foo_04__html_0;\n/*4*/', // Replaces invalid characters with _.
'a|web/%05_test.html.0.dart':
'library a.web._05_test_html_0;\n/*5*/', // Replace invalid character followed by number.
});
testPhases('no transformation outside web/', phases,
{
'a|lib/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|lib/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
}, {
'a|lib/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|lib/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
});
testPhases('shallow, elements, many', phases,
{
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'<link rel="import" href="test3.html">'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/test3.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>3</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>3</polymer-element>'
'</body></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/test3.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>3</polymer-element></html>',
});
testPhases('deep, elements, one per file', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="assets/b/test3.html">'
'</head><body><polymer-element>2</polymer-element></html>',
'b|asset/test3.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="../../packages/c/test4.html">'
'</head><body><polymer-element>3</polymer-element></html>',
'c|lib/test4.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>4</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>4</polymer-element>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>4</polymer-element>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
'b|asset/test3.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="../../packages/c/test4.html">'
'</head><body><polymer-element>3</polymer-element></html>',
'c|lib/test4.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>4</polymer-element></html>',
});
testPhases('deep, elements, many imports', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2a.html">'
'<link rel="import" href="test2b.html">'
'</head></html>',
'a|web/test2a.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test3a.html">'
'<link rel="import" href="test3b.html">'
'</head><body><polymer-element>2a</polymer-element></body></html>',
'a|web/test2b.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test4a.html">'
'<link rel="import" href="test4b.html">'
'</head><body><polymer-element>2b</polymer-element></body></html>',
'a|web/test3a.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>3a</polymer-element></body></html>',
'a|web/test3b.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>3b</polymer-element></body></html>',
'a|web/test4a.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>4a</polymer-element></body></html>',
'a|web/test4b.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>4b</polymer-element></body></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3a</polymer-element>'
'<polymer-element>3b</polymer-element>'
'<polymer-element>2a</polymer-element>'
'<polymer-element>4a</polymer-element>'
'<polymer-element>4b</polymer-element>'
'<polymer-element>2b</polymer-element>'
'</body></html>',
'a|web/test2a.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3a</polymer-element>'
'<polymer-element>3b</polymer-element>'
'<polymer-element>2a</polymer-element>'
'</body></html>',
'a|web/test2b.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>4a</polymer-element>'
'<polymer-element>4b</polymer-element>'
'<polymer-element>2b</polymer-element>'
'</body></html>',
'a|web/test3a.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3a</polymer-element>'
'</body></html>',
'a|web/test3b.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3b</polymer-element>'
'</body></html>',
'a|web/test4a.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>4a</polymer-element>'
'</body></html>',
'a|web/test4b.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>4b</polymer-element>'
'</body></html>',
});
testPhases('imports cycle, 1-step lasso', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_2.html">'
'</head><body><polymer-element>1</polymer-element></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body><polymer-element>2</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
});
testPhases('imports cycle, 1-step lasso, scripts too', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_2.html">'
'</head><body><polymer-element>1</polymer-element>'
'<script src="s1"></script></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body><polymer-element>2</polymer-element>'
'<script src="s2"></script></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<script src="s2"></script>'
'<polymer-element>1</polymer-element>'
'<script src="s1"></script></body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<script src="s2"></script>'
'<polymer-element>1</polymer-element>'
'<script src="s1"></script></body></html>',
'a|web/test_1.html._data': EMPTY_DATA,
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element>'
'<script src="s1"></script>'
'<polymer-element>2</polymer-element>'
'<script src="s2"></script></body></html>',
'a|web/test_2.html._data': EMPTY_DATA,
});
testPhases('imports cycle, 1-step lasso, Dart scripts too', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_2.html">'
'</head><body><polymer-element>1</polymer-element>'
'<script type="application/dart" src="s1.dart">'
'</script></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body><polymer-element>2'
'<script type="application/dart" src="s2.dart"></script>'
'</polymer-element>'
'</html>',
'a|web/s1.dart': '',
'a|web/s2.dart': '',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element>'
'</body></html>',
'a|web/test.html._data': expectedData(['web/s2.dart', 'web/s1.dart']),
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element>'
'</body></html>',
'a|web/test_1.html._data': expectedData(['web/s2.dart', 'web/s1.dart']),
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element>'
'<polymer-element>2'
'</polymer-element>'
'</body></html>',
'a|web/test_2.html._data': expectedData(['web/s1.dart', 'web/s2.dart']),
});
testPhases('imports with Dart script after JS script', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body>'
'<foo>42</foo><bar-baz></bar-baz>'
'<polymer-element>1'
'<script src="s1.js"></script>'
'<script type="application/dart" src="s1.dart"></script>'
'</polymer-element>'
'FOO</body></html>',
'a|web/s1.dart': '',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<foo>42</foo><bar-baz></bar-baz>'
'<polymer-element>1'
'<script src="s1.js"></script>'
'</polymer-element>'
'FOO</body></html>',
'a|web/test.html._data': expectedData(['web/s1.dart']),
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<foo>42</foo><bar-baz></bar-baz>'
'<polymer-element>1'
'<script src="s1.js"></script>'
'</polymer-element>'
'FOO</body></html>',
'a|web/test_1.html._data': expectedData(['web/s1.dart']),
});
testPhases('imports cycle, 2-step lasso', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_2.html">'
'</head><body><polymer-element>1</polymer-element></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_3.html">'
'</head><body><polymer-element>2</polymer-element></html>',
'a|web/test_3.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body><polymer-element>3</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test_3.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>2</polymer-element>'
'<polymer-element>1</polymer-element>'
'<polymer-element>3</polymer-element></body></html>',
});
testPhases('imports cycle, self cycle', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'</head><body><polymer-element>1</polymer-element></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>1</polymer-element></body></html>',
});
testPhases('imports DAG', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_1.html">'
'<link rel="import" href="test_2.html">'
'</head></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_3.html">'
'</head><body><polymer-element>1</polymer-element></body></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test_3.html">'
'</head><body><polymer-element>2</polymer-element></body></html>',
'a|web/test_3.html':
'<!DOCTYPE html><html><head>'
'</head><body><polymer-element>3</polymer-element></body></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element>'
'<polymer-element>1</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test_1.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element>'
'<polymer-element>1</polymer-element></body></html>',
'a|web/test_2.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element>'
'<polymer-element>2</polymer-element></body></html>',
'a|web/test_3.html':
'<!DOCTYPE html><html><head>'
'</head><body>'
'<polymer-element>3</polymer-element></body></html>',
});
testLogOutput(
(options) => new ImportInliner(options),
"missing styles don't throw errors and are not inlined", {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="foo.css">'
'</head></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<link rel="stylesheet" href="foo.css">'
'</body></html>',
}, [
'warning: Failed to inline stylesheet: '
'Could not find asset a|web/foo.css. (web/test.html 0 27)',
]);
testLogOutput(
(options) => new ImportInliner(options),
"missing html imports throw errors", {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo.html">'
'</head></html>',
}, {
'a|web/test.html._buildLogs.1':
'[{'
'"level":"Error",'
'"message":"${const HtmlEscape().convert(
'Failed to inline html import: '
'Could not find asset a|web/foo.html.')}",'
'"assetId":{"package":"a","path":"web/foo.html"},'
'"span":{'
'"location":"web/test.html:1:28",'
'"text":"${const HtmlEscape().convert(
'<link rel="import" href="foo.html">')}"'
'}'
'}]',
}, [
'error: Failed to inline html import: '
'Could not find asset a|web/foo.html. (web/test.html 0 27)',
]);
}
void stylesheetTests() {
testPhases('empty stylesheet', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="">' // empty href
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet">' // no href
'</head></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="">' // empty href
'</head></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet">' // no href
'</head></html>',
'a|web/test2.html._data': EMPTY_DATA,
});
testPhases('absolute uri', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="/foo.css">'
'</head></html>',
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="http://example.com/bar.css">'
'</head></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="/foo.css">'
'</head></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="http://example.com/bar.css">'
'</head></html>',
'a|web/test2.html._data': EMPTY_DATA,
});
testPhases('shallow, inlines css', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="test2.css">'
'</head></html>',
'a|web/test2.css':
'h1 { font-size: 70px; }',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<style>h1 { font-size: 70px; }</style>'
'</body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.css':
'h1 { font-size: 70px; }',
});
testPhases('deep, inlines css', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="test2.html">'
'</head></html>',
'a|web/test2.html':
'<polymer-element>2'
'<link rel="stylesheet" href="assets/b/test3.css">'
'</polymer-element>',
'b|asset/test3.css':
'body {\n background: #eaeaea url("../../assets/b/test4.png");\n}\n'
'.foo {\n background: url("../../packages/c/test5.png");\n}',
'b|asset/test4.png': 'PNG',
'c|lib/test5.png': 'PNG',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<polymer-element>2'
'<style>'
'body {\n background: #eaeaea url(assets/b/test4.png);\n}\n'
'.foo {\n background: url(packages/c/test5.png);\n}'
'</style>'
'</polymer-element>'
'</body></html>',
'a|web/test2.html':
'<html><head></head><body>'
'<polymer-element>2'
'<style>'
'body {\n background: #eaeaea url(assets/b/test4.png);\n}\n'
'.foo {\n background: url(packages/c/test5.png);\n}'
'</style>'
'</polymer-element>'
'</body></html>',
'b|asset/test3.css':
'body {\n background: #eaeaea url("../../assets/b/test4.png");\n}\n'
'.foo {\n background: url("../../packages/c/test5.png");\n}',
'b|asset/test4.png': 'PNG',
'c|lib/test5.png': 'PNG',
});
testPhases('deep, inlines css, multiple nesting', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo/test2.html">'
'</head></html>',
'a|web/foo/test2.html':
'<link rel="import" href="bar/test3.html">'
'<polymer-element>2'
'<link rel="stylesheet" href="test.css">'
'</polymer-element>',
'a|web/foo/bar/test3.html':
'<img src="qux.png">',
'a|web/foo/test.css':
'body {\n background: #eaeaea url("test4.png");\n}\n'
'.foo {\n background: url("test5.png");\n}',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="foo/bar/qux.png">'
'<polymer-element>2'
'<style>'
'body {\n background: #eaeaea url(foo/test4.png);\n}\n'
'.foo {\n background: url(foo/test5.png);\n}'
'</style></polymer-element></body></html>',
'a|web/foo/test2.html':
'<html><head></head><body>'
'<img src="bar/qux.png">'
'<polymer-element>2'
'<style>'
'body {\n background: #eaeaea url(test4.png);\n}\n'
'.foo {\n background: url(test5.png);\n}'
'</style></polymer-element></body></html>',
'a|web/foo/bar/test3.html':
'<img src="qux.png">',
'a|web/foo/test.css':
'body {\n background: #eaeaea url("test4.png");\n}\n'
'.foo {\n background: url("test5.png");\n}',
});
testPhases('shallow, inlines css and preserves order', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<style>.first { color: black }</style>'
'<link rel="stylesheet" href="test2.css">'
'<style>.second { color: black }</style>'
'</head></html>',
'a|web/test2.css':
'h1 { font-size: 70px; }',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<style>.first { color: black }</style>'
'<style>h1 { font-size: 70px; }</style>'
'<style>.second { color: black }</style>'
'</body></html>',
'a|web/test.html._data': EMPTY_DATA,
'a|web/test2.css':
'h1 { font-size: 70px; }',
});
testPhases('inlined tags keep original attributes', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="stylesheet" href="foo.css" no-shim>'
'<link rel="stylesheet" href="bar.css" shim-shadow foo>'
'</head></html>',
'a|web/foo.css':
'h1 { font-size: 70px; }',
'a|web/bar.css':
'h2 { font-size: 35px; }',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<style no-shim="">h1 { font-size: 70px; }</style>'
'<style shim-shadow="" foo="">h2 { font-size: 35px; }</style>'
'</body></html>',
'a|web/foo.css':
'h1 { font-size: 70px; }',
'a|web/bar.css':
'h2 { font-size: 35px; }',
});
testPhases(
'can configure default stylesheet inlining',
[[new ImportInliner(new TransformOptions(
inlineStylesheets: {'default': false}))]], {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<link rel="stylesheet" href="foo.css">'
'</body></html>',
'a|web/foo.css':
'h1 { font-size: 70px; }',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<link rel="stylesheet" href="foo.css">'
'</body></html>',
});
testPhases(
'can override default stylesheet inlining',
[[new ImportInliner(new TransformOptions(
inlineStylesheets: {
'default': false,
'web/foo.css': true,
'b|lib/baz.css': true,
}))]],
{
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<link rel="stylesheet" href="bar.css">'
'<link rel="stylesheet" href="foo.css">'
'<link rel="stylesheet" href="packages/b/baz.css">'
'<link rel="stylesheet" href="packages/c/buz.css">'
'</body></html>',
'a|web/foo.css':
'h1 { font-size: 70px; }',
'a|web/bar.css':
'h1 { font-size: 35px; }',
'b|lib/baz.css':
'h1 { font-size: 20px; }',
'c|lib/buz.css':
'h1 { font-size: 10px; }',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<link rel="stylesheet" href="bar.css">'
'<style>h1 { font-size: 70px; }</style>'
'<style>h1 { font-size: 20px; }</style>'
'<link rel="stylesheet" href="packages/c/buz.css">'
'</body></html>',
});
}
void urlAttributeTests() {
testPhases('url attributes are normalized', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo/test_1.html">'
'<link rel="import" href="foo/test_2.html">'
'</head></html>',
'a|web/foo/test_1.html':
'<script src="baz.jpg"></script>',
'a|web/foo/test_2.html':
'<foo-element src="baz.jpg"></foo-element>'
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<script src="foo/baz.jpg"></script>' // normalized
'<foo-element src="baz.jpg"></foo-element>' // left alone (custom)
'</body></html>',
'a|web/foo/test_1.html':
'<script src="baz.jpg"></script>',
'a|web/foo/test_2.html':
'<foo-element src="baz.jpg"></foo-element>',
});
testPhases('paths with a binding prefix are not normalized', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo/test.html">'
'</head></html>',
'a|web/foo/test.html':
'<img src="{{bar}}">'
'<img src="[[bar]]">',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="{{bar}}">'
'<img src="[[bar]]">'
'</body></html>',
'a|web/foo/test.html':
'<img src="{{bar}}">'
'<img src="[[bar]]">',
});
testPhases('relative paths followed by bindings are normalized', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo/test.html">'
'</head></html>',
'a|web/foo/test.html':
'<img src="baz/{{bar}}">'
'<img src="./{{bar}}">',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="foo/baz/{{bar}}">'
'<img src="foo/{{bar}}">'
'</body></html>',
});
testPhases('relative paths in _* attributes are normalized', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="foo/test.html">'
'</head></html>',
'a|web/foo/test.html':
'<img _src="./{{bar}}">'
'<a _href="./{{bar}}">test</a>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img _src="foo/{{bar}}">'
'<a _href="foo/{{bar}}">test</a>'
'</body></html>',
});
testLogOutput(
(options) => new ImportInliner(options),
'warnings are given about _* attributes', {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="foo/{{bar}}">'
'<a _href="foo/bar">test</a>'
'</body></html>',
}, {}, [
'warning: When using bindings with the "src" attribute you may '
'experience errors in certain browsers. Please use the "_src" '
'attribute instead. For more information, see '
'http://goo.gl/5av8cU (web/test.html 0 40)',
'warning: The "_href" attribute is only supported when using '
'bindings. Please change to the "href" attribute. '
'(web/test.html 0 63)',
]);
testPhases('arbitrary bindings can exist in paths', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="./{{(bar[2] + baz[\'foo\']) * 14 / foobar() - 0.5}}.jpg">'
'<img src="./[[bar[2]]].jpg">'
'</body></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="{{(bar[2] + baz[\'foo\']) * 14 / foobar() - 0.5}}.jpg">'
'<img src="[[bar[2]]].jpg">'
'</body></html>',
});
testPhases('multiple bindings can exist in paths', phases, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="./{{bar[0]}}/{{baz[1]}}.{{extension}}">'
'</body></html>',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<img src="{{bar[0]}}/{{baz[1]}}.{{extension}}">'
'</body></html>',
});
}
void entryPointTests() {
testPhases('one level deep entry points normalize correctly', phases, {
'a|web/test/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="../../packages/a/foo/foo.html">'
'</head></html>',
'a|lib/foo/foo.html':
'<script rel="import" href="../../../packages/b/bar/bar.js">'
'</script>',
'b|lib/bar/bar.js':
'console.log("here");',
}, {
'a|web/test/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<script rel="import" href="../packages/b/bar/bar.js"></script>'
'</body></html>',
});
testPhases('includes in entry points normalize correctly', phases, {
'a|web/test/test.html':
'<!DOCTYPE html><html><head>'
'<script src="packages/a/foo/bar.js"></script>'
'</head></html>',
'a|lib/foo/bar.js':
'console.log("here");',
}, {
'a|web/test/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<script src="../packages/a/foo/bar.js"></script>'
'</body></html>',
});
testPhases('two level deep entry points normalize correctly', phases, {
'a|web/test/well/test.html':
'<!DOCTYPE html><html><head>'
'<link rel="import" href="../../../packages/a/foo/foo.html">'
'</head></html>',
'a|lib/foo/foo.html':
'<script rel="import" href="../../../packages/b/bar/bar.js"></script>',
'b|lib/bar/bar.js':
'console.log("here");',
}, {
'a|web/test/well/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<script rel="import" href="../../packages/b/bar/bar.js"></script>'
'</body></html>',
});
}