1 /*
2  * Copyright (C) 2008 - 2011 Vivien Malerba <malerba@gnome-db.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 #include "common.h"
19 #ifdef HAVE_JSON_GLIB
20 #include <json-glib/json-glib.h>
21 #endif
22 
23 void
tests_common_display_value(const gchar * prefix,const GValue * value)24 tests_common_display_value (const gchar *prefix, const GValue *value)
25 {
26 	gchar *str;
27 
28 	str = gda_value_stringify ((GValue*) value);
29 	g_print ("*** %s: %s\n", prefix, str);
30 	g_free (str);
31 }
32 
33 gchar *
tests_common_holder_serialize(GdaHolder * h)34 tests_common_holder_serialize (GdaHolder *h)
35 {
36 	GString *string;
37 	gchar *str, *json;
38 	const GValue *value;
39 
40 	string = g_string_new ("{");
41 
42 	g_string_append (string, "\"type\":");
43 	g_string_append_printf (string, "\"%s\"", g_type_name (gda_holder_get_g_type (h)));
44 
45 	g_string_append (string, ",\"id\":");
46 	json = _json_quote_string (gda_holder_get_id (h));
47 	g_string_append (string, json);
48 	g_free (json);
49 
50 	g_object_get (G_OBJECT (h), "name", &str, NULL);
51 	if (str) {
52 		g_string_append (string, ",\"name\":");
53 		json = _json_quote_string (str);
54 		g_string_append (string, json);
55 		g_free (json);
56 		g_free (str);
57 	}
58 
59 	g_object_get (G_OBJECT (h), "description", &str, NULL);
60 	if (str) {
61 		g_string_append (string, ",\"descr\":");
62 		json = _json_quote_string (str);
63 		g_string_append (string, json);
64 		g_free (json);
65 		g_free (str);
66 	}
67 
68 	g_string_append (string, ",\"value\":");
69 	value = gda_holder_get_value (h);
70 	str = gda_value_stringify (value);
71 	json = _json_quote_string (str);
72 	g_free (str);
73 	g_string_append (string, json);
74 	g_free (json);
75 
76 	g_string_append (string, ",\"default_value\":");
77 	value = gda_holder_get_default_value (h);
78 	str = gda_value_stringify (value);
79 	json = _json_quote_string (str);
80 	g_free (str);
81 	g_string_append (string, json);
82 	g_free (json);
83 
84 	g_string_append (string, ",\"is_default\":");
85 	g_string_append_printf (string, gda_holder_value_is_default (h) ? "\"TRUE\"" : "\"FALSE\"");
86 
87 	g_string_append (string, ",\"is_valid\":");
88 	g_string_append_printf (string, gda_holder_is_valid (h) ? "\"TRUE\"" : "\"FALSE\"");
89 
90 	g_string_append (string, ",\"not_null\":");
91 	g_string_append_printf (string, gda_holder_get_not_null (h) ? "\"TRUE\"" : "\"FALSE\"");
92 
93 	g_string_append_c (string, '}');
94 	str = string->str;
95 	g_string_free (string, FALSE);
96 	return str;
97 }
98 
99 gchar *
tests_common_set_serialize(GdaSet * set)100 tests_common_set_serialize (GdaSet *set)
101 {
102 	GString *string;
103 	gchar *str, *json;
104 	GSList *list;
105 
106 	string = g_string_new ("{");
107 
108 	/* holders */
109 	if (set->holders) {
110 		g_string_append (string, "\"holders\":[");
111 		for (list = set->holders; list; list = list->next) {
112 			if (list != set->holders)
113 				g_string_append_c (string, ',');
114 			str = tests_common_holder_serialize (GDA_HOLDER (list->data));
115 			g_string_append (string, str);
116 			g_free (str);
117 		}
118 		g_string_append_c (string, ']');
119 	}
120 
121 	/* set description */
122 	g_object_get (G_OBJECT (set), "id", &str, NULL);
123 	if (str) {
124 		g_string_append (string, "\"id\":");
125 		json = _json_quote_string (str);
126 		g_string_append (string, json);
127 		g_free (json);
128 		g_free (str);
129 	}
130 
131 	g_object_get (G_OBJECT (set), "name", &str, NULL);
132 	if (str) {
133 		g_string_append (string, ",\"name\":");
134 		json = _json_quote_string (str);
135 		g_string_append (string, json);
136 		g_free (json);
137 		g_free (str);
138 	}
139 
140 	g_object_get (G_OBJECT (set), "description", &str, NULL);
141 	if (str) {
142 		g_string_append (string, ",\"descr\":");
143 		json = _json_quote_string (str);
144 		g_string_append (string, json);
145 		g_free (json);
146 		g_free (str);
147 	}
148 
149 	/* public data */
150 	if (set->nodes_list) {
151 		g_string_append (string, ",\"nodes\":[");
152 		for (list = set->nodes_list; list; list = list->next) {
153 			GdaSetNode *node = (GdaSetNode*) list->data;
154 			if (list != set->nodes_list)
155 				g_string_append_c (string, ',');
156 
157 			g_string_append_c (string, '{');
158 			g_string_append_printf (string, "\"holder\":%d", g_slist_index (set->holders, gda_set_node_get_holder (node)));
159 
160 			GdaDataModel *source_model;
161 			source_model = gda_set_node_get_data_model (node);
162 			if (source_model) {
163 				g_string_append (string, ",\"source_model\":");
164 				if (g_object_get_data (G_OBJECT (source_model), "name"))
165 					json = _json_quote_string (g_object_get_data (G_OBJECT (source_model), "name"));
166 				else {
167 					str = gda_data_model_export_to_string (source_model,
168 									       GDA_DATA_MODEL_IO_TEXT_SEPARATED,
169 									       NULL, 0, NULL, 0, NULL);
170 					json = _json_quote_string (str);
171 					g_free (str);
172 				}
173 				g_string_append (string, json);
174 				g_free (json);
175 
176 				g_string_append (string, ",\"source_column\":");
177 				g_string_append_printf (string, "\"%d\"", gda_set_node_get_source_column (node));
178 				/* FIXME: node->hint */
179 			}
180 			g_string_append_c (string, '}');
181 		}
182 		g_string_append_c (string, ']');
183 	}
184 
185 	if (set->sources_list) {
186 		g_string_append (string, ",\"sources\":[");
187 		for (list = set->sources_list; list; list = list->next) {
188 			GdaSetSource *source = (GdaSetSource*) list->data;
189 			if (list != set->sources_list)
190 				g_string_append_c (string, ',');
191 			g_string_append_c (string, '{');
192 			g_string_append (string, "\"model\":");
193 			GdaDataModel *data_model;
194 			data_model = gda_set_source_get_data_model (source);
195 			if (g_object_get_data (G_OBJECT (data_model), "name"))
196 				json = _json_quote_string (g_object_get_data (G_OBJECT (data_model), "name"));
197 			else {
198 				str = gda_data_model_export_to_string (data_model,
199 								       GDA_DATA_MODEL_IO_TEXT_SEPARATED,
200 								       NULL, 0, NULL, 0, NULL);
201 				json = _json_quote_string (str);
202 				g_free (str);
203 			}
204 			g_string_append (string, json);
205 			g_free (json);
206 
207 			g_string_append (string, ",\"nodes\":[");
208 			GSList *nodes;
209 			for (nodes = gda_set_source_get_nodes (source); nodes; nodes = nodes->next) {
210 				if (nodes != gda_set_source_get_nodes (source))
211 					g_string_append_c (string, ',');
212 				g_string_append_printf (string, "%d", g_slist_index (set->nodes_list, nodes->data));
213 			}
214 			g_string_append_c (string, ']');
215 
216 			g_string_append_c (string, '}');
217 		}
218 		g_string_append_c (string, ']');
219 	}
220 
221 	g_string_append_c (string, '}');
222 	str = string->str;
223 	g_string_free (string, FALSE);
224 	return str;
225 }
226 
227 /*
228  * Loads @filename where each line (terminated by a '\n') is in the form <id>|<text>, and lines starting
229  * with a '#' will be ignored. The new hash table is indexed on the <id> part.
230  */
231 GHashTable *
tests_common_load_data(const gchar * filename)232 tests_common_load_data (const gchar *filename)
233 {
234 	GHashTable *table;
235 	gchar *contents;
236 	GError *error = NULL;
237 	gchar *ptr;
238 	gchar *line_start, *line_end;
239 	gboolean stop = FALSE;
240 
241 	ptr = g_build_filename (ROOT_DIR, "tests", "value-holders", filename, NULL);
242 	if (!g_file_get_contents (ptr, &contents, NULL, &error))
243 		g_error ("Could not load file '%s': %s", ptr,
244 			 error->message);
245 
246 	table = g_hash_table_new (g_str_hash, g_str_equal);
247 
248 	line_start = contents;
249 	line_end = line_start;
250 	while (!stop) {
251 		for (line_end = line_start; *line_end && (*line_end != '\n'); line_end++);
252 		if (! *line_end) {
253 			stop = TRUE;
254 			if (line_end == line_start)
255 				break;
256 		}
257 
258 		*line_end = 0;
259 		if (*line_start != '#') {
260 			for (ptr = line_start; *ptr && (*ptr != '|'); ptr++);
261 			*ptr = 0;
262 			if (ptr == line_end)
263 				g_warning ("Invalid line in data file: %s", line_start);
264 			else {
265 				g_hash_table_insert (table, line_start, ptr+1);
266 				/*g_print ("ADDED (%s): %s\n", line_start, ptr+1);*/
267 			}
268 		}
269 
270 		if (!stop)
271 			line_start = line_end + 1;
272 	}
273 
274 	return table;
275 }
276 
277 gboolean
tests_common_check_holder(GHashTable * data,const gchar * id,GdaHolder * h,GError ** error)278 tests_common_check_holder (GHashTable *data, const gchar *id, GdaHolder *h, GError **error)
279 {
280 	gchar *s;
281 	const gchar *got;
282 
283 	s = tests_common_holder_serialize (h);
284 	got = g_hash_table_lookup (data, id);
285 	if (!got) {
286 #ifdef HAVE_JSON_GLIB
287 		JsonParser *jparser;
288 		jparser = json_parser_new ();
289 		if (!json_parser_load_from_data (jparser, s, -1, NULL))
290 			g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
291 				     "Unknown ID '%s', GdaHolder is: %s (JSON INVALID)\n", id, s);
292 		else {
293 			JsonGenerator *jgen;
294 			gchar *out;
295 			jgen = json_generator_new ();
296 			g_object_set (G_OBJECT (jgen), "pretty", TRUE, "indent", 5, NULL);
297 			json_generator_set_root (jgen, json_parser_get_root (jparser));
298 			out = json_generator_to_data (jgen, NULL);
299 			g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
300 				     "Unknown ID '%s', GdaHolder is: %s\nJSON: %s\n", id, s, out);
301 			g_print ("%s\n", out);
302 			g_free (out);
303 			g_object_unref (jgen);
304 		}
305 		g_object_unref (jparser);
306 #else
307 		g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
308 			     "Unknown ID '%s', GdaHolder is: %s\n", id, s);
309 #endif
310 
311 		g_free (s);
312 		g_object_unref (h);
313 		return FALSE;
314 	}
315 
316 	if (strcmp (got, s)) {
317 		g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
318 			     "GdaHolder error:\nexp: %s\ngot: %s\n", got, s);
319 		g_free (s);
320 		g_object_unref (h);
321 		return FALSE;
322 	}
323 	g_free (s);
324 	return TRUE;
325 }
326 
327 gboolean
tests_common_check_set(GHashTable * data,const gchar * id,GdaSet * set,GError ** error)328 tests_common_check_set (GHashTable *data, const gchar *id, GdaSet *set, GError **error)
329 {
330 	gchar *s;
331 	const gchar *got = NULL;
332 
333 	s = tests_common_set_serialize (set);
334 
335 	if (id)
336 		got = g_hash_table_lookup (data, id);
337 	if (!got) {
338 #ifdef HAVE_JSON_GLIB
339 		JsonParser *jparser;
340 		jparser = json_parser_new ();
341 		if (!json_parser_load_from_data (jparser, s, -1, NULL))
342 			g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
343 				     "Unknown ID '%s', GdaSet is: %s (JSON INVALID)\n", id, s);
344 		else {
345 			JsonGenerator *jgen;
346 			gchar *out;
347 			jgen = json_generator_new ();
348 			g_object_set (G_OBJECT (jgen), "pretty", TRUE, "indent", 5, NULL);
349 			json_generator_set_root (jgen, json_parser_get_root (jparser));
350 			out = json_generator_to_data (jgen, NULL);
351 			g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
352 				     "Unknown ID '%s', GdaSet is: %s\nJSON: %s\n", id, s, out);
353 			g_free (out);
354 			g_object_unref (jgen);
355 		}
356 		g_object_unref (jparser);
357 #else
358 		g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
359 			     "Unknown ID '%s', GdaSet is: %s\n", id, s);
360 #endif
361 
362 		g_free (s);
363 		g_object_unref (set);
364 		return FALSE;
365 	}
366 
367 	if (strcmp (got, s)) {
368 		g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC,
369 			     "GdaSet error:\nexp: %s\ngot: %s\n", got, s);
370 		g_free (s);
371 		g_object_unref (set);
372 		return FALSE;
373 	}
374 	g_free (s);
375 	return TRUE;
376 }
377