1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2008  Kouhei Sutou <kou@cozmixng.org>
4  *
5  *  This library is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif /* HAVE_CONFIG_H */
23 
24 #include <stdlib.h>
25 #include <string.h>
26 #include <glib.h>
27 
28 #include "cut-test.h"
29 #include "cut-test-container.h"
30 #include "cut-run-context.h"
31 #include "cut-test-result.h"
32 #include "cut-utils.h"
33 
34 #define CUT_TEST_DATA_GET_PRIVATE(obj)                                  \
35     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CUT_TYPE_TEST_DATA, CutTestDataPrivate))
36 
37 typedef struct _CutTestDataPrivate	CutTestDataPrivate;
38 struct _CutTestDataPrivate
39 {
40     gchar *name;
41     gpointer value;
42     CutDestroyFunction destroy_function;
43 };
44 
45 enum
46 {
47     PROP_0,
48     PROP_NAME,
49     PROP_VALUE,
50     PROP_DESTROY_FUNCTION
51 };
52 
53 G_DEFINE_TYPE(CutTestData, cut_test_data, G_TYPE_OBJECT)
54 
55 static void dispose        (GObject         *object);
56 static void set_property   (GObject         *object,
57                             guint            prop_id,
58                             const GValue    *value,
59                             GParamSpec      *pspec);
60 static void get_property   (GObject         *object,
61                             guint            prop_id,
62                             GValue          *value,
63                             GParamSpec      *pspec);
64 
65 static void
cut_test_data_class_init(CutTestDataClass * klass)66 cut_test_data_class_init (CutTestDataClass *klass)
67 {
68     GObjectClass *gobject_class;
69     GParamSpec *spec;
70 
71     gobject_class = G_OBJECT_CLASS(klass);
72 
73     gobject_class->dispose      = dispose;
74     gobject_class->set_property = set_property;
75     gobject_class->get_property = get_property;
76 
77     spec = g_param_spec_string("name",
78                                "Test Data Name",
79                                "The name of the test data",
80                                NULL,
81                                G_PARAM_READWRITE);
82     g_object_class_install_property(gobject_class, PROP_NAME, spec);
83 
84     spec = g_param_spec_pointer("value",
85                                 "Test Data Value",
86                                 "The value of the test data",
87                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
88     g_object_class_install_property(gobject_class, PROP_VALUE, spec);
89 
90     spec = g_param_spec_pointer("destroy-function",
91                                 "Test Data Destroy Function",
92                                 "The destroy function for the test data's value",
93                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
94     g_object_class_install_property(gobject_class, PROP_DESTROY_FUNCTION, spec);
95 
96     g_type_class_add_private(gobject_class, sizeof(CutTestDataPrivate));
97 }
98 
99 static void
cut_test_data_init(CutTestData * test)100 cut_test_data_init (CutTestData *test)
101 {
102     CutTestDataPrivate *priv = CUT_TEST_DATA_GET_PRIVATE(test);
103 
104     priv->name = NULL;
105     priv->value = NULL;
106     priv->destroy_function = NULL;
107 }
108 
109 static void
free_name(CutTestDataPrivate * priv)110 free_name (CutTestDataPrivate *priv)
111 {
112     if (priv->name) {
113         g_free(priv->name);
114         priv->name = NULL;
115     }
116 }
117 
118 static void
free_value(CutTestDataPrivate * priv)119 free_value (CutTestDataPrivate *priv)
120 {
121     if (priv->value) {
122         if (priv->destroy_function)
123             priv->destroy_function(priv->value);
124         priv->value = NULL;
125     }
126 }
127 
128 static void
dispose(GObject * object)129 dispose (GObject *object)
130 {
131     CutTestDataPrivate *priv = CUT_TEST_DATA_GET_PRIVATE(object);
132 
133     free_name(priv);
134     free_value(priv);
135 
136     G_OBJECT_CLASS(cut_test_data_parent_class)->dispose(object);
137 }
138 
139 static void
set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)140 set_property (GObject      *object,
141               guint         prop_id,
142               const GValue *value,
143               GParamSpec   *pspec)
144 {
145     CutTestDataPrivate *priv = CUT_TEST_DATA_GET_PRIVATE(object);
146 
147     switch (prop_id) {
148       case PROP_NAME:
149         cut_test_data_set_name(CUT_TEST_DATA(object), g_value_get_string(value));
150         break;
151       case PROP_VALUE:
152         free_value(priv);
153         priv->value = g_value_get_pointer(value);
154         break;
155       case PROP_DESTROY_FUNCTION:
156         priv->destroy_function = g_value_get_pointer(value);
157         break;
158       default:
159         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
160         break;
161     }
162 }
163 
164 static void
get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)165 get_property (GObject    *object,
166               guint       prop_id,
167               GValue     *value,
168               GParamSpec *pspec)
169 {
170     CutTestDataPrivate *priv = CUT_TEST_DATA_GET_PRIVATE(object);
171 
172     switch (prop_id) {
173       case PROP_NAME:
174         g_value_set_string(value, priv->name);
175         break;
176       case PROP_VALUE:
177         g_value_set_pointer(value, priv->value);
178         break;
179       case PROP_DESTROY_FUNCTION:
180         g_value_set_pointer(value, priv->destroy_function);
181         break;
182       default:
183         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
184         break;
185     }
186 }
187 
188 CutTestData *
cut_test_data_new(const gchar * name,gpointer value,CutDestroyFunction destroy_function)189 cut_test_data_new (const gchar *name, gpointer value,
190                    CutDestroyFunction destroy_function)
191 {
192     return g_object_new(CUT_TYPE_TEST_DATA,
193                         "name", name,
194                         "value", value,
195                         "destroy-function", destroy_function,
196                         NULL);
197 }
198 
199 CutTestData *
cut_test_data_new_empty(void)200 cut_test_data_new_empty (void)
201 {
202     return cut_test_data_new(NULL, NULL, NULL);
203 }
204 
205 const gchar *
cut_test_data_get_name(CutTestData * test_data)206 cut_test_data_get_name (CutTestData *test_data)
207 {
208     return CUT_TEST_DATA_GET_PRIVATE(test_data)->name;
209 }
210 
211 void
cut_test_data_set_name(CutTestData * test_data,const gchar * name)212 cut_test_data_set_name (CutTestData *test_data, const gchar *name)
213 {
214     CutTestDataPrivate *priv;
215 
216     priv = CUT_TEST_DATA_GET_PRIVATE(test_data);
217     free_name(priv);
218 
219     if (name)
220         priv->name = g_strdup(name);
221 }
222 
223 gpointer
cut_test_data_get_value(CutTestData * test_data)224 cut_test_data_get_value (CutTestData *test_data)
225 {
226     return CUT_TEST_DATA_GET_PRIVATE(test_data)->value;
227 }
228 
229 void
cut_test_data_set_value(CutTestData * test_data,gpointer value,CutDestroyFunction destroy_function)230 cut_test_data_set_value (CutTestData *test_data, gpointer value,
231                          CutDestroyFunction destroy_function)
232 {
233     CutTestDataPrivate *priv;
234 
235     priv = CUT_TEST_DATA_GET_PRIVATE(test_data);
236     free_value(priv);
237 
238     priv->value = value;
239     priv->destroy_function = destroy_function;
240 }
241 
242 gchar *
cut_test_data_to_xml(CutTestData * test_data)243 cut_test_data_to_xml (CutTestData *test_data)
244 {
245     GString *string;
246 
247     string = g_string_new(NULL);
248     cut_test_data_to_xml_string(test_data, string, 0);
249     return g_string_free(string, FALSE);
250 }
251 
252 void
cut_test_data_to_xml_string(CutTestData * test_data,GString * string,guint indent)253 cut_test_data_to_xml_string (CutTestData *test_data, GString *string,
254                              guint indent)
255 {
256     CutTestDataPrivate *priv;
257 
258     priv = CUT_TEST_DATA_GET_PRIVATE(test_data);
259 
260     cut_utils_append_indent(string, indent);
261     g_string_append_printf(string, "<test-data>\n");
262 
263     if (priv->name)
264         cut_utils_append_xml_element_with_value(string, indent + 2,
265                                                 "name", priv->name);
266 
267     cut_utils_append_indent(string, indent);
268     g_string_append_printf(string, "</test-data>\n");
269 }
270 
271 /*
272 vi:ts=4:nowrap:ai:expandtab:sw=4
273 */
274