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