1 //  (C) Copyright Raffi Enficiaud 2018
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 /// @file
9 /// @brief tests the access to the master test suite from the datasets, trac 12953
10 // ***************************************************************************
11 
12 #define BOOST_TEST_MODULE "Access master test suite arguments from datasets"
13 #include <boost/test/included/unit_test.hpp>
14 
15 #include <boost/test/data/test_case.hpp>
16 #include <iostream>
17 
18 class dataset_loader
19 {
20 public:
21     enum { arity = 1 };
22 
23     // this constructor access the master test suite
24     dataset_loader();
dataset_loader(std::initializer_list<std::string> init_list)25     dataset_loader(std::initializer_list<std::string> init_list)
26     : m_input_extension(init_list)
27     {}
dataset_loader(std::string s1,std::string s2)28     dataset_loader(std::string s1, std::string s2)
29     {
30       m_input_extension.push_back(s1);
31       m_input_extension.push_back(s2);
32     }
33 
34     struct iterator {
iteratordataset_loader::iterator35         iterator(std::vector<std::string>::const_iterator const& v_iterator)
36         : m_iterator(v_iterator)
37         {}
38 
39         // bug in joins, see 13380, can safely be changed to std::string once fixed
operator *dataset_loader::iterator40         const std::string& operator*() const   { return *m_iterator; }
operator ++dataset_loader::iterator41         void operator++()
42         {
43             ++m_iterator;
44         }
45     private:
46         std::vector<std::string>::const_iterator m_iterator;
47     };
48 
size() const49     boost::unit_test::data::size_t size() const {
50       return m_input_extension.size();
51     }
52 
53     // iterator
begin() const54     iterator        begin() const   { return iterator(m_input_extension.begin()); }
55 
56 private:
57     std::vector<std::string> m_input_extension;
58 };
59 
60 
dataset_loader()61 dataset_loader::dataset_loader()
62 {
63     BOOST_TEST_INFO("dataset_loader");
64 
65     int argc = boost::unit_test::framework::master_test_suite().argc;
66     char** argv = boost::unit_test::framework::master_test_suite().argv;
67 
68     // not taking into account the name of the program (first argument)
69     for(unsigned i = 1; i != argc; i++) {
70         m_input_extension.push_back(argv[i]);
71     }
72 }
73 
74 //------------------------------------------------------------------------------
75 
76 namespace boost { namespace unit_test { namespace data {
77 
78 namespace monomorphic {
79   template <>
80   struct is_dataset<dataset_loader> : boost::mpl::true_ {};
81 }
82 }}}
83 
84 BOOST_AUTO_TEST_SUITE( concrete_testsuite )
85 
86 // parameters passed on the command line
87 char const* expected[] = {"--param1=1", "--param2=2"};
88 
89 BOOST_DATA_TEST_CASE(master_access_zips,
90     boost::unit_test::data::make_delayed<dataset_loader>( ) ^ boost::unit_test::data::make(expected),
91     input, expect)
92 {
93     // ...
94     BOOST_TEST(input == expect);
95 }
96 
97 
98 BOOST_DATA_TEST_CASE(master_access_zips_flip,
99     boost::unit_test::data::make_delayed<dataset_loader>( ) ^ dataset_loader({"--param1=1", "--param2=2"}),
100     input, expect)
101 {
102     BOOST_TEST(input == expect);
103 }
104 
105 // checking the forward of the arguments
106 BOOST_DATA_TEST_CASE(master_access_zips_args_forward,
107     boost::unit_test::data::make_delayed<dataset_loader>( "--param1=1", "--param2=2" ) ^ boost::unit_test::data::make_delayed<dataset_loader>( ),
108     input, expect)
109 {
110     BOOST_TEST(input == expect);
111 }
112 
113 BOOST_DATA_TEST_CASE(master_access_grid,
114     boost::unit_test::data::make_delayed<dataset_loader>( ) * dataset_loader({"--param1=1", "--param2=2"}),
115     input, expect)
116 {
117     BOOST_TEST((input == expect || input == "--param1=1" || expect == "--param1=1" ));
118 }
119 
120 BOOST_DATA_TEST_CASE(master_access_grid_flip,
121     dataset_loader({"--param1=1", "--param2=2"}) * boost::unit_test::data::make_delayed<dataset_loader>( ),
122     input, expect)
123 {
124     BOOST_TEST((input == expect || input == "--param1=1" || expect == "--param1=1" ));
125 }
126 
127 int counter4 = 0;
128 BOOST_DATA_TEST_CASE(master_access_joins,
129     boost::unit_test::data::make_delayed<dataset_loader>( ) + dataset_loader({"--param1=1", "--param2=2"}),
130     input)
131 {
132     static const std::string values[] = {"--param1=1", "--param2=2", "--param1=1", "--param2=2"};
133     BOOST_TEST(input == values[counter4++]);
134 }
135 
136 int counter41 = 0;
137 BOOST_DATA_TEST_CASE(master_access_joins_flip,
138     dataset_loader({"--param2=2", "--param1=1"}) + boost::unit_test::data::make_delayed<dataset_loader>( ),
139     input)
140 {
141     static const std::string values[] = {"--param2=2", "--param1=1", "--param1=1", "--param2=2"};
142     BOOST_TEST(input == values[counter41++]);
143 }
144 
145 BOOST_AUTO_TEST_SUITE_END()
146 
147 
148 class dataset_loader_arity3
149 {
150 public:
151     typedef std::vector<std::string>                    data_type;
152 
153     data_type m_expected;
154     data_type m_input;
155 
156     enum { arity = 3 };
157 
158 public:
dataset_loader_arity3(std::string some_additional)159     dataset_loader_arity3(std::string some_additional) : m_some_additional(some_additional)
160     {
161       int argc = boost::unit_test::framework::master_test_suite().argc;
162       char** argv = boost::unit_test::framework::master_test_suite().argv;
163 
164 
165       for(unsigned i = 1; i != argc; i++) {
166         std::string current(argv[i]);
167         std::cout << "current " << current << std::endl;
168         if(current.find("--param1") != std::string::npos) {
169           m_expected.push_back(current);
170         }
171         else {
172           m_input.push_back(current);
173         }
174       }
175     }
176 
177     struct iterator {
iteratordataset_loader_arity3::iterator178         iterator(
179           data_type::const_iterator v_expected,
180           data_type::const_iterator v_input,
181           std::string additional)
182         : m_input(v_input)
183         , m_expected(v_expected)
184         , m_additional(additional)
185         {}
186 
187         // bug in joins, see 13380. We should return a non temporary
operator *dataset_loader_arity3::iterator188         std::tuple<std::string, std::string, std::string> operator*() const {
189           return std::tuple<std::string, std::string, std::string>(*m_input, *m_expected, *m_input + " -" + m_additional + "- " + *m_expected);
190         }
operator ++dataset_loader_arity3::iterator191         void operator++()
192         {
193             ++m_input;
194             ++m_expected;
195         }
196     private:
197         data_type::const_iterator m_input, m_expected;
198         std::string m_additional;
199     };
200 
size() const201     boost::unit_test::data::size_t size() const {
202       using namespace boost;
203       BOOST_TEST_I_ASSRT( m_expected.size() == m_input.size(), "Lists of strings of different size" );
204       return m_input.size();
205     }
206 
207     // iterator
begin() const208     iterator        begin() const   {
209       using namespace boost;
210       BOOST_TEST_I_ASSRT( m_expected.size() == m_input.size(), "Lists of strings of different size" );
211       return iterator(m_expected.begin(), m_input.begin(), m_some_additional); }
212 
213 private:
214     std::string m_some_additional;
215 
216 };
217 
218 namespace boost { namespace unit_test { namespace data {
219 
220 namespace monomorphic {
221   template <>
222   struct is_dataset<dataset_loader_arity3> : boost::mpl::true_ {};
223 }
224 }}}
225 
226 BOOST_DATA_TEST_CASE(master_access_make_ds_with_arity,
227     boost::unit_test::data::make_delayed<dataset_loader_arity3>( "something-in-the-middle"),
228     input, expected, additional)
229 {
230     std::cout << "input: " << input << " -- expected: " << expected << " -- additional: " << additional << std::endl;
231     BOOST_TEST(true);
232 }
233