// 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.

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

void main() {
  test('allowTrailingOptions defaults to false', () {
    var parser = new ArgParser();
    expect(parser.allowTrailingOptions, isFalse);
  });

  group('when trailing options are allowed', () {
    var parser;
    setUp(() {
      parser = new ArgParser(allowTrailingOptions: true);
    });

    void expectThrows(List<String> args) => expect(
        () => parser.parse(args), throwsFormatException,
        reason: "with allowTrailingOptions: true");

    test('collects non-options in rest', () {
      parser.addFlag('flag');
      parser.addOption('opt', abbr: 'o');
      var results = parser.parse(['a', '--flag', 'b', '-o', 'value', 'c']);
      expect(results['flag'], isTrue);
      expect(results['opt'], equals('value'));
      expect(results.rest, equals(['a', 'b', 'c']));
    });

    test('stops parsing options at "--"', () {
      parser.addFlag('flag');
      parser.addOption('opt', abbr: 'o');
      var results = parser.parse(['a', '--flag', '--', '-ovalue', 'c']);
      expect(results['flag'], isTrue);
      expect(results.rest, equals(['a', '-ovalue', 'c']));
    });

    test('only consumes first "--"', () {
      parser.addFlag('flag', abbr: 'f');
      parser.addOption('opt', abbr: 'o');
      var results = parser.parse(['a', '--', 'b', '--', 'c']);
      expect(results.rest, equals(['a', 'b', '--', 'c']));
    });

    test('parses a trailing flag', () {
      parser.addFlag('flag');
      var results = parser.parse(['arg', '--flag']);

      expect(results['flag'], isTrue);
      expect(results.rest, equals(['arg']));
    });

    test('throws on a trailing option missing its value', () {
      parser.addOption('opt');
      expectThrows(['arg', '--opt']);
    });

    test('parses a trailing option', () {
      parser.addOption('opt');
      var results = parser.parse(['arg', '--opt', 'v']);
      expect(results['opt'], equals('v'));
      expect(results.rest, equals(['arg']));
    });

    test('throws on a trailing unknown flag', () {
      expectThrows(['arg', '--xflag']);
    });

    test('throws on a trailing unknown option and value', () {
      expectThrows(['arg', '--xopt', 'v']);
    });

    test('throws on a command', () {
      parser.addCommand('com');
      expectThrows(['arg', 'com']);
    });
  });

  test("uses the innermost command's trailing options behavior", () {
    var parser = new ArgParser(allowTrailingOptions: true);
    parser.addFlag('flag', abbr: 'f');
    var command =
        parser.addCommand('cmd', new ArgParser(allowTrailingOptions: false));
    command.addFlag('verbose', abbr: 'v');

    var results = parser.parse(['a', '-f', 'b']);
    expect(results['flag'], isTrue);
    expect(results.rest, equals(['a', 'b']));

    results = parser.parse(['cmd', '-f', 'a', '-v', '--unknown']);
    expect(results['flag'], isTrue); // Not trailing.
    expect(results.command['verbose'], isFalse);
    expect(results.command.rest, equals(['a', '-v', '--unknown']));
  });
}
