HTMLParser more forgiving with bad attributes
[metaproxy-moved-to-github.git] / src / test_html_parser.cpp
1 /* This file is part of Metaproxy.
2    Copyright (C) 2005-2013 Index Data
3
4 Metaproxy is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #include "config.hpp"
20 #include <iostream>
21 #include <stdexcept>
22
23 #include "html_parser.hpp"
24 #include <metaproxy/util.hpp>
25
26 #include <boost/lexical_cast.hpp>
27
28 #include <yaz/log.h>
29
30 #define BOOST_AUTO_TEST_MAIN
31 #define BOOST_TEST_DYN_LINK
32
33 #include <boost/test/auto_unit_test.hpp>
34
35 using namespace boost::unit_test;
36 namespace mp = metaproxy_1;
37
38 class MyEvent : public mp::HTMLParserEvent
39 {
40 public:
41     std::string out;
42     void openTagStart(const char *tag, int tag_len) {
43         out += "<";
44         out.append(tag, tag_len);
45     }
46
47     void attribute(const char *tag, int tag_len,
48                    const char *attr, int attr_len,
49                    const char *value, int val_len, const char *sep) {
50         out += " ";
51         out.append(attr, attr_len);
52         out += "=";
53         out += sep;
54         out.append(value, val_len);
55         out += sep;
56     }
57     void anyTagEnd(const char *tag, int tag_len, int close_it) {
58         if (close_it)
59             out += "/";
60         out += ">";
61     }
62     void closeTag(const char *tag, int tag_len) {
63         out += "</";
64         out.append(tag, tag_len);
65     }
66     void text(const char *value, int len) {
67         out.append(value, len);
68     }
69 };
70
71 BOOST_AUTO_TEST_CASE( test_html_parser_1 )
72 {
73     try
74     {
75         mp::HTMLParser hp;
76         const char* html =
77             "<html><body><a t1=v1 t2='v2' t3=\"v3\">some text</a>"
78             "<hr><table ></table  ><a href=\"x\"/></body></html>";
79         const char* expected =
80             "<html><body><a t1=v1 t2='v2' t3=\"v3\">some text</a>"
81             "<hr><table></table  ><a href=\"x\"/></body></html>";
82         MyEvent e;
83         hp.set_verbose(0);
84         hp.parse(e, html);
85
86         BOOST_CHECK_EQUAL(std::string(expected), e.out);
87         if (std::string(expected) != e.out)
88         {
89             std::cout << "Expected" << std::endl;
90             std::cout << expected << std::endl;
91             std::cout << "Got" << std::endl;
92             std::cout << e.out << std::endl;
93         }
94     }
95     catch (std::exception & e)
96     {
97         std::cout << e.what();
98         std::cout << std::endl;
99         BOOST_CHECK (false);
100     }
101 }
102
103 BOOST_AUTO_TEST_CASE( test_html_parser_2 )
104 {
105     try
106     {
107         mp::HTMLParser hp;
108         const char* html = 
109             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n"
110             "<HTML>\n"
111             " <HEAD>\n"
112             "  <TITLE>YAZ 4.2.60</TITLE>\n"
113             " </HEAD>\n"
114             " <BODY>\n"
115             "  <P><A HREF=\"http://www.indexdata.com/yaz/\">YAZ</A> 4.2.60</P>\n"
116             "  <P>Error: 404</P>\n"
117             "  <P>Description: Not Found</P>\n"
118             " </BODY>\n"
119             "</HTML>";
120
121         const char* expected = html;
122         MyEvent e;
123         hp.set_verbose(0);
124         hp.parse(e, html);
125
126         BOOST_CHECK_EQUAL(std::string(expected), e.out);
127         if (std::string(expected) != e.out)
128         {
129             std::cout << "Expected" << std::endl;
130             std::cout << expected << std::endl;
131             std::cout << "Got" << std::endl;
132             std::cout << e.out << std::endl;
133         }
134     }
135     catch (std::exception & e) 
136     {
137         std::cout << e.what();
138         std::cout << std::endl;
139         BOOST_CHECK (false);
140     }
141 }
142
143 BOOST_AUTO_TEST_CASE( test_html_parser_3 )
144 {
145     try
146     {
147         mp::HTMLParser hp;
148         const char* html =
149             "<?xml version=\"1.0\" strandalone=\"no\"?>\n"
150             "<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\"\n"
151             "  \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\"\n"
152             "[\n"
153             " <!ENTITY % local SYSTEM \"local.ent\">\n"
154             " %local;\n"
155             "]>\n"
156             "<book></book>";
157
158         const char* expected = html;
159         MyEvent e;
160         hp.set_verbose(0);
161         hp.parse(e, html);
162
163         BOOST_CHECK_EQUAL(std::string(expected), e.out);
164         if (std::string(expected) != e.out)
165         {
166             std::cout << "Expected" << std::endl;
167             std::cout << expected << std::endl;
168             std::cout << "Got" << std::endl;
169             std::cout << e.out << std::endl;
170         }
171     }
172     catch (std::exception & e) 
173     {
174         std::cout << e.what();
175         std::cout << std::endl;
176         BOOST_CHECK (false);
177     }
178 }
179
180 BOOST_AUTO_TEST_CASE( test_html_parser_4 )
181 {
182     try
183     {
184         mp::HTMLParser hp;
185         const char* html =
186             "<\"?xml version=\"1.0\" strandalone=\"no\"?  ax>\n"
187             "<book></book>";  // <book badboy></book> does not work
188
189         const char* expected = html;
190         MyEvent e;
191         hp.set_verbose(1);
192         hp.parse(e, html);
193
194         BOOST_CHECK_EQUAL(std::string(expected), e.out);
195         if (std::string(expected) != e.out)
196         {
197             std::cout << "Expected" << std::endl;
198             std::cout << expected << std::endl;
199             std::cout << "Got" << std::endl;
200             std::cout << e.out << std::endl;
201         }
202     }
203     catch (std::exception & e) 
204     {
205         std::cout << e.what();
206         std::cout << std::endl;
207         BOOST_CHECK (false);
208     }
209 }
210
211 /*
212  * Local variables:
213  * c-basic-offset: 4
214  * c-file-style: "Stroustrup"
215  * indent-tabs-mode: nil
216  * End:
217  * vim: shiftwidth=4 tabstop=8 expandtab
218  */
219