1 // Copyright (c) 2019 Raffi Enficiaud 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 //[example_code 9 #define BOOST_TEST_MODULE runtime_configuration4 10 11 #include <boost/test/included/unit_test.hpp> 12 #include <boost/test/data/test_case.hpp> 13 14 #include <iostream> 15 #include <functional> 16 #include <sstream> 17 #include <fstream> 18 19 // this dataset loads a file that contains a list of strings 20 // this list is used to create a dataset test case. 21 class file_dataset 22 { 23 private: 24 std::string m_filename; 25 std::size_t m_line_start; 26 std::size_t m_line_end; 27 28 public: 29 enum { arity = 2 }; 30 31 public: file_dataset(std::size_t line_start=0,std::size_t line_end=std::size_t (-1))32 file_dataset(std::size_t line_start = 0, std::size_t line_end = std::size_t(-1)) 33 : m_line_start(line_start) 34 , m_line_end(line_end) 35 { 36 int argc = boost::unit_test::framework::master_test_suite().argc; 37 char** argv = boost::unit_test::framework::master_test_suite().argv; 38 39 if(argc != 3) 40 throw std::logic_error("Incorrect number of arguments"); 41 if(std::string(argv[1]) != "--test-file") 42 throw std::logic_error("First argument != '--test-file'"); 43 if(!(m_line_start < std::size_t(-1))) 44 throw std::logic_error("Incorrect line start/end"); 45 46 m_filename = argv[2]; 47 48 std::ifstream file(m_filename); 49 if(!file.is_open()) 50 throw std::logic_error("Cannot open the file '" + m_filename + "'"); 51 std::size_t nb_lines = std::count_if( 52 std::istreambuf_iterator<char>(file), 53 std::istreambuf_iterator<char>(), 54 [](char c){ return c == '\n';}); 55 56 m_line_end = (std::min)(nb_lines, m_line_end); 57 if(!(m_line_start <= m_line_end)) 58 throw std::logic_error("Incorrect line start/end"); 59 } 60 61 struct iterator { iteratorfile_dataset::iterator62 iterator(std::string const& filename, std::size_t line_start) 63 : file(filename, std::ios::binary) { 64 if(!file.is_open()) 65 throw std::runtime_error("Cannot open the file"); 66 for(std::size_t i = 0; i < line_start; i++) { 67 getline(file, m_current_line); 68 } 69 } 70 operator *file_dataset::iterator71 auto operator*() const -> std::tuple<float, float> { 72 float a, b; 73 std::istringstream istr(m_current_line); 74 istr >> a >> b; 75 return std::tuple<float, float>(a, b); 76 } 77 operator ++file_dataset::iterator78 void operator++() { 79 getline(file, m_current_line); 80 } 81 private: 82 std::ifstream file; 83 std::string m_current_line; 84 }; 85 86 // size of the DS size() const87 boost::unit_test::data::size_t size() const { 88 return m_line_end - m_line_start; 89 } 90 91 // iterator over the lines of the file begin() const92 iterator begin() const { 93 return iterator(m_filename, m_line_start); 94 } 95 }; 96 97 namespace boost { namespace unit_test { namespace data { 98 99 namespace monomorphic { 100 template <> 101 struct is_dataset<file_dataset> : boost::mpl::true_ {}; 102 } 103 }}} 104 105 BOOST_DATA_TEST_CASE(command_line_test_file, 106 boost::unit_test::data::make_delayed<file_dataset>( 3, 10 ), 107 input, expected) { 108 BOOST_TEST(input <= expected); 109 } 110 //] 111