Bump copyright year
[yaz-moved-to-github.git] / test / tst_record_conv.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5 #include <yaz/record_conv.h>
6 #include <yaz/test.h>
7 #include <yaz/wrbuf.h>
8 #include <string.h>
9 #include <yaz/log.h>
10 #include <yaz/libxml2_error.h>
11
12 #if HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #if YAZ_HAVE_XML2
17
18 #include <libxml/parser.h>
19 #include <libxml/tree.h>
20
21 yaz_record_conv_t conv_configure(const char *xmlstring, WRBUF w)
22 {
23     xmlDocPtr doc = xmlParseMemory(xmlstring, strlen(xmlstring));
24     if (!doc)
25     {
26         wrbuf_printf(w, "xmlParseMemory");
27         return 0;
28     }
29     else
30     {
31         xmlNodePtr ptr = xmlDocGetRootElement(doc);
32         yaz_record_conv_t p = yaz_record_conv_create();
33
34         if (p)
35         {
36             const char *srcdir = getenv("srcdir");
37             if (srcdir)
38                 yaz_record_conv_set_path(p, srcdir);
39         }
40         if (!ptr)
41         {
42             wrbuf_printf(w, "xmlDocGetRootElement");
43             yaz_record_conv_destroy(p);
44             p = 0;
45         }
46         else if (!p)
47         {
48             wrbuf_printf(w, "yaz_record_conv_create");
49         }
50         else
51         {
52
53
54             int r = yaz_record_conv_configure(p, ptr);
55             
56             if (r)
57             {
58                 wrbuf_puts(w, yaz_record_conv_get_error(p));
59                 yaz_record_conv_destroy(p);
60                 p = 0;
61             }
62         }
63         xmlFreeDoc(doc);
64         return p;
65     }    
66 }
67
68 int conv_configure_test(const char *xmlstring, const char *expect_error,
69                         yaz_record_conv_t *pt)
70 {
71     WRBUF w = wrbuf_alloc();
72     int ret;
73
74     yaz_record_conv_t p = conv_configure(xmlstring, w);
75
76     if (!p)
77     {
78         if (expect_error && !strcmp(wrbuf_cstr(w), expect_error))
79             ret = 1;
80         else
81         {
82             ret = 0;
83             printf("%s\n", wrbuf_cstr(w));
84         }
85     }
86     else
87     {
88         if (expect_error)
89             ret = 0;
90         else
91             ret = 1;
92     }
93
94     if (pt)
95         *pt = p;
96     else
97         if (p)
98             yaz_record_conv_destroy(p);
99
100     wrbuf_destroy(w);
101     return ret;
102 }
103
104 static void tst_configure(void)
105 {
106
107
108
109     YAZ_CHECK(conv_configure_test("<bad", "xmlParseMemory", 0));
110
111
112     YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
113                                   "<bad/></backend>",
114                                   "Element <backend>: expected <marc> or "
115                                   "<xslt> element, got <bad>", 0));
116
117 #if YAZ_HAVE_XSLT
118     YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
119                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
120                                   "<marc"
121                                   " inputcharset=\"marc-8\""
122                                   " outputcharset=\"marc-8\""
123                                   "/>"
124                                   "</backend>",
125                                   "Element <marc>: attribute 'inputformat' "
126                                   "required", 0));
127     YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
128                                   "<xslt/>"
129                                   "</backend>",
130                                   "Element <xslt>: attribute 'stylesheet' "
131                                   "expected", 0));
132     YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
133                                   "<marc"
134                                   " inputcharset=\"utf-8\""
135                                   " outputcharset=\"marc-8\""
136                                   " inputformat=\"xml\""
137                                   " outputformat=\"marc\""
138                                   "/>"
139                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
140                                   "</backend>",
141                                   0, 0));
142 #else
143     YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
144                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
145                                   "</backend>",
146                                   "xslt unsupported."
147                                   " YAZ compiled without XSLT support", 0));
148 #endif 
149 }
150
151 static int conv_convert_test(yaz_record_conv_t p,
152                              const char *input_record,
153                              const char *output_expect_record)
154 {
155     int ret = 0;
156     if (!p)
157     {
158         YAZ_CHECK(ret);
159     }
160     else
161     {
162         WRBUF output_record = wrbuf_alloc();
163         int r = yaz_record_conv_record(p, input_record, strlen(input_record),
164                                        output_record);
165         if (r)
166         {
167             if (output_expect_record)
168             {
169                 printf("yaz_record_conv error=%s\n",
170                        yaz_record_conv_get_error(p));
171                 ret = 0;
172             }
173             else
174                 ret = 1;
175         }
176         else
177         {
178             if (!output_expect_record)
179             {
180                 ret = 0;
181             }
182             else if (strcmp(output_expect_record, wrbuf_cstr(output_record)))
183             {
184                 ret = 0;
185                 printf("got-output_record len=%ld: %s\n", 
186                        (long) wrbuf_len(output_record),
187                        wrbuf_cstr(output_record));
188                 printf("output_expect_record len=%ld %s\n",
189                        (long) strlen(output_expect_record),
190                        output_expect_record);
191             }
192             else
193             {
194                 ret = 1;
195             }
196         }
197         wrbuf_destroy(output_record);
198     }
199     return ret;
200 }
201
202 static int conv_convert_test_iter(yaz_record_conv_t p,
203                                   const char *input_record,
204                                   const char *output_expect_record,
205                                   int num_iter)
206 {
207     int i;
208     int ret;
209     for (i = 0; i < num_iter; i++)
210     {
211         ret = conv_convert_test(p, input_record, output_expect_record);
212         if (!ret)
213             break;
214     }
215     return ret;
216 }
217
218 static void tst_convert1(void)
219 {
220     yaz_record_conv_t p = 0;
221     const char *marcxml_rec =
222         "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
223         "  <leader>00080nam a22000498a 4500</leader>\n"
224         "  <controlfield tag=\"001\">   11224466 </controlfield>\n"
225         "  <datafield tag=\"010\" ind1=\" \" ind2=\" \">\n"
226         "    <subfield code=\"a\">   11224466 </subfield>\n"
227         "  </datafield>\n"
228         "</record>\n";
229     const char *iso2709_rec =
230         "\x30\x30\x30\x38\x30\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34"
231         "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
232         "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x37\x30\x30\x30\x31\x33"
233         "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20"
234         "\x1F\x61\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x1D";
235
236     YAZ_CHECK(conv_configure_test("<backend>"
237                                   "<marc"
238                                   " inputcharset=\"utf-8\""
239                                   " outputcharset=\"marc-8\""
240                                   " inputformat=\"xml\""
241                                   " outputformat=\"marc\""
242                                   "/>"
243                                   "</backend>",
244                                   0, &p));
245     YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec));
246     yaz_record_conv_destroy(p);
247
248     YAZ_CHECK(conv_configure_test("<backend>"
249                                   "<marc"
250                                   " outputcharset=\"utf-8\""
251                                   " inputcharset=\"marc-8\""
252                                   " outputformat=\"marcxml\""
253                                   " inputformat=\"marc\""
254                                   "/>"
255                                   "</backend>",
256                                   0, &p));
257     YAZ_CHECK(conv_convert_test(p, iso2709_rec, marcxml_rec));
258     yaz_record_conv_destroy(p);
259
260
261     YAZ_CHECK(conv_configure_test("<backend>"
262                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
263                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
264                                   "<marc"
265                                   " inputcharset=\"utf-8\""
266                                   " outputcharset=\"marc-8\""
267                                   " inputformat=\"xml\""
268                                   " outputformat=\"marc\""
269                                   "/>"
270                                   "<marc"
271                                   " outputcharset=\"utf-8\""
272                                   " inputcharset=\"marc-8\""
273                                   " outputformat=\"marcxml\""
274                                   " inputformat=\"marc\""
275                                   "/>"
276                                   "</backend>",
277                                   0, &p));
278     YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec));
279     yaz_record_conv_destroy(p);
280
281
282     YAZ_CHECK(conv_configure_test("<backend>"
283                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
284                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
285                                   "<marc"
286                                   " outputcharset=\"marc-8\""
287                                   " inputformat=\"xml\""
288                                   " outputformat=\"marc\""
289                                   "/>"
290                                   "<marc"
291                                   " inputcharset=\"marc-8\""
292                                   " outputformat=\"marcxml\""
293                                   " inputformat=\"marc\""
294                                   "/>"
295                                   "</backend>",
296                                   0, &p));
297     YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec));
298     yaz_record_conv_destroy(p);
299 }
300
301 static void tst_convert2(void)
302 {
303     yaz_record_conv_t p = 0;
304     const char *marcxml_rec =
305         "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
306         "  <leader>00080nam a22000498a 4500</leader>\n"
307         "  <controlfield tag=\"001\">   11224466 </controlfield>\n"
308         "  <datafield tag=\"010\" ind1=\" \" ind2=\" \">\n"
309         "    <subfield code=\"a\">k&#xf8;benhavn</subfield>\n"
310         "  </datafield>\n"
311         "</record>\n";
312     const char *iso2709_rec =
313         "\x30\x30\x30\x37\x37\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34"
314         "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
315         "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x34\x30\x30\x30\x31\x33"
316         "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20"
317         "\x1F\x61\x6b\xb2\x62\x65\x6e\x68\x61\x76\x6e\x1E\x1D";
318
319     YAZ_CHECK(conv_configure_test("<backend>"
320                                   "<marc"
321                                   " inputcharset=\"utf-8\""
322                                   " outputcharset=\"marc-8\""
323                                   " inputformat=\"xml\""
324                                   " outputformat=\"marc\""
325                                   "/>"
326                                   "</backend>",
327                                   0, &p));
328     YAZ_CHECK(conv_convert_test_iter(p, marcxml_rec, iso2709_rec, 100));
329     yaz_record_conv_destroy(p);
330 }
331
332 #endif
333
334 int main(int argc, char **argv)
335 {
336     YAZ_CHECK_INIT(argc, argv);
337     libxml2_error_to_yazlog(0 /* disable log */, 0);
338 #if YAZ_HAVE_XML2
339     tst_configure();
340 #endif
341 #if  YAZ_HAVE_XSLT 
342     tst_convert1();
343     tst_convert2();
344 #endif
345     YAZ_CHECK_TERM;
346 }
347
348 /*
349  * Local variables:
350  * c-basic-offset: 4
351  * c-file-style: "Stroustrup"
352  * indent-tabs-mode: nil
353  * End:
354  * vim: shiftwidth=4 tabstop=8 expandtab
355  */
356