// Copyright (c) 2017, 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.

import 'package:code_builder/code_builder.dart';
import 'package:test/test.dart';

import '../common.dart';

void main() {
  useDartfmt();

  test('should generate a complex generated file', () {
    // Imports from an existing Dart library.
    final $App = refer('App', 'package:app/app.dart');
    final $Module = refer('Module', 'package:app/module.dart');
    final $Thing = refer('Thing', 'package:app/thing.dart');

    final clazz =
        ClassBuilder()
          ..name = 'Injector'
          ..implements.add($App)
          ..fields.add(
            Field(
              (b) =>
                  b
                    ..modifier = FieldModifier.final$
                    ..name = '_module'
                    ..type = $Module.type,
            ),
          )
          ..constructors.add(
            Constructor(
              (b) =>
                  b
                    ..requiredParameters.add(
                      Parameter(
                        (b) =>
                            b
                              ..name = '_module'
                              ..toThis = true,
                      ),
                    ),
            ),
          )
          ..methods.add(
            Method(
              (b) =>
                  b
                    ..name = 'getThing'
                    ..body =
                        $Thing.newInstance([
                          refer('_module').property('get1').call([]),
                          refer('_module').property('get2').call([]),
                        ]).code
                    ..returns = $Thing
                    ..annotations.add(refer('override')),
            ),
          );

    expect(
      clazz.build(),
      equalsDart(r'''
        class Injector implements App {
          Injector(this._module);

          final Module _module;

          @override
          Thing getThing() => Thing(_module.get1(), _module.get2(), );
        }
      '''),
    );

    expect(
      clazz.build(),
      equalsDart(r'''
        class Injector implements _i1.App {
          Injector(this._module);

          final _i2.Module _module;

          @override
          _i3.Thing getThing() => _i3.Thing(_module.get1(), _module.get2(), );
        }
      ''', DartEmitter(allocator: Allocator.simplePrefixing())),
    );
  });
}
