00001 // See ../../license.txt for license information. 00002 // 00003 // unit_test.cpp 00004 // 00005 // 4-Jul-2003 phamilton Created 00006 // 00007 00008 #include <iostream> 00009 #include <boost/test/included/unit_test_framework.hpp> 00010 using boost::unit_test_framework::test_suite; 00011 using boost::test_toolbox::output_test_stream; 00012 #include "test_base.hpp" 00013 #include "../xml/writeobj.hpp" 00014 #include "../xml/parseobj.hpp" 00015 #include "../dumpobj.hpp" 00016 #include "context.hpp" 00017 00018 using namespace persist_test; 00019 00020 namespace persist_test { 00021 00022 class test_dumper 00023 /* 00024 A test for the simple object dumper. 00025 */ 00026 { 00027 public: 00028 00029 void test(); 00030 }; 00031 00032 class test_dump : public test_base 00033 /* 00034 Test which will read in an XML file and then "dump" it using 00035 the dump member inside the root object. 00036 */ 00037 { 00038 public: 00039 test_dump(const std::string &infile, const std::string &matchfile) : 00040 test_base(infile, matchfile) 00041 {}; 00042 00043 // test_base overrides 00044 virtual void write_output(ph::common::object_base *obj, 00045 const std::string &matchfile); 00046 }; 00047 00048 class test_xml_read : public test_dump 00049 /* 00050 A test for reading a simple XML file. 00051 */ 00052 { 00053 public: 00054 test_xml_read(const std::string &infile, const std::string &matchfile) : 00055 test_dump(infile, matchfile) 00056 {}; 00057 void test() { dotest(); } 00058 }; 00059 00060 class test_import : public test_dump 00061 /* 00062 A test for reading an XML file which imports another. 00063 */ 00064 { 00065 public: 00066 test_import(const std::string &infile, const std::string &matchfile) : 00067 test_dump(infile, matchfile) 00068 {}; 00069 void test() { dotest(); } 00070 }; 00071 00072 class test_fragment : public test_dump 00073 /* 00074 A test for reading an XML file which imports another as a "fragment". 00075 */ 00076 { 00077 public: 00078 test_fragment(const std::string &infile, const std::string &matchfile) : 00079 test_dump(infile, matchfile) 00080 {}; 00081 void test() { dotest(); } 00082 }; 00083 00084 class test_vars : public test_dump 00085 /* 00086 A test for vars in the XML file. 00087 */ 00088 { 00089 public: 00090 test_vars(const std::string &infile, const std::string &matchfile) : 00091 test_dump(infile, matchfile) 00092 {}; 00093 void test() { dotest(); } 00094 }; 00095 00096 class test_write : public test_base 00097 /* 00098 A test for writing an XML file after reading the same one. 00099 00100 For now, the two files may differ because of whitespace preservation 00101 issues. 00102 */ 00103 { 00104 public: 00105 test_write(const std::string &infile, const std::string &matchfile) : 00106 test_base(infile, matchfile) 00107 {}; 00108 void test() { dotest(); } 00109 00110 // test_base overrides 00111 virtual void write_output(ph::common::object_base *obj, 00112 const std::string &matchfile); 00113 }; 00114 00115 class test_baddata 00116 /* 00117 A test for writing an XML file after reading the same one. 00118 00119 For now, the two files may differ because of whitespace preservation 00120 issues. 00121 */ 00122 { 00123 public: 00124 test_baddata(const std::string &infile) : 00125 _infile(infile) 00126 {}; 00127 00128 void test(); 00129 00130 private: 00131 std::string _infile; 00132 }; 00133 00134 }; 00135 00136 test_suite *init_unit_test_suite(int argc, char* argv[]) 00137 { 00138 test_suite * test = BOOST_TEST_SUITE("persist units tests"); 00139 00140 test->add(BOOST_CLASS_TEST_CASE(&test_dumper::test, 00141 boost::shared_ptr<test_dumper>(new test_dumper()))); 00142 test->add(BOOST_CLASS_TEST_CASE(&test_xml_read::test, 00143 boost::shared_ptr<test_xml_read>(new test_xml_read(argv[1], argv[4])))); 00144 test->add(BOOST_CLASS_TEST_CASE(&test_import::test, 00145 boost::shared_ptr<test_import>(new test_import(argv[2], argv[4])))); 00146 test->add(BOOST_CLASS_TEST_CASE(&test_fragment::test, 00147 boost::shared_ptr<test_fragment>(new test_fragment(argv[3], argv[4])))); 00148 test->add(BOOST_CLASS_TEST_CASE(&test_write::test, 00149 boost::shared_ptr<test_write>(new test_write(argv[1], argv[5])))); 00150 test->add(BOOST_CLASS_TEST_CASE(&test_baddata::test, 00151 boost::shared_ptr<test_baddata>(new test_baddata(argv[6])))); 00152 test->add(BOOST_CLASS_TEST_CASE(&test_vars::test, 00153 boost::shared_ptr<test_vars>(new test_vars(argv[7], argv[4])))); 00154 00155 return test; 00156 } 00157 00158 using namespace persist_test; 00159 00160 // test_dumper 00161 // 00162 00163 void test_dumper::test() 00164 { 00165 // simple object with attributes. 00166 { 00167 output_test_stream output; 00168 output_test_stream console; 00169 ph::persist::dumpobj writer(&output, &console); 00170 { 00171 ph::common::object_writer_context c(&writer, "xxx"); 00172 c.attr("yyy", "zzz"); 00173 BOOST_CHECK(console.is_empty()); 00174 } 00175 BOOST_CHECK(output.is_equal("xxx(yyy=zzz) {\n}\n")); 00176 } 00177 00178 // simple data object. 00179 { 00180 output_test_stream output; 00181 output_test_stream console; 00182 ph::persist::dumpobj writer(&output, &console); 00183 { 00184 ph::common::object_writer_context c(&writer, "xxx"); 00185 c.data("yyy"); 00186 } 00187 BOOST_CHECK(console.is_empty()); 00188 BOOST_CHECK(output.is_equal("xxx=yyy\n")); 00189 } 00190 00191 // nested object with attributes. 00192 { 00193 output_test_stream output; 00194 output_test_stream console; 00195 ph::persist::dumpobj writer(&output, &console); 00196 { 00197 ph::common::object_writer_context c1(&writer, "root"); 00198 c1.attr("name", "root"); 00199 { 00200 ph::common::object_writer_context c2(&writer, "x"); 00201 c2.data("1"); 00202 } 00203 { 00204 ph::common::object_writer_context c2(&writer, "foos"); 00205 { 00206 ph::common::object_writer_context c3(&writer, "foo"); 00207 c3.attr("name", "foo_1"); 00208 { 00209 ph::common::object_writer_context c4(&writer, "x"); 00210 c4.data("1"); 00211 } 00212 { 00213 ph::common::object_writer_context c4(&writer, "y"); 00214 c4.data("2.1"); 00215 } 00216 } 00217 { 00218 ph::common::object_writer_context c3(&writer, "foo"); 00219 c3.attr("name", "foo_2"); 00220 } 00221 } 00222 } 00223 BOOST_CHECK(console.is_empty()); 00224 BOOST_CHECK(output.is_equal( 00225 "root(name=root) {\n x=1\n foos {\n foo(name=foo_1) {\n " 00226 "x=1\n y=2.1\n }\n foo(name=foo_2) {\n }\n }\n}\n")); 00227 } 00228 } 00229 00230 // test_dump 00231 // 00232 00233 void test_dump::write_output(ph::common::object_base *obj, 00234 const std::string &matchfile) 00235 { 00236 output_test_stream output(matchfile); 00237 { 00238 output_test_stream console; 00239 ph::persist::dumpobj writer(&output, &console); 00240 { 00241 BOOST_REQUIRE_MESSAGE(obj->persistable(), 00242 "No persistable interface from object returned."); 00243 BOOST_REQUIRE(obj->persistable()->write(&writer)); 00244 } 00245 BOOST_CHECK(console.is_empty()); 00246 } 00247 BOOST_CHECK(output.match_pattern()); 00248 } 00249 00250 // test_write 00251 // 00252 00253 void test_write::write_output(ph::common::object_base *obj, 00254 const std::string &matchfile) 00255 { 00256 output_test_stream output(matchfile); 00257 { 00258 output_test_stream console; 00259 ph::persist::xml::writeobj writer(&output, &console); 00260 { 00261 BOOST_REQUIRE_MESSAGE(obj->persistable(), 00262 "No persistable interface from object returned."); 00263 BOOST_REQUIRE(obj->persistable()->write(&writer)); 00264 } 00265 BOOST_CHECK(console.is_empty()); 00266 } 00267 BOOST_CHECK(output.match_pattern()); 00268 } 00269 00270 // test_baddata 00271 // 00272 00273 void test_baddata::test() 00274 { 00275 std::ifstream f(_infile.c_str()); 00276 BOOST_REQUIRE(f.is_open()); 00277 00278 context c; 00279 output_test_stream output; 00280 ph::persist::xml::parseobj parser(0, &f, _infile.c_str(), 00281 &c, false, &output, "", false, false); 00282 BOOST_CHECK(ph::persist::xml::parse::parse_xml(&f, _infile.c_str(), &parser, 0)); 00283 BOOST_CHECK(output.is_equal("file: test/test4.xml Tried to set a member [x] with bad data [xxxxxx]. at line 28\n")); 00284 f.close(); 00285 BOOST_CHECK(!parser.obj()); 00286 }