1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * Copyright (C) 2008-2009 Kouhei Sutou <kou@clear-code.com>
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-iterated-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_ITERATED_TEST_GET_PRIVATE(obj) \
35 (G_TYPE_INSTANCE_GET_PRIVATE((obj), CUT_TYPE_ITERATED_TEST, CutIteratedTestPrivate))
36
37 typedef struct _CutIteratedTestPrivate CutIteratedTestPrivate;
38 struct _CutIteratedTestPrivate
39 {
40 CutIteratedTestFunction iterated_test_function;
41 CutTestData *data;
42 };
43
44 enum
45 {
46 PROP_0,
47 PROP_ITERATED_TEST_FUNCTION,
48 PROP_DATA
49 };
50
51 G_DEFINE_TYPE(CutIteratedTest, cut_iterated_test, CUT_TYPE_TEST)
52
53 static void dispose (GObject *object);
54 static void set_property (GObject *object,
55 guint prop_id,
56 const GValue *value,
57 GParamSpec *pspec);
58 static void get_property (GObject *object,
59 guint prop_id,
60 GValue *value,
61 GParamSpec *pspec);
62
63 static gboolean is_available (CutTest *test,
64 CutTestContext *test_context,
65 CutRunContext *run_context);
66 static void invoke (CutTest *test,
67 CutTestContext *test_context,
68 CutRunContext *run_context);
69
70 static void
cut_iterated_test_class_init(CutIteratedTestClass * klass)71 cut_iterated_test_class_init (CutIteratedTestClass *klass)
72 {
73 GObjectClass *gobject_class;
74 CutTestClass *test_class;
75 GParamSpec *spec;
76
77 gobject_class = G_OBJECT_CLASS(klass);
78
79 gobject_class->dispose = dispose;
80 gobject_class->set_property = set_property;
81 gobject_class->get_property = get_property;
82
83 test_class = CUT_TEST_CLASS(klass);
84 test_class->is_available = is_available;
85 test_class->invoke = invoke;
86
87 spec = g_param_spec_pointer("iterated-test-function",
88 "Iterated Test Function",
89 "The function for iterated test",
90 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
91 g_object_class_install_property(gobject_class, PROP_ITERATED_TEST_FUNCTION,
92 spec);
93
94 spec = g_param_spec_object("data",
95 "Data",
96 "The test data for iterated test",
97 CUT_TYPE_TEST_DATA,
98 G_PARAM_READWRITE);
99 g_object_class_install_property(gobject_class, PROP_DATA, spec);
100
101 g_type_class_add_private(gobject_class, sizeof(CutIteratedTestPrivate));
102 }
103
104 static void
cut_iterated_test_init(CutIteratedTest * test)105 cut_iterated_test_init (CutIteratedTest *test)
106 {
107 CutIteratedTestPrivate *priv = CUT_ITERATED_TEST_GET_PRIVATE(test);
108
109 priv->iterated_test_function = NULL;
110 priv->data = NULL;
111 }
112
113 static void
dispose(GObject * object)114 dispose (GObject *object)
115 {
116 CutIteratedTestPrivate *priv = CUT_ITERATED_TEST_GET_PRIVATE(object);
117
118 priv->iterated_test_function = NULL;
119
120 if (priv->data) {
121 g_object_unref(priv->data);
122 priv->data = NULL;
123 }
124
125 G_OBJECT_CLASS(cut_iterated_test_parent_class)->dispose(object);
126 }
127
128 static void
set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)129 set_property (GObject *object,
130 guint prop_id,
131 const GValue *value,
132 GParamSpec *pspec)
133 {
134 CutIteratedTestPrivate *priv = CUT_ITERATED_TEST_GET_PRIVATE(object);
135
136 switch (prop_id) {
137 case PROP_ITERATED_TEST_FUNCTION:
138 priv->iterated_test_function = g_value_get_pointer(value);
139 break;
140 case PROP_DATA:
141 cut_iterated_test_set_data(CUT_ITERATED_TEST(object),
142 g_value_get_object(value));
143 break;
144 default:
145 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
146 break;
147 }
148 }
149
150 static void
get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)151 get_property (GObject *object,
152 guint prop_id,
153 GValue *value,
154 GParamSpec *pspec)
155 {
156 CutIteratedTestPrivate *priv = CUT_ITERATED_TEST_GET_PRIVATE(object);
157
158 switch (prop_id) {
159 case PROP_ITERATED_TEST_FUNCTION:
160 g_value_set_pointer(value, priv->iterated_test_function);
161 break;
162 case PROP_DATA:
163 g_value_set_object(value, priv->data);
164 break;
165 default:
166 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
167 break;
168 }
169 }
170
171 CutIteratedTest *
cut_iterated_test_new(const gchar * name,CutIteratedTestFunction function,CutTestData * data)172 cut_iterated_test_new (const gchar *name, CutIteratedTestFunction function,
173 CutTestData *data)
174 {
175 return g_object_new(CUT_TYPE_ITERATED_TEST,
176 "element-name", "iterated-test",
177 "name", name,
178 "iterated-test-function", function,
179 "data", data,
180 NULL);
181 }
182
183 CutIteratedTest *
cut_iterated_test_new_empty(void)184 cut_iterated_test_new_empty (void)
185 {
186 return cut_iterated_test_new(NULL, NULL, NULL);
187 }
188
189 CutTestData *
cut_iterated_test_get_data(CutIteratedTest * test)190 cut_iterated_test_get_data (CutIteratedTest *test)
191 {
192 return CUT_ITERATED_TEST_GET_PRIVATE(test)->data;
193 }
194
195 void
cut_iterated_test_set_data(CutIteratedTest * test,CutTestData * data)196 cut_iterated_test_set_data (CutIteratedTest *test, CutTestData *data)
197 {
198 CutIteratedTestPrivate *priv;
199
200 priv = CUT_ITERATED_TEST_GET_PRIVATE(test);
201 if (priv->data)
202 g_object_unref(priv->data);
203 priv->data = data;
204 if (priv->data)
205 g_object_ref(priv->data);
206 }
207
208 void
cut_iterated_test_clear_data(CutIteratedTest * test)209 cut_iterated_test_clear_data (CutIteratedTest *test)
210 {
211 CutIteratedTestPrivate *priv;
212
213 priv = CUT_ITERATED_TEST_GET_PRIVATE(test);
214 if (priv->data)
215 cut_test_data_set_value(priv->data, NULL, NULL);
216 }
217
218 static gboolean
is_available(CutTest * test,CutTestContext * test_context,CutRunContext * run_context)219 is_available (CutTest *test, CutTestContext *test_context,
220 CutRunContext *run_context)
221 {
222 CutIteratedTestPrivate *priv;
223
224 priv = CUT_ITERATED_TEST_GET_PRIVATE(test);
225 return priv->iterated_test_function && priv->data;
226 }
227
228 static void
invoke(CutTest * test,CutTestContext * test_context,CutRunContext * run_context)229 invoke (CutTest *test, CutTestContext *test_context, CutRunContext *run_context)
230 {
231 CutIteratedTestPrivate *priv;
232 gconstpointer value;
233
234 priv = CUT_ITERATED_TEST_GET_PRIVATE(test);
235
236 value = cut_test_data_get_value(priv->data);
237 if (cut_run_context_get_stop_before_test(run_context))
238 G_BREAKPOINT();
239 priv->iterated_test_function(value);
240 }
241
242 /*
243 vi:ts=4:nowrap:ai:expandtab:sw=4
244 */
245