File: TestProgramOptions.cpp

package info (click to toggle)
ecflow 5.15.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 51,868 kB
  • sloc: cpp: 269,341; python: 22,756; sh: 3,609; perl: 770; xml: 333; f90: 204; ansic: 141; makefile: 70
file content (153 lines) | stat: -rw-r--r-- 6,228 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright 2009- ECMWF.
 *
 * This software is licensed under the terms of the Apache Licence version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation
 * nor does it submit to any jurisdiction.
 */

#include <iostream>
#include <string>

#include <boost/program_options.hpp>
#include <boost/test/unit_test.hpp>

#include "ecflow/test/scaffold/Naming.hpp"

using namespace std;
namespace po = boost::program_options;

BOOST_AUTO_TEST_SUITE(U_Base)

BOOST_AUTO_TEST_SUITE(T_ProgramOptions)

BOOST_AUTO_TEST_CASE(test_program_options_implicit_value) {
    ECF_NAME_THIS_TEST();

    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()("help", "produce help message")(
        "arg1", po::value<string>()->implicit_value(string("")), "optional arg1 description");

    {
        char* argv[] = {const_cast<char*>("test_program_options_implicit_value"),
                        const_cast<char*>("--help"),
                        const_cast<char*>("--arg1")};

        po::variables_map vm;
        po::store(po::parse_command_line(3, argv, desc), vm); // populate variable map
        po::notify(vm);                                       // raise any errors

        BOOST_CHECK_MESSAGE(vm.count("help"), "Expected help");
        BOOST_CHECK_MESSAGE(vm.count("arg1"), "Expected arg1");
        BOOST_CHECK_MESSAGE(vm["arg1"].as<string>() == "", "Expected arg1 to be empty");
    }
    //   {
    //      // This test fails on boost 1.59, can't cope --arg1 10, only --arg1=10 *******
    //      // See: ECFLOW-509 and https://svn.boost.org/trac/boost/ticket/11893
    //      char* argv[] = {
    //            const_cast<char*>("test_program_options_implicit_value"),
    //            const_cast<char*>("--arg1"),
    //            const_cast<char*>("10")
    //      };
    //
    //      po::variables_map vm;
    ////      po::store(po::parse_command_line(3, argv, desc,
    ////                        po::command_line_style::unix_style ^ po::command_line_style::allow_short ^
    ////                        po::command_line_style::long_allow_adjacent |
    ////                        po::command_line_style::short_allow_adjacent |
    ////                        po::command_line_style::allow_long_disguise
    ////                ), vm);
    //
    //      po::store(po::command_line_parser(3,argv).options(desc).style(
    //                       po::command_line_style::long_allow_next |
    //                       po::command_line_style::allow_long_disguise |
    //                       po::command_line_style::long_allow_adjacent).run(),
    //                vm);
    //      po::notify(vm);
    //
    //      BOOST_CHECK_MESSAGE(vm.count("arg1"), "Expected arg1");
    //      BOOST_CHECK_MESSAGE(vm["arg1"].as<string>() == "10", "Expected arg1 with value of 10 but found '" <<
    //      vm["arg1"].as<string>() << "'");
    //   }

    {
        char* argv[] = {const_cast<char*>("test_program_options_implicit_value"), const_cast<char*>("--arg1=11")};

        po::variables_map vm;
        po::store(po::parse_command_line(2, argv, desc), vm);
        po::notify(vm);

        BOOST_CHECK_MESSAGE(vm.count("arg1"), "Expected arg1");
        BOOST_CHECK_MESSAGE(vm["arg1"].as<string>() == "11",
                            "Expected arg1 with value of 11 but found " << vm["arg1"].as<string>());
    }
}

BOOST_AUTO_TEST_CASE(test_program_options_multitoken) {
    ECF_NAME_THIS_TEST();

    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()("help",
                       "produce help message")("arg1", po::value<vector<string>>()->multitoken(), "arg1 description");

    char* argv[] = {const_cast<char*>("test_program_options_multitoken"),
                    const_cast<char*>("--help"),
                    const_cast<char*>("--arg1"),
                    const_cast<char*>("a"),
                    const_cast<char*>("b")};

    po::variables_map vm;
    po::store(po::parse_command_line(5, argv, desc), vm);
    po::notify(vm);

    BOOST_CHECK_MESSAGE(vm.count("help"), "Expected help");
    BOOST_CHECK_MESSAGE(vm.count("arg1"), "Expected arg1");

    std::vector<string> expected;
    expected.emplace_back("a");
    expected.emplace_back("b");
    BOOST_CHECK_MESSAGE(vm["arg1"].as<vector<string>>() == expected, "multi-token not as expected");
}

BOOST_AUTO_TEST_CASE(test_program_options_multitoken_with_negative_values) {
    ECF_NAME_THIS_TEST();

    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()("help",
                       "produce help message")("arg1", po::value<vector<string>>()->multitoken(), "arg1 description");

    char* argv[] = {const_cast<char*>("test_program_options_multitoken_1"),
                    const_cast<char*>("--help"),
                    const_cast<char*>("--arg1"),
                    const_cast<char*>("-1"),
                    const_cast<char*>("-w")};

    //  --alter delete cron -w 0,1 10:00 /s1     # -w treated as option
    //  --alter=/s1 change meter name -1         # -1 treated as option
    // Note: negative numbers get treated as options: i.e trying to change meter value to a negative number
    //  To avoid negative numbers from being treated as option use, we need to change command line style:
    //       po::command_line_style::unix_style ^ po::command_line_style::allow_short

    po::variables_map vm;
    po::store(
        po::parse_command_line(5, argv, desc, po::command_line_style::unix_style ^ po::command_line_style::allow_short),
        vm);
    po::notify(vm);

    BOOST_CHECK_MESSAGE(vm.count("help"), "Expected help");
    BOOST_CHECK_MESSAGE(vm.count("arg1"), "Expected arg1");

    std::vector<string> expected;
    expected.emplace_back("-1");
    expected.emplace_back("-w");
    BOOST_CHECK_MESSAGE(vm["arg1"].as<vector<string>>() == expected, "multi-token not as expected");
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()