2 * Copyright © 2020 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
33 #include <sys/types.h>
35 #include "xkbcommon/xkbregistry.h"
39 #define NO_VARIANT NULL
49 const char *name; /* required */
51 const char *description;
55 const char *name; /* required */
58 const char *description;
59 const char *iso639[3]; /* language list (iso639 three letter codes), 3 is enough for our test */
60 const char *iso3166[3]; /* country list (iso3166 two letter codes), 3 is enough for our tests */
65 const char *description;
68 struct test_option_group {
70 const char *description;
71 bool allow_multiple_selection;
73 struct test_option options[10];
77 fprint_config_item(FILE *fp,
81 const char *description,
82 const char * const iso639[3],
83 const char * const iso3166[3])
85 fprintf(fp, " <configItem>\n"
86 " <name>%s</name>\n", name);
88 fprintf(fp, " <shortDescription>%s</shortDescription>\n", brief);
90 fprintf(fp, " <description>%s</description>\n", description);
92 fprintf(fp, " <vendor>%s</vendor>\n", vendor);
93 if (iso3166 && iso3166[0]) {
94 fprintf(fp, " <countryList>\n");
95 for (int i = 0; i < 3; i++) {
96 const char *iso = iso3166[i];
99 fprintf(fp, " <iso3166Id>%s</iso3166Id>\n", iso);
101 fprintf(fp, " </countryList>\n");
103 if (iso639 && iso639[0]) {
104 fprintf(fp, " <languageList>\n");
105 for (int i = 0; i < 3; i++) {
106 const char *iso = iso639[i];
109 fprintf(fp, " <iso639Id>%s</iso639Id>\n", iso);
111 fprintf(fp, " </languageList>\n");
114 fprintf(fp, " </configItem>\n");
118 * Create a directory populated with a rules/<ruleset>.xml that contains the
121 * @return the XKB base directory
124 test_create_rules(const char *ruleset,
125 const struct test_model *test_models,
126 const struct test_layout *test_layouts,
127 const struct test_option_group *test_groups)
129 static int iteration;
135 tmpdir = asprintf_safe("/tmp/%s.%d.XXXXXX", ruleset, iteration++);
137 assert(mkdtemp(tmpdir) == tmpdir);
139 rc = snprintf_safe(buf, sizeof(buf), "%s/rules", tmpdir);
141 rc = mkdir(buf, 0777);
143 rc = snprintf_safe(buf, sizeof(buf), "%s/rules/%s.xml", tmpdir, ruleset);
146 fp = fopen(buf, "w");
150 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
151 "<!DOCTYPE xkbConfigRegistry SYSTEM \"xkb.dtd\">\n"
152 "<xkbConfigRegistry version=\"1.1\">\n");
155 fprintf(fp, "<modelList>\n");
157 for (const struct test_model *m = test_models; m->name; m++) {
158 fprintf(fp, "<model>\n");
159 fprint_config_item(fp, m->name, m->vendor, NULL, m->description, NULL, NULL);
160 fprintf(fp, "</model>\n");
162 fprintf(fp, "</modelList>\n");
166 const struct test_layout *l, *next;
168 fprintf(fp, "<layoutList>\n");
173 assert(l->variant == NULL);
176 fprintf(fp, "<layout>\n");
177 fprint_config_item(fp, l->name, NULL, l->brief, l->description, l->iso639, l->iso3166);
179 if (next->name && streq(next->name, l->name)) {
180 fprintf(fp, "<variantList>\n");
182 fprintf(fp, "<variant>\n");
183 fprint_config_item(fp, next->variant, NULL, next->brief, next->description, next->iso639, next->iso3166);
184 fprintf(fp, "</variant>\n");
187 } while (next->name && streq(next->name, l->name));
188 fprintf(fp, "</variantList>\n");
190 fprintf(fp, "</layout>\n");
193 fprintf(fp, "</layoutList>\n");
197 fprintf(fp, "<optionList>\n");
199 for (const struct test_option_group *g = test_groups; g->name; g++) {
200 fprintf(fp, "<group allowMultipleSelection=\"%s\">\n",
201 g->allow_multiple_selection ? "true" : "false");
202 fprint_config_item(fp, g->name, NULL, NULL, g->description, NULL, NULL);
203 for (const struct test_option *o = g->options; o->name; o++) {
204 fprintf(fp, " <option>\n");
205 fprint_config_item(fp, o->name, NULL, NULL, o->description, NULL, NULL);
206 fprintf(fp, "</option>\n");
208 fprintf(fp, "</group>\n");
210 fprintf(fp, "</optionList>\n");
213 fprintf(fp, "</xkbConfigRegistry>\n");
220 test_remove_rules(char *basedir, const char *ruleset)
225 rc = snprintf_safe(path, sizeof(path), "%s/rules/%s.xml", basedir,
229 rc = snprintf_safe(path, sizeof(path), "%s/xkb/rules", basedir);
236 static struct rxkb_context *
237 test_setup_context_for(const char *ruleset,
238 struct test_model *system_models,
239 struct test_model *user_models,
240 struct test_layout *system_layouts,
241 struct test_layout *user_layouts,
242 struct test_option_group *system_groups,
243 struct test_option_group *user_groups)
245 char *sysdir = NULL, *userdir = NULL;
246 struct rxkb_context *ctx;
248 sysdir = test_create_rules(ruleset, system_models, system_layouts,
250 if (user_models || user_layouts || user_groups)
251 userdir = test_create_rules(ruleset, user_models, user_layouts,
254 ctx = rxkb_context_new(RXKB_CONTEXT_NO_DEFAULT_INCLUDES);
257 assert(rxkb_context_include_path_append(ctx, userdir));
258 assert(rxkb_context_include_path_append(ctx, sysdir));
259 assert(rxkb_context_parse(ctx, ruleset));
261 test_remove_rules(sysdir, ruleset);
263 test_remove_rules(userdir, ruleset);
268 static struct rxkb_context *
269 test_setup_context(struct test_model *system_models,
270 struct test_model *user_models,
271 struct test_layout *system_layouts,
272 struct test_layout *user_layouts,
273 struct test_option_group *system_groups,
274 struct test_option_group *user_groups)
276 const char *ruleset = "xkbtests";
277 return test_setup_context_for(ruleset, system_models,
278 user_models, system_layouts,
279 user_layouts, system_groups,
283 static struct rxkb_model *
284 fetch_model(struct rxkb_context *ctx, const char *model)
286 struct rxkb_model *m = rxkb_model_first(ctx);
288 if (streq(rxkb_model_get_name(m), model))
289 return rxkb_model_ref(m);
290 m = rxkb_model_next(m);
296 find_model(struct rxkb_context *ctx, const char *model)
298 struct rxkb_model *m = fetch_model(ctx, model);
304 find_models(struct rxkb_context *ctx, ...)
312 name = va_arg(args, const char *);
314 assert(++idx < 20); /* safety guard */
315 if (!find_model(ctx, name))
317 name = va_arg(args, const char *);
326 static struct rxkb_layout *
327 fetch_layout(struct rxkb_context *ctx, const char *layout, const char *variant)
329 struct rxkb_layout *l = rxkb_layout_first(ctx);
331 const char *v = rxkb_layout_get_variant(l);
333 if (streq(rxkb_layout_get_name(l), layout) &&
334 ((v == NULL && variant == NULL) ||
335 (v != NULL && variant != NULL && streq(v, variant))))
336 return rxkb_layout_ref(l);
337 l = rxkb_layout_next(l);
343 find_layout(struct rxkb_context *ctx, const char *layout, const char *variant)
345 struct rxkb_layout *l = fetch_layout(ctx, layout, variant);
346 rxkb_layout_unref(l);
351 find_layouts(struct rxkb_context *ctx, ...)
354 const char *name, *variant;
359 name = va_arg(args, const char *);
360 variant = va_arg(args, const char *);
362 assert(++idx < 20); /* safety guard */
363 if (!find_layout(ctx, name, variant))
365 name = va_arg(args, const char *);
367 variant = va_arg(args, const char *);
376 static struct rxkb_option_group *
377 fetch_option_group(struct rxkb_context *ctx, const char *grp)
379 struct rxkb_option_group *g = rxkb_option_group_first(ctx);
381 if (streq(grp, rxkb_option_group_get_name(g)))
382 return rxkb_option_group_ref(g);
383 g = rxkb_option_group_next(g);
389 find_option_group(struct rxkb_context *ctx, const char *grp)
391 struct rxkb_option_group *g = fetch_option_group(ctx, grp);
392 rxkb_option_group_unref(g);
396 static struct rxkb_option *
397 fetch_option(struct rxkb_context *ctx, const char *grp, const char *opt)
399 struct rxkb_option_group *g = rxkb_option_group_first(ctx);
401 if (streq(grp, rxkb_option_group_get_name(g))) {
402 struct rxkb_option *o = rxkb_option_first(g);
405 if (streq(opt, rxkb_option_get_name(o)))
406 return rxkb_option_ref(o);
407 o = rxkb_option_next(o);
410 g = rxkb_option_group_next(g);
416 find_option(struct rxkb_context *ctx, const char *grp, const char *opt)
418 struct rxkb_option *o = fetch_option(ctx, grp, opt);
419 rxkb_option_unref(o);
424 find_options(struct rxkb_context *ctx, ...)
427 const char *grp, *opt;
432 grp = va_arg(args, const char *);
433 opt = va_arg(args, const char *);
435 assert(++idx < 20); /* safety guard */
436 if (!find_option(ctx, grp, opt))
438 grp = va_arg(args, const char *);
440 opt = va_arg(args, const char *);
450 cmp_models(struct test_model *tm, struct rxkb_model *m)
455 if (!streq(tm->name, rxkb_model_get_name(m)))
458 if (!streq_null(tm->vendor, rxkb_model_get_vendor(m)))
461 if (!streq_null(tm->description, rxkb_model_get_description(m)))
468 cmp_layouts(struct test_layout *tl, struct rxkb_layout *l)
470 struct rxkb_iso3166_code *iso3166 = NULL;
471 struct rxkb_iso639_code *iso639 = NULL;
476 if (!streq(tl->name, rxkb_layout_get_name(l)))
479 if (!streq_null(tl->variant, rxkb_layout_get_variant(l)))
482 if (!streq_null(tl->brief, rxkb_layout_get_brief(l)))
485 if (!streq_null(tl->description, rxkb_layout_get_description(l)))
488 iso3166 = rxkb_layout_get_iso3166_first(l);
489 for (size_t i = 0; i < sizeof(tl->iso3166); i++) {
490 const char *iso = tl->iso3166[i];
491 if (iso == NULL && iso3166 == NULL)
494 if (!streq_null(iso, rxkb_iso3166_code_get_code(iso3166)))
497 iso3166 = rxkb_iso3166_code_next(iso3166);
503 iso639 = rxkb_layout_get_iso639_first(l);
504 for (size_t i = 0; i < sizeof(tl->iso639); i++) {
505 const char *iso = tl->iso639[i];
506 if (iso == NULL && iso639 == NULL)
509 if (!streq_null(iso, rxkb_iso639_code_get_code(iso639)))
512 iso639 = rxkb_iso639_code_next(iso639);
522 cmp_options(struct test_option *to, struct rxkb_option *o)
527 if (!streq(to->name, rxkb_option_get_name(o)))
530 if (!streq_null(to->description, rxkb_option_get_description(o)))
542 cmp_option_groups(struct test_option_group *tg, struct rxkb_option_group *g,
545 struct rxkb_option *o;
546 struct test_option *to;
551 if (!streq(tg->name, rxkb_option_group_get_name(g)))
554 if (!streq_null(tg->description, rxkb_option_group_get_description(g)))
557 if (tg->allow_multiple_selection != rxkb_option_group_allows_multiple(g))
561 o = rxkb_option_first(g);
563 while (o && to->name) {
564 if (!cmp_options(to, o))
567 o = rxkb_option_next(o);
570 if (cmp == CMP_EXACT && (o || to->name))
577 test_load_basic(void)
579 struct test_model system_models[] = {
584 struct test_layout system_layouts[] = {
589 struct test_option_group system_groups[] = {
591 { {"grp1:1"}, {"grp1:2"} } },
592 {"grp2", NULL, false,
593 { {"grp2:1"}, {"grp2:2"} } },
596 struct rxkb_context *ctx;
598 ctx = test_setup_context(system_models, NULL,
599 system_layouts, NULL,
600 system_groups, NULL);
602 assert(find_models(ctx, "m1", "m2", NULL));
603 assert(find_layouts(ctx, "l1", NO_VARIANT,
605 assert(find_options(ctx, "grp1", "grp1:1",
608 "grp2", "grp2:2", NULL));
609 rxkb_context_unref(ctx);
615 struct test_model system_models[] = {
616 {"m1", "vendor1", "desc1"},
617 {"m2", "vendor2", "desc2"},
620 struct test_layout system_layouts[] = {
621 {"l1", NO_VARIANT, "lbrief1", "ldesc1"},
622 {"l1", "v1", "vbrief1", "vdesc1"},
623 {"l1", "v2", NULL, "vdesc2"},
626 struct test_option_group system_groups[] = {
627 {"grp1", "gdesc1", true,
628 { {"grp1:1", "odesc11"}, {"grp1:2", "odesc12"} } },
629 {"grp2", "gdesc2", false,
630 { {"grp2:1", "odesc21"}, {"grp2:2", "odesc22"} } },
633 struct rxkb_context *ctx;
634 struct rxkb_model *m;
635 struct rxkb_layout *l;
636 struct rxkb_option_group *g;
638 ctx = test_setup_context(system_models, NULL,
639 system_layouts, NULL,
640 system_groups, NULL);
642 m = fetch_model(ctx, "m1");
643 assert(cmp_models(&system_models[0], m));
646 m = fetch_model(ctx, "m2");
647 assert(cmp_models(&system_models[1], m));
650 l = fetch_layout(ctx, "l1", NO_VARIANT);
651 assert(cmp_layouts(&system_layouts[0], l));
652 rxkb_layout_unref(l);
654 l = fetch_layout(ctx, "l1", "v1");
655 assert(cmp_layouts(&system_layouts[1], l));
656 rxkb_layout_unref(l);
658 l = fetch_layout(ctx, "l1", "v2");
659 struct test_layout expected = {"l1", "v2", "lbrief1", "vdesc2"};
660 assert(cmp_layouts(&expected, l));
661 rxkb_layout_unref(l);
663 g = fetch_option_group(ctx, "grp1");
664 assert(cmp_option_groups(&system_groups[0], g, CMP_EXACT));
665 rxkb_option_group_unref(g);
667 g = fetch_option_group(ctx, "grp2");
668 assert(cmp_option_groups(&system_groups[1], g, CMP_EXACT));
669 rxkb_option_group_unref(g);
671 rxkb_context_unref(ctx);
675 test_load_languages(void)
677 struct test_model system_models[] = {
678 {"m1", "vendor1", "desc1"},
681 struct test_layout system_layouts[] = {
682 {"l1", NO_VARIANT, "lbrief1", "ldesc1",
683 .iso639 = { "abc", "def" },
684 .iso3166 = { "uv", "wx" }},
685 {"l1", "v1", "vbrief1", "vdesc1",
690 struct test_option_group system_groups[] = {
691 {"grp1", "gdesc1", true,
692 { {"grp1:1", "odesc11"}, {"grp1:2", "odesc12"} } },
695 struct rxkb_context *ctx;
696 struct rxkb_layout *l;
698 ctx = test_setup_context(system_models, NULL,
699 system_layouts, NULL,
700 system_groups, NULL);
702 l = fetch_layout(ctx, "l1", NO_VARIANT);
703 assert(cmp_layouts(&system_layouts[0], l));
704 rxkb_layout_unref(l);
706 l = fetch_layout(ctx, "l1", "v1");
707 assert(cmp_layouts(&system_layouts[1], l));
708 rxkb_layout_unref(l);
710 rxkb_context_unref(ctx);
714 test_load_invalid_languages(void)
716 struct test_model system_models[] = {
717 {"m1", "vendor1", "desc1"},
720 struct test_layout system_layouts[] = {
721 {"l1", NO_VARIANT, "lbrief1", "ldesc1",
722 .iso639 = { "ab", "def" },
723 .iso3166 = { "uvw", "xz" }},
726 struct test_option_group system_groups[] = {
727 {"grp1", "gdesc1", true,
728 { {"grp1:1", "odesc11"}, {"grp1:2", "odesc12"} } },
731 struct rxkb_context *ctx;
732 struct rxkb_layout *l;
733 struct rxkb_iso3166_code *iso3166;
734 struct rxkb_iso639_code *iso639;
736 ctx = test_setup_context(system_models, NULL,
737 system_layouts, NULL,
738 system_groups, NULL);
740 l = fetch_layout(ctx, "l1", NO_VARIANT);
741 /* uvw is invalid, we expect 2 letters, verify it was ignored */
742 iso3166 = rxkb_layout_get_iso3166_first(l);
743 assert(streq(rxkb_iso3166_code_get_code(iso3166), "xz"));
744 assert(rxkb_iso3166_code_next(iso3166) == NULL);
746 /* ab is invalid, we expect 3 letters, verify it was ignored */
747 iso639 = rxkb_layout_get_iso639_first(l);
748 assert(streq(rxkb_iso639_code_get_code(iso639), "def"));
749 assert(rxkb_iso639_code_next(iso639) == NULL);
750 rxkb_layout_unref(l);
752 rxkb_context_unref(ctx);
756 test_popularity(void)
758 struct test_layout system_layouts[] = {
763 struct rxkb_context *ctx;
764 struct rxkb_layout *l;
765 const char *ruleset = "xkbtests.extras";
768 dir = test_create_rules(ruleset, NULL, system_layouts, NULL);
769 ctx = rxkb_context_new(RXKB_CONTEXT_NO_DEFAULT_INCLUDES |
770 RXKB_CONTEXT_LOAD_EXOTIC_RULES);
772 assert(rxkb_context_include_path_append(ctx, dir));
773 /* Hack: rulest above generates xkbtests.extras.xml, loading "xkbtests"
774 * means the extras file counts as exotic */
775 assert(rxkb_context_parse(ctx, "xkbtests"));
777 l = fetch_layout(ctx, "l1", NO_VARIANT);
778 assert(rxkb_layout_get_popularity(l) == RXKB_POPULARITY_EXOTIC);
779 rxkb_layout_unref(l);
781 l = fetch_layout(ctx, "l1", "v1");
782 assert(rxkb_layout_get_popularity(l) == RXKB_POPULARITY_EXOTIC);
783 rxkb_layout_unref(l);
785 test_remove_rules(dir, ruleset);
786 rxkb_context_unref(ctx);
791 test_load_merge(void)
793 struct test_model system_models[] = {
794 {"m1", "vendor1", "desc1"},
795 {"m2", "vendor2", "desc2"},
798 struct test_model user_models[] = {
799 {"m3", "vendor3", "desc3"},
800 {"m4", "vendor4", "desc4"},
803 struct test_layout system_layouts[] = {
804 {"l1", NO_VARIANT, "lbrief1", "ldesc1"},
805 {"l1", "v1", "vbrief1", "vdesc1"},
808 struct test_layout user_layouts[] = {
809 {"l2", NO_VARIANT, "lbrief2", "ldesc2"},
810 {"l2", "v2", "vbrief2", "vdesc2"},
813 struct test_option_group system_groups[] = {
815 { {"grp1:1"}, {"grp1:2"} } },
816 {"grp2", NULL, false,
817 { {"grp2:1"}, {"grp2:2"} } },
820 struct test_option_group user_groups[] = {
822 { {"grp3:1"}, {"grp3:2"} } },
823 {"grp4", NULL, false,
824 { {"grp4:1"}, {"grp4:2"} } },
827 struct rxkb_context *ctx;
828 struct rxkb_model *m;
829 struct rxkb_layout *l;
830 struct rxkb_option_group *g;
832 ctx = test_setup_context(system_models, user_models,
833 system_layouts, user_layouts,
834 system_groups, user_groups);
836 assert(find_models(ctx, "m1", "m2", "m3", "m4", NULL));
837 assert(find_layouts(ctx, "l1", NO_VARIANT,
842 m = fetch_model(ctx, "m1");
843 assert(cmp_models(&system_models[0], m));
846 m = fetch_model(ctx, "m2");
847 assert(cmp_models(&system_models[1], m));
850 m = fetch_model(ctx, "m3");
851 assert(cmp_models(&user_models[0], m));
854 m = fetch_model(ctx, "m4");
855 assert(cmp_models(&user_models[1], m));
858 l = fetch_layout(ctx, "l1", NO_VARIANT);
859 assert(cmp_layouts(&system_layouts[0], l));
860 rxkb_layout_unref(l);
862 l = fetch_layout(ctx, "l1", "v1");
863 assert(cmp_layouts(&system_layouts[1], l));
864 rxkb_layout_unref(l);
866 l = fetch_layout(ctx, "l2", NO_VARIANT);
867 assert(cmp_layouts(&user_layouts[0], l));
868 rxkb_layout_unref(l);
870 l = fetch_layout(ctx, "l2", "v2");
871 assert(cmp_layouts(&user_layouts[1], l));
872 rxkb_layout_unref(l);
874 g = fetch_option_group(ctx, "grp1");
875 assert(cmp_option_groups(&system_groups[0], g, CMP_EXACT));
876 rxkb_option_group_unref(g);
878 g = fetch_option_group(ctx, "grp2");
879 assert(cmp_option_groups(&system_groups[1], g, CMP_EXACT));
880 rxkb_option_group_unref(g);
882 g = fetch_option_group(ctx, "grp3");
883 assert(cmp_option_groups(&user_groups[0], g, CMP_EXACT));
884 rxkb_option_group_unref(g);
886 g = fetch_option_group(ctx, "grp4");
887 assert(cmp_option_groups(&user_groups[1], g, CMP_EXACT));
888 rxkb_option_group_unref(g);
890 rxkb_context_unref(ctx);
894 test_load_merge_no_overwrite(void)
896 struct test_model system_models[] = {
897 {"m1", "vendor1", "desc1"},
898 {"m2", "vendor2", "desc2"},
901 struct test_model user_models[] = {
902 {"m1", "vendor3", "desc3"}, /* must not overwrite */
903 {"m4", "vendor4", "desc4"},
906 struct test_layout system_layouts[] = {
907 {"l1", NO_VARIANT, "lbrief1", "ldesc1"},
908 {"l1", "v1", "vbrief1", "vdesc1"},
911 struct test_layout user_layouts[] = {
912 {"l2", NO_VARIANT, "lbrief2", "ldesc2"},
913 {"l2", "v2", "vbrief2", "vdesc2"},
914 {"l1", NO_VARIANT, "lbrief3", "ldesc3"}, /* must not overwrite */
915 {"l1", "v2", "vbrief3", "vdesc3"}, /* must not overwrite */
918 struct test_option_group system_groups[] = {
919 {"grp1", "gdesc1", true,
920 { {"grp1:1", "odesc11"}, {"grp1:2", "odesc12"} } },
921 {"grp2", "gdesc2", false,
922 { {"grp2:1", "odesc21"}, {"grp2:2", "odesc22"} } },
925 struct test_option_group user_groups[] = {
926 {"grp1", "XXXXX", false, /* must not overwrite */
927 { {"grp1:1", "YYYYYYY"}, /* must not overwrite */
928 {"grp1:3", "ZZZZZZ"} } }, /* append */
929 {"grp4", "gdesc4", false,
930 { {"grp4:1", "odesc41"}, {"grp4:2", "odesc42"} } },
933 struct rxkb_context *ctx;
934 struct rxkb_model *m;
935 struct rxkb_layout *l;
936 struct rxkb_option_group *g;
938 ctx = test_setup_context(system_models, user_models,
939 system_layouts, user_layouts,
940 system_groups, user_groups);
942 m = fetch_model(ctx, "m1");
943 assert(cmp_models(&system_models[0], m));
946 l = fetch_layout(ctx, "l1", NO_VARIANT);
947 assert(cmp_layouts(&system_layouts[0], l));
948 rxkb_layout_unref(l);
950 l = fetch_layout(ctx, "l1", "v1");
951 assert(cmp_layouts(&system_layouts[1], l));
952 rxkb_layout_unref(l);
954 assert(find_option(ctx, "grp1", "grp1:3"));
955 g = fetch_option_group(ctx, "grp1");
956 assert(cmp_option_groups(&system_groups[0], g, CMP_MATCHING_ONLY));
957 rxkb_option_group_unref(g);
959 rxkb_context_unref(ctx);
963 test_no_include_paths(void)
965 struct rxkb_context *ctx;
967 ctx = rxkb_context_new(RXKB_CONTEXT_NO_DEFAULT_INCLUDES);
969 assert(!rxkb_context_parse_default_ruleset(ctx));
971 rxkb_context_unref(ctx);
975 test_invalid_include(void)
977 struct rxkb_context *ctx;
979 ctx = rxkb_context_new(RXKB_CONTEXT_NO_DEFAULT_INCLUDES);
981 assert(!rxkb_context_include_path_append(ctx, "/foo/bar/baz/bat"));
982 assert(!rxkb_context_parse_default_ruleset(ctx));
984 rxkb_context_unref(ctx);
990 test_no_include_paths();
991 test_invalid_include();
995 test_load_merge_no_overwrite();
996 test_load_languages();
997 test_load_invalid_languages();