Ansel
0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
test_metadata_notify.c
Go to the documentation of this file.
1
/*
2
This file is part of Ansel,
3
Copyright (C) 2026 Aurélien PIERRE.
4
5
Ansel is free software: you can redistribute it and/or modify
6
it under the terms of the GNU 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
Ansel 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 General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
27
#include "
metadata/notify.h
"
28
29
#include <stdarg.h>
30
#include <stddef.h>
31
// cmocka.h declares `extern jmp_buf global_expect_assert_env' at file scope and does not
32
// include <setjmp.h> itself -- it says so at its own line 50. No test names a setjmp
33
// symbol, so include-cleaner cannot attribute this one; removing it stops cmocka.h from
34
// parsing. The suppression is on the line itself, not NOLINTNEXTLINE above: that form
35
// applies to the immediately following line, which a multi-line reason turns into another
36
// comment, silently suppressing nothing.
37
#include <setjmp.h>
// NOLINT(misc-include-cleaner)
38
#include <stdint.h>
39
#include <cmocka.h>
40
41
#include <string.h>
42
43
#include <glib.h>
44
45
typedef
struct
_seen_t
46
{
47
int
toasts
;
48
int
messages
;
49
int
tag_changes
;
50
gchar *
last
;
51
}
_seen_t
;
52
53
static
_seen_t
_seen
;
54
55
static
void
_record
(
const
dt_metadata_notice_t
kind
,
const
char
*message)
56
{
57
if
(
kind
==
DT_METADATA_NOTICE_TOAST
)
_seen
.
toasts
++;
58
else
_seen
.
messages
++;
59
g_free
(
_seen
.
last
);
60
_seen
.
last
=
g_strdup
(message);
61
}
62
63
static
void
_record_tag_change
(
void
)
64
{
65
_seen
.
tag_changes
++;
66
}
67
68
static
int
_setup
(
void
**
state
)
69
{
70
(
void
)
state
;
71
memset
(&
_seen
, 0,
sizeof
(
_seen
));
72
return
0;
73
}
74
75
static
int
_teardown
(
void
**
state
)
76
{
77
(
void
)
state
;
78
dt_metadata_set_notify_handler
(
NULL
);
79
dt_metadata_set_tags_changed_handler
(
NULL
);
80
g_free
(
_seen
.
last
);
81
_seen
.
last
=
NULL
;
82
return
0;
83
}
84
85
/* The headless contract: with nothing installed, raising a message must be a silent no-op
86
* rather than a crash. ansel-cli and every unit test run in exactly this state. */
87
static
void
test_no_handler_is_silent
(
void
**
state
)
88
{
89
(
void
)
state
;
90
dt_metadata_set_notify_handler
(
NULL
);
91
dt_metadata_set_tags_changed_handler
(
NULL
);
92
93
dt_metadata_notify
(
DT_METADATA_NOTICE_TOAST
,
"%s"
,
"dropped"
);
94
dt_metadata_notify
(
DT_METADATA_NOTICE_MESSAGE
,
"dropped %d"
, 1);
95
dt_metadata_tags_changed
();
96
97
assert_int_equal
(
_seen
.
toasts
, 0);
98
assert_int_equal
(
_seen
.
messages
, 0);
99
assert_int_equal
(
_seen
.
tag_changes
, 0);
100
}
101
102
/* The two notice kinds are not interchangeable: one is a transient acknowledgement, the
103
* other the running commentary, and they land in different widgets. */
104
static
void
test_kinds_stay_distinct
(
void
**
state
)
105
{
106
(
void
)
state
;
107
dt_metadata_set_notify_handler
(
_record
);
108
109
dt_metadata_notify
(
DT_METADATA_NOTICE_TOAST
,
"Rating set to %s for %i image(s)"
,
"three"
, 12);
110
assert_int_equal
(
_seen
.
toasts
, 1);
111
assert_int_equal
(
_seen
.
messages
, 0);
112
assert_string_equal
(
_seen
.
last
,
"Rating set to three for 12 image(s)"
);
113
114
dt_metadata_notify
(
DT_METADATA_NOTICE_MESSAGE
,
"no images selected to apply rating"
);
115
assert_int_equal
(
_seen
.
toasts
, 1);
116
assert_int_equal
(
_seen
.
messages
, 1);
117
assert_string_equal
(
_seen
.
last
,
"no images selected to apply rating"
);
118
}
119
120
/* Removing the handler must actually remove it -- a stale pointer here would outlive the
121
* GUI it belongs to. */
122
static
void
test_handler_can_be_removed
(
void
**
state
)
123
{
124
(
void
)
state
;
125
dt_metadata_set_notify_handler
(
_record
);
126
dt_metadata_notify
(
DT_METADATA_NOTICE_MESSAGE
,
"heard"
);
127
assert_int_equal
(
_seen
.
messages
, 1);
128
129
dt_metadata_set_notify_handler
(
NULL
);
130
dt_metadata_notify
(
DT_METADATA_NOTICE_MESSAGE
,
"not heard"
);
131
assert_int_equal
(
_seen
.
messages
, 1);
132
assert_string_equal
(
_seen
.
last
,
"heard"
);
133
}
134
135
/* The tag-changed notification carries no payload on purpose: every consumer re-reads. */
136
static
void
test_tags_changed_fires_each_time
(
void
**
state
)
137
{
138
(
void
)
state
;
139
dt_metadata_set_tags_changed_handler
(
_record_tag_change
);
140
141
dt_metadata_tags_changed
();
142
dt_metadata_tags_changed
();
143
assert_int_equal
(
_seen
.
tag_changes
, 2);
144
145
dt_metadata_set_tags_changed_handler
(
NULL
);
146
dt_metadata_tags_changed
();
147
assert_int_equal
(
_seen
.
tag_changes
, 2);
148
}
149
150
/* The two channels are independent: installing one must not arm or silence the other. */
151
static
void
test_channels_are_independent
(
void
**
state
)
152
{
153
(
void
)
state
;
154
dt_metadata_set_notify_handler
(
_record
);
155
156
dt_metadata_tags_changed
();
// no tags handler yet
157
assert_int_equal
(
_seen
.
tag_changes
, 0);
158
159
dt_metadata_set_tags_changed_handler
(
_record_tag_change
);
160
dt_metadata_set_notify_handler
(
NULL
);
161
162
dt_metadata_notify
(
DT_METADATA_NOTICE_TOAST
,
"dropped"
);
163
dt_metadata_tags_changed
();
164
assert_int_equal
(
_seen
.
toasts
, 0);
165
assert_int_equal
(
_seen
.
tag_changes
, 1);
166
}
167
168
int
main
(
void
)
169
{
170
const
struct
CMUnitTest
tests
[] = {
171
cmocka_unit_test_setup_teardown
(
test_no_handler_is_silent
,
_setup
,
_teardown
),
172
cmocka_unit_test_setup_teardown
(
test_kinds_stay_distinct
,
_setup
,
_teardown
),
173
cmocka_unit_test_setup_teardown
(
test_handler_can_be_removed
,
_setup
,
_teardown
),
174
cmocka_unit_test_setup_teardown
(
test_tags_changed_fires_each_time
,
_setup
,
_teardown
),
175
cmocka_unit_test_setup_teardown
(
test_channels_are_independent
,
_setup
,
_teardown
),
176
};
177
return
cmocka_run_group_tests
(
tests
,
NULL
,
NULL
);
178
}
void
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
kind
static const dt_adaptation_t kind
Definition
chromatic_adaptation.h:125
L
const float L
Definition
colorspaces_inline_conversions.h:494
dt_metadata_set_tags_changed_handler
void dt_metadata_set_tags_changed_handler(dt_metadata_tags_changed_handler_t handler)
Definition
metadata/notify.c:52
dt_metadata_set_notify_handler
void dt_metadata_set_notify_handler(dt_metadata_notify_handler_t handler)
Install the handler, or NULL to remove it. Messages raised with none installed are dropped.
Definition
metadata/notify.c:30
dt_metadata_tags_changed
void dt_metadata_tags_changed(void)
Raise it. Internal to the module.
Definition
metadata/notify.c:57
dt_metadata_notify
void dt_metadata_notify(const dt_metadata_notice_t kind, const char *format,...)
Definition
metadata/notify.c:35
notify.h
Everything this module says to the outside world: messages for the user, and the fact that the tag vo...
dt_metadata_notice_t
dt_metadata_notice_t
Which affordance the message belongs in. The two are not interchangeable, and the module knows which ...
Definition
metadata/notify.h:48
DT_METADATA_NOTICE_TOAST
@ DT_METADATA_NOTICE_TOAST
Definition
metadata/notify.h:51
DT_METADATA_NOTICE_MESSAGE
@ DT_METADATA_NOTICE_MESSAGE
Definition
metadata/notify.h:54
state
const float uint32_t state[4]
Definition
src/iop/noise_generator.h:75
_seen_t
Definition
test_metadata_notify.c:46
_seen_t::tag_changes
int tag_changes
Definition
test_metadata_notify.c:49
_seen_t::last
gchar * last
Definition
test_metadata_notify.c:50
_seen_t::messages
int messages
Definition
test_metadata_notify.c:48
_seen_t::toasts
int toasts
Definition
test_metadata_notify.c:47
_record
static void _record(const dt_metadata_notice_t kind, const char *message)
Definition
test_metadata_notify.c:55
test_channels_are_independent
static void test_channels_are_independent(void **state)
Definition
test_metadata_notify.c:151
test_no_handler_is_silent
static void test_no_handler_is_silent(void **state)
Definition
test_metadata_notify.c:87
test_kinds_stay_distinct
static void test_kinds_stay_distinct(void **state)
Definition
test_metadata_notify.c:104
_setup
static int _setup(void **state)
Definition
test_metadata_notify.c:68
_teardown
static int _teardown(void **state)
Definition
test_metadata_notify.c:75
main
int main(void)
Definition
test_metadata_notify.c:168
_record_tag_change
static void _record_tag_change(void)
Definition
test_metadata_notify.c:63
test_tags_changed_fires_each_time
static void test_tags_changed_fires_each_time(void **state)
Definition
test_metadata_notify.c:136
_seen
static _seen_t _seen
Definition
test_metadata_notify.c:53
test_handler_can_be_removed
static void test_handler_can_be_removed(void **state)
Definition
test_metadata_notify.c:122
src
tests
unittests
test_metadata_notify.c
Generated by
1.9.8