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