// Copyright (c) 2015, 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.
@TestOn('vm')
library web_components.test.build.html_import_annotation_recorder_test;

import 'package:transformer_test/utils.dart' hide testPhases;
import 'package:web_components/build/html_import_annotation_recorder.dart';
import 'package:initialize/transformer.dart';
import 'package:test/test.dart';
import 'common.dart';

testPhases(String name, Map<String, String> inputs,
    Map<String, String> expected, List<String> expectedPaths) {
  var plugin = new HtmlImportAnnotationRecorder();
  var transformer =
      new InitializeTransformer(['web/index.dart'], plugins: [plugin]);

  test(name, () {
    // Run the transformer and test the output.
    return applyTransformers([[transformer]],
        inputs: inputs,
        results: expected,
        formatter: StringFormatter.noNewlinesOrSurroundingWhitespace).then((_) {
      // Check that we recorded the right html imports.
      expect(plugin.importPaths, expectedPaths);
    });
  });
}

main() {
  testPhases('basic', {
    'a|web/index.dart': '''
        @HtmlImport('index.html')
        library index;

        import 'package:web_components/html_import_annotation.dart';
        import 'foo.dart';
        ''',
    'a|web/foo.dart': '''
        @HtmlImport(fooHtml)
        library foo;

        import 'package:initialize/initialize.dart';
        import 'package:web_components/html_import_annotation.dart';
        import 'package:bar/bar.dart';

        const String fooHtml = 'foo.html';

        @initMethod
        foo() {}
        ''',
    'bar|lib/bar.dart': '''
        @HtmlImport(barHtml)
        library bar;

        import 'package:initialize/initialize.dart';
        import 'package:web_components/html_import_annotation.dart';
        import 'src/zap.dart';

        const String barHtml = 'bar.html';

        @initMethod
        bar() {}
        ''',
    'bar|lib/src/zap.dart': '''
        @zapImport
        library bar.src.zap;

        import 'package:web_components/html_import_annotation.dart';

        const zapImport = const HtmlImport('zap.html');
        ''',
    // Mock out the Initialize package plus some initializers.
    'initialize|lib/initialize.dart': mockInitialize,
    'web_components|lib/html_import_annotation.dart': mockHtmlImportAnnotation,
  }, {
    'a|web/index.initialize.dart': '''
        import 'package:initialize/src/static_loader.dart';
        import 'package:initialize/initialize.dart';
        import 'index.dart' as i0;
        import 'package:bar/src/zap.dart' as i1;
        import 'package:bar/bar.dart' as i2;
        import 'package:web_components/html_import_annotation.dart' as i3;
        import 'package:initialize/initialize.dart' as i4;
        import 'foo.dart' as i5;

        main() {
          initializers.addAll([
            new InitEntry(i4.initMethod, i2.bar),
            new InitEntry(i4.initMethod, i5.foo),
          ]);

          return i0.main();
        }
        '''
  }, [
    'packages/bar/src/zap.html',
    'packages/bar/bar.html',
    'foo.html',
    'index.html',
  ]);
}
