Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
test_tag_selection_metadata.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
23#include "testdb.h"
24
25#include "common/image.h" // UNKNOWN_IMAGE
26#include "metadata/tags.h" // DT_TF_CATEGORY
27
28
30{
31 (void)state;
32 const int32_t film = testdb_make_film("/testdb/sel");
33 const int32_t a = testdb_make_image(film, "a.raw");
34 const int32_t b = testdb_make_image(film, "b.raw");
35 const int32_t c = testdb_make_image(film, "c.raw");
36 assert_true(a > 0 && b > a && c > b);
37
38 // nothing selected: the sentinel, not a garbage id
41
42 // selection order must not matter: the answer is the LOWEST id, which the unordered
43 // scan this replaced produced only because imgid is the table's INTEGER PRIMARY KEY
48
49 // get_all comes back ascending, whatever order the ids went in
53 assert_int_equal(GPOINTER_TO_INT(all->next->data), b);
54 assert_int_equal(GPOINTER_TO_INT(all->next->next->data), c);
56
60}
61
62static void test_tag_agreement(void **state)
63{
64 (void)state;
65 const int32_t film = testdb_make_film("/testdb/tags");
66 const int32_t a = testdb_make_image(film, "a.raw");
67 const int32_t b = testdb_make_image(film, "b.raw");
68 assert_true(a > 0 && b > 0);
70
71 const guint shared = dt_tag_repository_insert("alpha");
72 const guint only_a = dt_tag_repository_insert("beta");
73 const guint category = dt_tag_repository_insert("group|c");
74 assert_true(shared > 0 && only_a > 0 && category > 0);
76
77 // a tag on only one image breaks tag agreement; the shared category keeps its own
83
88
89 // complete the pair and both agree
94
95 // the darktable| namespace is bookkeeping, not a keyword: it must not break agreement
96 const guint internal = dt_tag_repository_insert("darktable|style|x");
101
102 // the empty set agrees vacuously
106
108}
109
116
117static void _collect_meta(void *user_data, const int keyid, const char *value, const uint32_t count)
118{
119 _meta_collect_t *c = (_meta_collect_t *)user_data;
120 c->rows++;
121 if(keyid == 0 && !g_strcmp0(value, "same-creator")) c->shared_key_count = (int)count;
122 if(keyid == 2) c->split_key_rows++;
123}
124
126{
127 (void)state;
128 const int32_t film = testdb_make_film("/testdb/meta");
129 const int32_t a = testdb_make_image(film, "a.raw");
130 const int32_t b = testdb_make_image(film, "b.raw");
131 assert_true(a > 0 && b > 0);
132
133 const dt_metadata_row_t rows[] = {
134 { .imgid = a, .keyid = 0, .value = "same-creator" },
135 { .imgid = b, .keyid = 0, .value = "same-creator" },
136 { .imgid = a, .keyid = 2, .value = "title-a" },
137 { .imgid = b, .keyid = 2, .value = "title-b" },
138 };
140
144
145 _meta_collect_t c = { 0 };
147 assert_int_equal(c.rows, 3); // one shared value + two split values
148 assert_int_equal(c.shared_key_count, 2); // both selected images carry it -> they agree
149 assert_int_equal(c.split_key_rows, 2); // two values at count 1 -> they disagree
150
152}
153
#define FALSE
Definition ashift_lsd.c:158
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
#define UNKNOWN_IMAGE
Definition image.h:77
void dt_metadata_repository_foreach_selected(dt_metadata_repository_selected_cb cb, void *user_data)
Every distinct (key, value) pair across main.selected_images, ordered by value.
void dt_metadata_repository_add(const dt_metadata_row_t *rows, const size_t count)
Insert count rows as a single multi-VALUES statement.
void dt_selection_repository_select(const int32_t imgid)
Add imgid to the selection. Selecting an already-selected image does nothing.
void dt_selection_repository_clear(void)
Empty the selection.
void dt_selection_repository_deselect(const int32_t imgid)
Remove imgid from the selection.
GList * dt_selection_repository_get_all(void)
Every selected image id, GINT_TO_POINTER, ASCENDING. Free with g_list_free().
int32_t dt_selection_repository_get_lowest_id(void)
The lowest selected image id, or UNKNOWN_IMAGE when nothing is selected.
static const dt_aligned_pixel_simd_t value
Definition simd.h:144
const float uint32_t state[4]
gboolean dt_tag_repository_attach(const guint tagid, const int32_t imgid)
Attach tagid to imgid, at the end of the tag order.
void dt_tag_repository_get_agreement(GList *imgids, gboolean *same_tags, gboolean *same_categories)
Do all of imgids carry exactly the same tags? The same categories?
void dt_tag_repository_set_flags(const guint tagid, const gint flags)
Replace the flags word of tagid.
guint dt_tag_repository_insert(const char *name)
Insert a tag named name and return its new id, or 0 on failure.
@ DT_TF_CATEGORY
Definition tags.h:64
static void _collect_meta(void *user_data, const int keyid, const char *value, const uint32_t count)
static void test_selection_lowest_id(void **state)
int main(void)
static void test_metadata_foreach_selected(void **state)
static void test_tag_agreement(void **state)
Shared fixture for the src/database repository tests.
static int testdb_setup(void **state)
Definition testdb.h:55
static int32_t testdb_make_film(const char *folder)
Definition testdb.h:85
static int testdb_teardown(void **state)
Definition testdb.h:66
static int32_t testdb_make_image(const int32_t film_id, const char *filename)
Definition testdb.h:92