TEST_F(TargetParserIfaceTest, DispatchMany) {
  OptionsParser main_parser;
  Argv argv;
  argv.push_back("name")
      .push_back(json_path.string())
      .push_back("--");
  size_t iters = 16;
  for (size_t i = 0; i < iters; i++) {
    argv.push_back("--unknown" + std::to_string(i))
        .push_back(std::to_string(i));
  }
  main_parser.parse(argv.size(), argv.get(), &dummy_parser);
  ASSERT_EQ(2 * iters, dummy_parser.input.size());  
}
TEST_F(TargetParserBasicTest, ParsingError) {
  Argv argv;
  argv.push_back("--option1").push_back("1");
  std::stringstream os;
  ASSERT_NE(0, target_parser.parse(argv.get_vec(), &os));
  ASSERT_EQ("unrecognised option '--option1'\n", os.str());
}
TEST_F(TargetParserIfaceTest, DispatchEmpty) {
  OptionsParser main_parser;
  Argv argv;
  argv.push_back("name")
      .push_back(json_path.string());
  main_parser.parse(argv.size(), argv.get(), &dummy_parser);
  ASSERT_EQ(0u, dummy_parser.input.size());
}
TEST_F(TargetParserIfaceTest, NoDispatch) {
  OptionsParser main_parser;
  Argv argv;
  argv.push_back("name")
      .push_back(json_path.string());
  main_parser.parse(argv.size(), argv.get(), nullptr);
  SUCCEED();
}
TEST_F(TargetParserBasicTest, InvalidOptionType) {
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.add_string_option("option1", "hs1"));
  Argv argv;
  argv.push_back("--option1").push_back("1");
  target_parser.parse(argv.get_vec(), nullptr);
  int v;
  ASSERT_EQ(ReturnCode::INVALID_OPTION_TYPE,
            target_parser.get_int_option("option1", &v));
}
TEST_F(TargetParserBasicTest, TargetOptionInt) {
  const std::string option_name = "option1";
  const int intv = 9;
  int v;
  target_parser.add_int_option(option_name, "hs1");
  Argv argv;
  argv.push_back("--" + option_name).push_back(std::to_string(intv));
  target_parser.parse(argv.get_vec(), nullptr);
  ASSERT_EQ(ReturnCode::SUCCESS, target_parser.get_int_option(option_name, &v));
  ASSERT_EQ(intv, v);
}
TEST_F(TargetParserIfaceTest, DispatchPositional) {
  OptionsParser main_parser;
  Argv argv;
  argv.push_back("name")
      .push_back(json_path.string())
      .push_back("--")
      .push_back("unknown");
  main_parser.parse(argv.size(), argv.get(), &dummy_parser);
  ASSERT_EQ(1u, dummy_parser.input.size());
  ASSERT_EQ("unknown", dummy_parser.input.at(0));
}
TEST_F(TargetParserBasicTest, TargetOptionString) {
  const std::string option_name = "option1";
  const std::string strv = "strv";
  std::string v;
  target_parser.add_string_option(option_name, "hs1");
  Argv argv;
  argv.push_back("--" + option_name).push_back(strv);
  target_parser.parse(argv.get_vec(), nullptr);
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_string_option(option_name, &v));
  ASSERT_EQ(strv, v);
}
TEST_F(TargetParserBasicTest, TargetOptionFlag) {
  const std::string option_name_1 = "option1";
  const std::string option_name_2 = "option2";
  bool v1, v2;
  target_parser.add_flag_option(option_name_1, "hs1");
  target_parser.add_flag_option(option_name_2, "hs2");
  Argv argv;
  argv.push_back("--" + option_name_1);
  target_parser.parse(argv.get_vec(), nullptr);
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_flag_option(option_name_1, &v1));
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_flag_option(option_name_2, &v2));
  ASSERT_TRUE(v1);
  ASSERT_FALSE(v2);
}
TEST_F(TargetParserBasicTest, TargetOptionMix) {
  target_parser.add_string_option("option1", "hs1");
  target_parser.add_flag_option("option2", "hs2");
  target_parser.add_int_option("option3", "hs3");
  std::string strv;
  int intv;
  bool boolv;
  Argv argv;
  argv.push_back("--option1").push_back("1")
      .push_back("--option2")
      .push_back("--option3").push_back("1");
  target_parser.parse(argv.get_vec(), nullptr);
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_string_option("option1", &strv));
  ASSERT_EQ("1", strv);
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_flag_option("option2", &boolv));
  ASSERT_TRUE(boolv);
  ASSERT_EQ(ReturnCode::SUCCESS,
            target_parser.get_int_option("option3", &intv));
  ASSERT_EQ(1, intv);
}