// Copyright 2013 The Flutter Authors. 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:pigeon/ast.dart';
import 'package:pigeon/generator_tools.dart';
import 'package:pigeon/objc_generator.dart';
import 'package:pigeon/pigeon_lib.dart';
import 'package:test/test.dart';

void main() {
  test('gen one class header', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(code, matches('@property.*NSString.*field1'));
  });

  test('gen one class source', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('#import "foo.h"'));
    expect(code, contains('@implementation Foobar'));
  });

  test('gen one enum header', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[], enums: <Enum>[
      Enum(
        name: 'Enum1',
        members: <EnumMember>[
          EnumMember(name: 'one'),
          EnumMember(name: 'two'),
        ],
      )
    ]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('typedef NS_ENUM(NSUInteger, Enum1) {'));
    expect(code, contains('  Enum1One = 0,'));
    expect(code, contains('  Enum1Two = 1,'));
  });

  test('gen one enum header with prefix', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[], enums: <Enum>[
      Enum(
        name: 'Enum1',
        members: <EnumMember>[
          EnumMember(name: 'one'),
          EnumMember(name: 'two'),
        ],
      )
    ]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(prefix: 'PREFIX'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('typedef NS_ENUM(NSUInteger, PREFIXEnum1) {'));
    expect(code, contains('  PREFIXEnum1One = 0,'));
    expect(code, contains('  PREFIXEnum1Two = 1,'));
  });

  test('gen one class source with enum', () {
    final Root root = Root(
      apis: <Api>[],
      classes: <Class>[
        Class(
          name: 'Foobar',
          fields: <NamedType>[
            NamedType(
                type:
                    const TypeDeclaration(baseName: 'String', isNullable: true),
                name: 'field1'),
            NamedType(
                type:
                    const TypeDeclaration(baseName: 'Enum1', isNullable: true),
                name: 'enum1'),
          ],
        ),
      ],
      enums: <Enum>[
        Enum(
          name: 'Enum1',
          members: <EnumMember>[
            EnumMember(name: 'one'),
            EnumMember(name: 'two'),
          ],
        )
      ],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('#import "foo.h"'));
    expect(code, contains('@implementation Foobar'));
    expect(
        code,
        contains(
            'pigeonResult.enum1 = [GetNullableObjectAtIndex(list, 1) integerValue];'));
  });

  test('primitive enum host', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Bar', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'bar',
            returnType: const TypeDeclaration.voidDeclaration(),
            arguments: <NamedType>[
              NamedType(
                  name: 'foo',
                  type:
                      const TypeDeclaration(baseName: 'Foo', isNullable: false))
            ])
      ])
    ], classes: <Class>[], enums: <Enum>[
      Enum(name: 'Foo', members: <EnumMember>[
        EnumMember(name: 'one'),
        EnumMember(name: 'two'),
      ])
    ]);
    final StringBuffer sink = StringBuffer();
    const ObjcOptions options =
        ObjcOptions(headerIncludePath: 'foo.h', prefix: 'AC');
    {
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions: options,
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('typedef NS_ENUM(NSUInteger, ACFoo)'));
      expect(code, contains(':(ACFoo)foo error:'));
    }
    {
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions: options,
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              'ACFoo arg_foo = [GetNullableObjectAtIndex(args, 0) integerValue];'));
    }
  });

  test('validate nullable primitive enum', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Bar', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'bar',
            returnType: const TypeDeclaration.voidDeclaration(),
            arguments: <NamedType>[
              NamedType(
                  name: 'foo',
                  type:
                      const TypeDeclaration(baseName: 'Foo', isNullable: true))
            ])
      ])
    ], classes: <Class>[], enums: <Enum>[
      Enum(name: 'Foo', members: <EnumMember>[
        EnumMember(name: 'one'),
        EnumMember(name: 'two'),
      ])
    ]);
    const ObjcOptions options = ObjcOptions(headerIncludePath: 'foo.h');
    final List<Error> errors = validateObjc(options, root);
    expect(errors.length, 1);
    expect(errors[0].message, contains('Nullable enum'));
  });

  test('gen one class header with enum', () {
    final Root root = Root(
      apis: <Api>[],
      classes: <Class>[
        Class(
          name: 'Foobar',
          fields: <NamedType>[
            NamedType(
                type:
                    const TypeDeclaration(baseName: 'String', isNullable: true),
                name: 'field1'),
            NamedType(
                type:
                    const TypeDeclaration(baseName: 'Enum1', isNullable: true),
                name: 'enum1'),
          ],
        ),
      ],
      enums: <Enum>[
        Enum(
          name: 'Enum1',
          members: <EnumMember>[
            EnumMember(name: 'one'),
            EnumMember(name: 'two'),
          ],
        )
      ],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@property(nonatomic, assign) Enum1 enum1'));
  });

  test('gen one api header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                      baseName: 'Input', isNullable: false),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Input'));
    expect(code, contains('@interface Output'));
    expect(code, contains('@protocol Api'));
    expect(code, contains('/// @return `nil` only when `error != nil`.'));
    expect(code, matches('nullable Output.*doSomething.*Input.*FlutterError'));
    expect(code, matches('ApiSetup.*<Api>.*_Nullable'));
  });

  test('gen one api source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('#import "foo.h"'));
    expect(code, contains('@implementation Input'));
    expect(code, contains('@implementation Output'));
    expect(code, contains('ApiSetup('));
    expect(
        code,
        contains(
            'NSCAssert([api respondsToSelector:@selector(doSomething:error:)'));
  });

  test('all the simple datatypes header', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'bool', isNullable: true),
            name: 'aBool'),
        NamedType(
            type: const TypeDeclaration(baseName: 'int', isNullable: true),
            name: 'aInt'),
        NamedType(
            type: const TypeDeclaration(baseName: 'double', isNullable: true),
            name: 'aDouble'),
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'aString'),
        NamedType(
            type:
                const TypeDeclaration(baseName: 'Uint8List', isNullable: true),
            name: 'aUint8List'),
        NamedType(
            type:
                const TypeDeclaration(baseName: 'Int32List', isNullable: true),
            name: 'aInt32List'),
        NamedType(
            type:
                const TypeDeclaration(baseName: 'Int64List', isNullable: true),
            name: 'aInt64List'),
        NamedType(
            type: const TypeDeclaration(
                baseName: 'Float64List', isNullable: true),
            name: 'aFloat64List'),
      ]),
    ], enums: <Enum>[]);

    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(code, contains('@class FlutterStandardTypedData;'));
    expect(code, matches('@property.*strong.*NSNumber.*aBool'));
    expect(code, matches('@property.*strong.*NSNumber.*aInt'));
    expect(code, matches('@property.*strong.*NSNumber.*aDouble'));
    expect(code, matches('@property.*copy.*NSString.*aString'));
    expect(code,
        matches('@property.*strong.*FlutterStandardTypedData.*aUint8List'));
    expect(code,
        matches('@property.*strong.*FlutterStandardTypedData.*aInt32List'));
    expect(code,
        matches('@property.*strong.*FlutterStandardTypedData.*Int64List'));
    expect(code,
        matches('@property.*strong.*FlutterStandardTypedData.*Float64List'));
  });

  test('bool source', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'bool', isNullable: true),
            name: 'aBool'),
      ]),
    ], enums: <Enum>[]);

    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@implementation Foobar'));
    expect(code,
        contains('pigeonResult.aBool = GetNullableObjectAtIndex(list, 0);'));
  });

  test('nested class header', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Nested', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'Input', isNullable: true),
            name: 'nested')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code,
        contains('@property(nonatomic, strong, nullable) Input * nested;'));
  });

  test('nested class source', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Nested', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'Input', isNullable: true),
            name: 'nested')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            'pigeonResult.nested = [Input nullableFromList:(GetNullableObjectAtIndex(list, 0))];'));
    expect(
        code, contains('self.nested ? [self.nested toList] : [NSNull null]'));
  });

  test('prefix class header', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface ABCFoobar'));
  });

  test('prefix class source', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@implementation ABCFoobar'));
  });

  test('prefix nested class header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Nested', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Nested', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'Input', isNullable: true),
            name: 'nested')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, matches('property.*ABCInput'));
    expect(code, matches('ABCNested.*doSomething.*ABCInput'));
    expect(code, contains('@protocol ABCApi'));
  });

  test('prefix nested class source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Nested', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Nested', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'Input', isNullable: true),
            name: 'nested')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('ABCInput fromList'));
    expect(code, matches(r'ABCInput.*=.*args.*0.*\;'));
    expect(code, contains('void ABCApiSetup('));
  });

  test('gen flutter api header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Api : NSObject'));
    expect(
        code,
        contains(
            'initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;'));
    expect(code, matches('void.*doSomething.*Input.*Output'));
  });

  test('gen flutter api source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@implementation Api'));
    expect(code, matches('void.*doSomething.*Input.*Output.*{'));
  });

  test('gen host void header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType: const TypeDeclaration.voidDeclaration())
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('(void)doSomething:'));
  });

  test('gen host void source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType: const TypeDeclaration.voidDeclaration())
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, isNot(matches('=.*doSomething')));
    expect(code, matches('[.*doSomething:.*]'));
    expect(code, contains('callback(wrapResult(nil, error))'));
  });

  test('gen flutter void return header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType: const TypeDeclaration.voidDeclaration())
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('completion:(void (^)(NSError *_Nullable))'));
  });

  test('gen flutter void return source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType: const TypeDeclaration.voidDeclaration())
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('completion:(void (^)(NSError *_Nullable))'));
    expect(code, contains('completion(nil)'));
  });

  test('gen host void arg header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, matches('ABCOutput.*doSomethingWithError:[(]FlutterError'));
  });

  test('gen host void arg source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, matches('output.*=.*api doSomethingWithError:&error'));
  });

  test('gen flutter void arg header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingWithCompletion:(void (^)(ABCOutput *_Nullable, NSError *_Nullable))completion'));
  });

  test('gen flutter void arg source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false))
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingWithCompletion:(void (^)(ABCOutput *_Nullable, NSError *_Nullable))completion'));
    expect(code, contains('channel sendMessage:nil'));
  });

  test('gen list', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'List', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(code, matches('@property.*NSArray.*field1'));
  });

  test('gen map', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'Map', isNullable: true),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(code, matches('@property.*NSDictionary.*field1'));
  });

  test('gen map field with object', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(
                baseName: 'Map',
                isNullable: true,
                typeArguments: <TypeDeclaration>[
                  TypeDeclaration(baseName: 'String', isNullable: true),
                  TypeDeclaration(baseName: 'Object', isNullable: true),
                ]),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(
        code,
        contains(
            '@property(nonatomic, strong, nullable) NSDictionary<NSString *, id> *'));
  });

  test('gen map argument with object', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doit',
            returnType: const TypeDeclaration.voidDeclaration(),
            arguments: <NamedType>[
              NamedType(
                  name: 'foo',
                  type: const TypeDeclaration(
                      baseName: 'Map',
                      isNullable: false,
                      typeArguments: <TypeDeclaration>[
                        TypeDeclaration(baseName: 'String', isNullable: true),
                        TypeDeclaration(baseName: 'Object', isNullable: true),
                      ]))
            ]),
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('(NSDictionary<NSString *, id> *)foo'));
  });

  test('async void (input) HostApi header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: 'input')
            ],
            returnType: const TypeDeclaration.voidDeclaration(),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingInput:(ABCInput *)input completion:(void (^)(FlutterError *_Nullable))completion'));
  });

  test('async output(input) HostApi header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: 'input')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingInput:(ABCInput *)input completion:(void (^)(ABCOutput *_Nullable, FlutterError *_Nullable))completion'));
  });

  test('async output(void) HostApi header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingWithCompletion:(void (^)(ABCOutput *_Nullable, FlutterError *_Nullable))completion'));
  });

  test('async void (void) HostApi header', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType: const TypeDeclaration.voidDeclaration(),
            isAsynchronous: true)
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '(void)doSomethingWithCompletion:(void (^)(FlutterError *_Nullable))completion'));
  });

  test('async output(input) HostApi source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: '')
            ],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '[api doSomething:arg0 completion:^(ABCOutput *_Nullable output, FlutterError *_Nullable error) {'));
  });

  test('async void (input) HostApi source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[
              NamedType(
                  type: const TypeDeclaration(
                    baseName: 'Input',
                    isNullable: false,
                  ),
                  name: 'foo')
            ],
            returnType: const TypeDeclaration.voidDeclaration(),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '[api doSomethingFoo:arg_foo completion:^(FlutterError *_Nullable error) {'));
  });

  test('async void (void) HostApi source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType: const TypeDeclaration.voidDeclaration(),
            isAsynchronous: true)
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '[api doSomethingWithCompletion:^(FlutterError *_Nullable error) {'));
  });

  test('async output(void) HostApi source', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
            name: 'doSomething',
            arguments: <NamedType>[],
            returnType:
                const TypeDeclaration(baseName: 'Output', isNullable: false),
            isAsynchronous: true)
      ])
    ], classes: <Class>[
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: true),
            name: 'output')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            '[api doSomethingWithCompletion:^(ABCOutput *_Nullable output, FlutterError *_Nullable error) {'));
  });

  Iterable<String> makeIterable(String string) sync* {
    yield string;
  }

  test('source copyright', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: ObjcOptions(
          headerIncludePath: 'foo.h',
          prefix: 'ABC',
          copyrightHeader: makeIterable('hello world')),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, startsWith('// hello world'));
  });

  test('header copyright', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: ObjcOptions(
          headerIncludePath: 'foo.h',
          prefix: 'ABC',
          copyrightHeader: makeIterable('hello world')),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, startsWith('// hello world'));
  });

  test('field generics', () {
    final Class klass = Class(
      name: 'Foobar',
      fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(
                baseName: 'List',
                isNullable: true,
                typeArguments: <TypeDeclaration>[
                  TypeDeclaration(baseName: 'int', isNullable: true)
                ]),
            name: 'field1'),
      ],
    );
    final Root root = Root(
      apis: <Api>[],
      classes: <Class>[klass],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions:
          const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('NSArray<NSNumber *> * field1'));
  });

  test('host generics argument', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                    type: const TypeDeclaration(
                        baseName: 'List',
                        isNullable: false,
                        typeArguments: <TypeDeclaration>[
                          TypeDeclaration(baseName: 'int', isNullable: true)
                        ]),
                    name: 'arg')
              ])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitArg:(NSArray<NSNumber *> *)arg'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              'NSArray<NSNumber *> *arg_arg = GetNullableObjectAtIndex(args, 0)'));
    }
  });

  test('flutter generics argument', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                    type: const TypeDeclaration(
                        baseName: 'List',
                        isNullable: false,
                        typeArguments: <TypeDeclaration>[
                          TypeDeclaration(baseName: 'int', isNullable: true)
                        ]),
                    name: 'arg')
              ])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitArg:(NSArray<NSNumber *> *)arg'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitArg:(NSArray<NSNumber *> *)arg'));
    }
  });

  test('host nested generic argument', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                    type: const TypeDeclaration(
                        baseName: 'List',
                        isNullable: false,
                        typeArguments: <TypeDeclaration>[
                          TypeDeclaration(
                              baseName: 'List',
                              isNullable: true,
                              typeArguments: <TypeDeclaration>[
                                TypeDeclaration(
                                    baseName: 'bool', isNullable: true)
                              ]),
                        ]),
                    name: 'arg')
              ])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitArg:(NSArray<NSArray<NSNumber *> *> *)arg'));
    }
  });

  test('host generics return', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                  baseName: 'List',
                  isNullable: false,
                  typeArguments: <TypeDeclaration>[
                    TypeDeclaration(baseName: 'int', isNullable: true)
                  ]),
              arguments: <NamedType>[])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code, contains('- (nullable NSArray<NSNumber *> *)doitWithError:'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('NSArray<NSNumber *> *output ='));
    }
  });

  test('flutter generics return', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                  baseName: 'List',
                  isNullable: false,
                  typeArguments: <TypeDeclaration>[
                    TypeDeclaration(baseName: 'int', isNullable: true)
                  ]),
              arguments: <NamedType>[])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code, contains('doitWithCompletion:(void (^)(NSArray<NSNumber *> *'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code, contains('doitWithCompletion:(void (^)(NSArray<NSNumber *> *'));
    }
  });

  test('host multiple args', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
          name: 'add',
          arguments: <NamedType>[
            NamedType(
                name: 'x',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
            NamedType(
                name: 'y',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
          ],
          returnType: const TypeDeclaration(baseName: 'int', isNullable: false),
        )
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              '- (nullable NSNumber *)addX:(NSNumber *)x y:(NSNumber *)y error:(FlutterError *_Nullable *_Nonnull)error;'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('NSArray *args = message;'));
      expect(code,
          contains('NSNumber *arg_x = GetNullableObjectAtIndex(args, 0);'));
      expect(code,
          contains('NSNumber *arg_y = GetNullableObjectAtIndex(args, 1);'));
      expect(code,
          contains('NSNumber *output = [api addX:arg_x y:arg_y error:&error]'));
    }
  });

  test('host multiple args async', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
        Method(
          name: 'add',
          arguments: <NamedType>[
            NamedType(
                name: 'x',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
            NamedType(
                name: 'y',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
          ],
          returnType: const TypeDeclaration(baseName: 'int', isNullable: false),
          isAsynchronous: true,
        )
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              '- (void)addX:(NSNumber *)x y:(NSNumber *)y completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion;'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('NSArray *args = message;'));
      expect(code,
          contains('NSNumber *arg_x = GetNullableObjectAtIndex(args, 0);'));
      expect(code,
          contains('NSNumber *arg_y = GetNullableObjectAtIndex(args, 1);'));
      expect(code, contains('[api addX:arg_x y:arg_y completion:'));
    }
  });

  test('flutter multiple args', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
          name: 'add',
          arguments: <NamedType>[
            NamedType(
                name: 'x',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
            NamedType(
                name: 'y',
                type:
                    const TypeDeclaration(isNullable: false, baseName: 'int')),
          ],
          returnType: const TypeDeclaration(baseName: 'int', isNullable: false),
        )
      ])
    ], classes: <Class>[], enums: <Enum>[]);
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              '- (void)addX:(NSNumber *)x y:(NSNumber *)y completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(
          code,
          contains(
              '- (void)addX:(NSNumber *)arg_x y:(NSNumber *)arg_y completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {'));
      expect(
          code,
          contains(
              '[channel sendMessage:@[arg_x ?: [NSNull null], arg_y ?: [NSNull null]] reply:'));
    }
  });

  Root getDivideRoot(ApiLocation location) => Root(
        apis: <Api>[
          Api(name: 'Api', location: location, methods: <Method>[
            Method(
                name: 'divide',
                objcSelector: 'divideValue:by:',
                arguments: <NamedType>[
                  NamedType(
                    type: const TypeDeclaration(
                        baseName: 'int', isNullable: false),
                    name: 'x',
                  ),
                  NamedType(
                    type: const TypeDeclaration(
                        baseName: 'int', isNullable: false),
                    name: 'y',
                  ),
                ],
                returnType: const TypeDeclaration(
                    baseName: 'double', isNullable: false))
          ])
        ],
        classes: <Class>[],
        enums: <Enum>[],
      );

  test('host custom objc selector', () {
    final Root divideRoot = getDivideRoot(ApiLocation.host);
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, divideRoot, sink);
      final String code = sink.toString();
      expect(code, matches('divideValue:.*by:.*error.*;'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, divideRoot, sink);
      final String code = sink.toString();
      expect(code, matches('divideValue:.*by:.*error.*;'));
    }
  });

  test('flutter custom objc selector', () {
    final Root divideRoot = getDivideRoot(ApiLocation.flutter);
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, divideRoot, sink);
      final String code = sink.toString();
      expect(code, matches('divideValue:.*by:.*completion.*;'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions:
            const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'),
      );
      generator.generate(generatorOptions, divideRoot, sink);
      final String code = sink.toString();
      expect(code, matches('divideValue:.*by:.*completion.*{'));
    }
  });

  test('test non null field', () {
    final Root root = Root(apis: <Api>[], classes: <Class>[
      Class(name: 'Foobar', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(baseName: 'String', isNullable: false),
            name: 'field1')
      ]),
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains('@interface Foobar'));
    expect(code, contains('@property(nonatomic, copy) NSString * field1'));
  });

  test('return nullable flutter header', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                baseName: 'int',
                isNullable: true,
              ),
              arguments: <NamedType>[])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        matches(
            r'doitWithCompletion.*void.*NSNumber \*_Nullable.*NSError.*completion;'));
  });

  test('return nullable flutter source', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                baseName: 'int',
                isNullable: true,
              ),
              arguments: <NamedType>[])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, matches(r'doitWithCompletion.*NSNumber \*_Nullable'));
  });

  test('return nullable host header', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                baseName: 'int',
                isNullable: true,
              ),
              arguments: <NamedType>[])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, matches(r'nullable NSNumber.*doitWithError'));
  });

  test('nullable argument host', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                    name: 'foo',
                    type: const TypeDeclaration(
                      baseName: 'int',
                      isNullable: true,
                    )),
              ])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions: const ObjcOptions(),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitFoo:(nullable NSNumber *)foo'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions: const ObjcOptions(),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code,
          contains('NSNumber *arg_foo = GetNullableObjectAtIndex(args, 0);'));
    }
  });

  test('nullable argument flutter', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                    name: 'foo',
                    type: const TypeDeclaration(
                      baseName: 'int',
                      isNullable: true,
                    )),
              ])
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.header,
        languageOptions: const ObjcOptions(),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('doitFoo:(nullable NSNumber *)foo'));
    }
    {
      final StringBuffer sink = StringBuffer();
      const ObjcGenerator generator = ObjcGenerator();
      final OutputFileOptions<ObjcOptions> generatorOptions =
          OutputFileOptions<ObjcOptions>(
        fileType: FileType.source,
        languageOptions: const ObjcOptions(),
      );
      generator.generate(generatorOptions, root, sink);
      final String code = sink.toString();
      expect(code, contains('- (void)doitFoo:(nullable NSNumber *)arg_foo'));
    }
  });

  test('background platform channel', () {
    final Root root = Root(
      apis: <Api>[
        Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
          Method(
              name: 'doit',
              returnType: const TypeDeclaration(
                baseName: 'int',
                isNullable: true,
              ),
              arguments: <NamedType>[],
              taskQueueType: TaskQueueType.serialBackgroundThread)
        ])
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(
        code,
        contains(
            'NSObject<FlutterTaskQueue> *taskQueue = [binaryMessenger makeBackgroundTaskQueue];'));
    expect(code, contains('taskQueue:taskQueue'));
  });

  test('transfers documentation comments', () {
    final List<String> comments = <String>[
      ' api comment',
      ' api method comment',
      ' class comment',
      ' class field comment',
      ' enum comment',
      ' enum member comment',
    ];
    int count = 0;

    final List<String> unspacedComments = <String>['////////'];
    int unspacedCount = 0;

    final Root root = Root(
      apis: <Api>[
        Api(
          name: 'api',
          location: ApiLocation.flutter,
          documentationComments: <String>[comments[count++]],
          methods: <Method>[
            Method(
              name: 'method',
              returnType: const TypeDeclaration.voidDeclaration(),
              documentationComments: <String>[comments[count++]],
              arguments: <NamedType>[
                NamedType(
                  name: 'field',
                  type: const TypeDeclaration(
                    baseName: 'int',
                    isNullable: true,
                  ),
                ),
              ],
            )
          ],
        )
      ],
      classes: <Class>[
        Class(
          name: 'class',
          documentationComments: <String>[comments[count++]],
          fields: <NamedType>[
            NamedType(
              documentationComments: <String>[comments[count++]],
              type: const TypeDeclaration(
                  baseName: 'Map',
                  isNullable: true,
                  typeArguments: <TypeDeclaration>[
                    TypeDeclaration(baseName: 'String', isNullable: true),
                    TypeDeclaration(baseName: 'int', isNullable: true),
                  ]),
              name: 'field1',
            ),
          ],
        ),
      ],
      enums: <Enum>[
        Enum(
          name: 'enum',
          documentationComments: <String>[
            comments[count++],
            unspacedComments[unspacedCount++]
          ],
          members: <EnumMember>[
            EnumMember(
              name: 'one',
              documentationComments: <String>[comments[count++]],
            ),
            EnumMember(name: 'two'),
          ],
        ),
      ],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.header,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    for (final String comment in comments) {
      expect(code, contains('///$comment'));
    }
    expect(code, contains('/// ///'));
  });

  test('doesnt create codecs if no custom datatypes', () {
    final Root root = Root(
      apis: <Api>[
        Api(
          name: 'Api',
          location: ApiLocation.flutter,
          methods: <Method>[
            Method(
              name: 'method',
              returnType: const TypeDeclaration.voidDeclaration(),
              arguments: <NamedType>[
                NamedType(
                  name: 'field',
                  type: const TypeDeclaration(
                    baseName: 'int',
                    isNullable: true,
                  ),
                ),
              ],
            )
          ],
        )
      ],
      classes: <Class>[],
      enums: <Enum>[],
    );
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, isNot(contains(' : FlutterStandardReader')));
  });

  test('creates custom codecs if custom datatypes present', () {
    final Root root = Root(apis: <Api>[
      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
        Method(
          name: 'doSomething',
          arguments: <NamedType>[
            NamedType(
                type: const TypeDeclaration(
                  baseName: 'Input',
                  isNullable: false,
                ),
                name: '')
          ],
          returnType:
              const TypeDeclaration(baseName: 'Output', isNullable: false),
          isAsynchronous: true,
        )
      ])
    ], classes: <Class>[
      Class(name: 'Input', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(
              baseName: 'String',
              isNullable: true,
            ),
            name: 'input')
      ]),
      Class(name: 'Output', fields: <NamedType>[
        NamedType(
            type: const TypeDeclaration(
              baseName: 'String',
              isNullable: true,
            ),
            name: 'output')
      ])
    ], enums: <Enum>[]);
    final StringBuffer sink = StringBuffer();
    const ObjcGenerator generator = ObjcGenerator();
    final OutputFileOptions<ObjcOptions> generatorOptions =
        OutputFileOptions<ObjcOptions>(
      fileType: FileType.source,
      languageOptions: const ObjcOptions(),
    );
    generator.generate(generatorOptions, root, sink);
    final String code = sink.toString();
    expect(code, contains(' : FlutterStandardReader'));
  });
}
