1 #include "../../include/sane/config.h"
2
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <assert.h>
10
11 /* sane includes for the sanei functions called */
12 #include "../include/sane/sane.h"
13 #include "../include/sane/saneopts.h"
14 #include "../include/sane/sanei.h"
15
16 static SANE_Option_Descriptor none_opt = {
17 SANE_NAME_SCAN_TL_X,
18 SANE_TITLE_SCAN_TL_X,
19 SANE_DESC_SCAN_TL_X,
20 SANE_TYPE_INT,
21 SANE_UNIT_NONE,
22 sizeof (SANE_Word),
23 0,
24 SANE_CONSTRAINT_NONE,
25 {NULL}
26 };
27
28
29 static SANE_Option_Descriptor none_bool_opt = {
30 SANE_NAME_SCAN_TL_X,
31 SANE_TITLE_SCAN_TL_X,
32 SANE_DESC_SCAN_TL_X,
33 SANE_TYPE_BOOL,
34 SANE_UNIT_NONE,
35 sizeof (SANE_Word),
36 0,
37 SANE_CONSTRAINT_NONE,
38 {NULL}
39 };
40
41 /* range for int constraint */
42 static const SANE_Range int_range = {
43 3, /* minimum */
44 18, /* maximum */
45 3 /* quantization */
46 };
47
48 /* range for sane fixed constraint */
49 static const SANE_Range fixed_range = {
50 SANE_FIX(1.0), /* minimum */
51 SANE_FIX(431.8), /* maximum */
52 SANE_FIX(0.01) /* quantization */
53 };
54
55 static SANE_Option_Descriptor int_opt = {
56 SANE_NAME_SCAN_TL_X,
57 SANE_TITLE_SCAN_TL_X,
58 SANE_DESC_SCAN_TL_X,
59 SANE_TYPE_FIXED,
60 SANE_UNIT_MM,
61 sizeof (SANE_Word),
62 0,
63 SANE_CONSTRAINT_RANGE,
64 {NULL}
65 };
66
67 static SANE_Option_Descriptor fixed_opt = {
68 SANE_NAME_SCAN_TL_X,
69 SANE_TITLE_SCAN_TL_X,
70 SANE_DESC_SCAN_TL_X,
71 SANE_TYPE_FIXED,
72 SANE_UNIT_MM,
73 sizeof (SANE_Word),
74 0,
75 SANE_CONSTRAINT_RANGE,
76 {NULL}
77 };
78
79 #define ARRAY_SIZE 7
80
81 static SANE_Option_Descriptor array_opt = {
82 SANE_NAME_SCAN_TL_X,
83 SANE_TITLE_SCAN_TL_X,
84 SANE_DESC_SCAN_TL_X,
85 SANE_TYPE_FIXED,
86 SANE_UNIT_MM,
87 sizeof (SANE_Word) * ARRAY_SIZE,
88 0,
89 SANE_CONSTRAINT_RANGE,
90 {NULL}
91 };
92
93 #define WORD_SIZE 9
94 static const SANE_Int dpi_list[] =
95 { WORD_SIZE - 1, 100, 200, 300, 400, 500, 600, 700, 800 };
96
97 static SANE_Option_Descriptor word_array_opt = {
98 SANE_NAME_SCAN_RESOLUTION,
99 SANE_TITLE_SCAN_RESOLUTION,
100 SANE_DESC_SCAN_RESOLUTION,
101 SANE_TYPE_INT,
102 SANE_UNIT_DPI,
103 sizeof (SANE_Word) * WORD_SIZE,
104 100,
105 SANE_CONSTRAINT_WORD_LIST,
106 {NULL}
107 };
108
109 static const SANE_String_Const string_list[] = {
110 SANE_VALUE_SCAN_MODE_LINEART,
111 SANE_VALUE_SCAN_MODE_HALFTONE,
112 SANE_VALUE_SCAN_MODE_GRAY,
113 "linelength",
114 0
115 };
116
117 static SANE_Option_Descriptor string_array_opt = {
118 SANE_NAME_SCAN_MODE,
119 SANE_TITLE_SCAN_MODE,
120 SANE_DESC_SCAN_MODE,
121 SANE_TYPE_STRING,
122 SANE_UNIT_NONE,
123 8,
124 0,
125 SANE_CONSTRAINT_STRING_LIST,
126 {NULL}
127 };
128
129
130 /******************************/
131 /* start of tests definitions */
132 /******************************/
133
134 /*
135 * constrained int
136 */
137 static void
min_int_value(void)138 min_int_value (void)
139 {
140 SANE_Int value = int_range.min;
141 SANE_Word info = 0;
142 SANE_Status status;
143
144 status = sanei_constrain_value (&int_opt, &value, &info);
145
146 /* check results */
147 assert (status == SANE_STATUS_GOOD);
148 assert (info == 0);
149 assert (value == int_range.min);
150 }
151
152 static void
max_int_value(void)153 max_int_value (void)
154 {
155 SANE_Int value = int_range.max;
156 SANE_Word info = 0;
157 SANE_Status status;
158
159 status = sanei_constrain_value (&int_opt, &value, &info);
160
161 /* check results */
162 assert (status == SANE_STATUS_GOOD);
163 assert (info == 0);
164 assert (value == int_range.max);
165 }
166
167 static void
below_min_int_value(void)168 below_min_int_value (void)
169 {
170 SANE_Int value = int_range.min - 1;
171 SANE_Word info = 0;
172 SANE_Status status;
173
174 status = sanei_constrain_value (&int_opt, &value, &info);
175
176 /* check results */
177 assert (status == SANE_STATUS_GOOD);
178 assert (info == SANE_INFO_INEXACT);
179 assert (value == int_range.min);
180 }
181
182 /* rounded to lower value */
183 static void
quant1_int_value(void)184 quant1_int_value (void)
185 {
186 SANE_Int value = int_range.min + 1;
187 SANE_Word info = 0;
188 SANE_Status status;
189
190 status = sanei_constrain_value (&int_opt, &value, &info);
191
192 /* check results */
193 assert (status == SANE_STATUS_GOOD);
194 assert (info == SANE_INFO_INEXACT);
195 assert (value == int_range.min);
196 }
197
198 /* rounded to higher value */
199 static void
quant2_int_value(void)200 quant2_int_value (void)
201 {
202 SANE_Int value = int_range.min + int_range.quant - 1;
203 SANE_Word info = 0;
204 SANE_Status status;
205
206 status = sanei_constrain_value (&int_opt, &value, &info);
207
208 /* check results */
209 assert (status == SANE_STATUS_GOOD);
210 assert (info == SANE_INFO_INEXACT);
211 assert (value == int_range.min + int_range.quant);
212 }
213
214 static void
in_range_int_value(void)215 in_range_int_value (void)
216 {
217 SANE_Int value = int_range.min + int_range.quant;
218 SANE_Word info = 0;
219 SANE_Status status;
220
221 status = sanei_constrain_value (&int_opt, &value, &info);
222
223 /* check results */
224 assert (status == SANE_STATUS_GOOD);
225 assert (info == 0);
226 assert (value == int_range.min + int_range.quant);
227 }
228
229 static void
above_max_int_value(void)230 above_max_int_value (void)
231 {
232 SANE_Int value = int_range.max + 1;
233 SANE_Word info = 0;
234 SANE_Status status;
235
236 status = sanei_constrain_value (&int_opt, &value, &info);
237
238 /* check results */
239 assert (status == SANE_STATUS_GOOD);
240 assert (info == SANE_INFO_INEXACT);
241 assert (value == int_range.max);
242 }
243
244 /*
245 * constrained fixed value
246 */
247 static void
min_fixed_value(void)248 min_fixed_value (void)
249 {
250 SANE_Int value = fixed_range.min;
251 SANE_Word info = 0;
252 SANE_Status status;
253
254 status = sanei_constrain_value (&fixed_opt, &value, &info);
255
256 /* check results */
257 assert (status == SANE_STATUS_GOOD);
258 assert (info == 0);
259 assert (value == fixed_range.min);
260 }
261
262 static void
max_fixed_value(void)263 max_fixed_value (void)
264 {
265 SANE_Int value = fixed_range.max;
266 SANE_Word info = 0;
267 SANE_Status status;
268
269 status = sanei_constrain_value (&fixed_opt, &value, &info);
270
271 /* check results */
272 assert (status == SANE_STATUS_GOOD);
273 assert (info == 0);
274 assert (value == fixed_range.max);
275 }
276
277 static void
below_min_fixed_value(void)278 below_min_fixed_value (void)
279 {
280 SANE_Int value = fixed_range.min - 1;
281 SANE_Word info = 0;
282 SANE_Status status;
283
284 status = sanei_constrain_value (&fixed_opt, &value, &info);
285
286 /* check results */
287 assert (status == SANE_STATUS_GOOD);
288 assert (info == SANE_INFO_INEXACT);
289 assert (value == fixed_range.min);
290 }
291
292 /* rounded to lower value */
293 static void
quant1_fixed_value(void)294 quant1_fixed_value (void)
295 {
296 SANE_Int value = fixed_range.min + fixed_range.quant/3;
297 SANE_Word info = 0;
298 SANE_Status status;
299
300 status = sanei_constrain_value (&fixed_opt, &value, &info);
301
302 /* check results */
303 assert (status == SANE_STATUS_GOOD);
304 assert (info == SANE_INFO_INEXACT);
305 assert (value == fixed_range.min);
306 }
307
308 /* rounded to higher value */
309 static void
quant2_fixed_value(void)310 quant2_fixed_value (void)
311 {
312 SANE_Int value = fixed_range.min + fixed_range.quant - fixed_range.quant/3;
313 SANE_Word info = 0;
314 SANE_Status status;
315
316 status = sanei_constrain_value (&fixed_opt, &value, &info);
317
318 /* check results */
319 assert (status == SANE_STATUS_GOOD);
320 assert (info == SANE_INFO_INEXACT);
321 assert (value == fixed_range.min + fixed_range.quant);
322 }
323
324 static void
in_range_fixed_value(void)325 in_range_fixed_value (void)
326 {
327 SANE_Int value = fixed_range.min + fixed_range.quant;
328 SANE_Word info = 0;
329 SANE_Status status;
330
331 status = sanei_constrain_value (&fixed_opt, &value, &info);
332
333 /* check results */
334 assert (status == SANE_STATUS_GOOD);
335 assert (info == 0);
336 assert (value == fixed_range.min + fixed_range.quant);
337 }
338
339 static void
above_max_fixed_value(void)340 above_max_fixed_value (void)
341 {
342 SANE_Int value = fixed_range.max + 1;
343 SANE_Word info = 0;
344 SANE_Status status;
345
346 status = sanei_constrain_value (&fixed_opt, &value, &info);
347
348 /* check results */
349 assert (status == SANE_STATUS_GOOD);
350 assert (info == SANE_INFO_INEXACT);
351 assert (value == fixed_range.max);
352 }
353
354
355 static void
above_max_word(void)356 above_max_word (void)
357 {
358 SANE_Word value = 25000;
359 SANE_Word info = 0;
360 SANE_Status status;
361
362 status = sanei_constrain_value (&word_array_opt, &value, &info);
363
364 /* check results */
365 assert (status == SANE_STATUS_GOOD);
366 assert (info == SANE_INFO_INEXACT);
367 assert (value == 800);
368 }
369
370
371 static void
below_max_word(void)372 below_max_word (void)
373 {
374 SANE_Word value = 1;
375 SANE_Word info = 0;
376 SANE_Status status;
377
378 status = sanei_constrain_value (&word_array_opt, &value, &info);
379
380 /* check results */
381 assert (status == SANE_STATUS_GOOD);
382 assert (info == SANE_INFO_INEXACT);
383 assert (value == 100);
384 }
385
386 static void
closest_200_word(void)387 closest_200_word (void)
388 {
389 SANE_Word value = 249;
390 SANE_Word info = 0;
391 SANE_Status status;
392
393 status = sanei_constrain_value (&word_array_opt, &value, &info);
394
395 /* check results */
396 assert (status == SANE_STATUS_GOOD);
397 assert (info == SANE_INFO_INEXACT);
398 assert (value == 200);
399 }
400
401
402 static void
closest_300_word(void)403 closest_300_word (void)
404 {
405 SANE_Word value = 251;
406 SANE_Word info = 0;
407 SANE_Status status;
408
409 status = sanei_constrain_value (&word_array_opt, &value, &info);
410
411 /* check results */
412 assert (status == SANE_STATUS_GOOD);
413 assert (info == SANE_INFO_INEXACT);
414 assert (value == 300);
415 }
416
417
418 static void
exact_400_word(void)419 exact_400_word (void)
420 {
421 SANE_Word value = 400;
422 SANE_Word info = 0;
423 SANE_Status status;
424
425 status = sanei_constrain_value (&word_array_opt, &value, &info);
426
427 /* check results */
428 assert (status == SANE_STATUS_GOOD);
429 assert (info == 0);
430 assert (value == 400);
431 }
432
433 /*
434 * constrained int array
435 */
436 static void
min_int_array(void)437 min_int_array (void)
438 {
439 SANE_Int value[ARRAY_SIZE];
440 SANE_Word info = 0;
441 SANE_Status status;
442 int i;
443
444 for (i = 0; i < ARRAY_SIZE; i++)
445 {
446 value[i] = int_range.min;
447 }
448 status = sanei_constrain_value (&array_opt, value, &info);
449
450 /* check results */
451 assert (status == SANE_STATUS_GOOD);
452 assert (info == 0);
453 for (i = 0; i < ARRAY_SIZE; i++)
454 {
455 assert (value[i] == int_range.min);
456 }
457 }
458
459 static void
max_int_array(void)460 max_int_array (void)
461 {
462 SANE_Int value[ARRAY_SIZE];
463 SANE_Word info = 0;
464 SANE_Status status;
465 int i;
466
467 for (i = 0; i < ARRAY_SIZE; i++)
468 {
469 value[i] = int_range.max;
470 }
471
472 status = sanei_constrain_value (&array_opt, value, &info);
473
474 /* check results */
475 assert (status == SANE_STATUS_GOOD);
476 assert (info == 0);
477 for (i = 0; i < ARRAY_SIZE; i++)
478 {
479 assert (value[i] == int_range.max);
480 }
481 }
482
483 static void
below_min_int_array(void)484 below_min_int_array (void)
485 {
486 SANE_Int value[ARRAY_SIZE];
487 SANE_Word info = 0;
488 SANE_Status status;
489 int i;
490
491 for (i = 0; i < ARRAY_SIZE; i++)
492 {
493 value[i] = int_range.min - 1;
494 }
495
496 status = sanei_constrain_value (&array_opt, &value, &info);
497
498 /* check results */
499 assert (status == SANE_STATUS_GOOD);
500 assert (info == SANE_INFO_INEXACT);
501 for (i = 0; i < ARRAY_SIZE; i++)
502 {
503 assert (value[i] == int_range.min);
504 }
505 }
506
507 /* rounded to lower value */
508 static void
quant1_int_array(void)509 quant1_int_array (void)
510 {
511 SANE_Int value[ARRAY_SIZE];
512 SANE_Word info = 0;
513 SANE_Status status;
514 int i;
515
516 for (i = 0; i < ARRAY_SIZE; i++)
517 {
518 value[i] = int_range.min + 1;
519 }
520 status = sanei_constrain_value (&array_opt, &value, &info);
521
522 /* check results */
523 assert (status == SANE_STATUS_GOOD);
524 assert (info == SANE_INFO_INEXACT);
525 for (i = 0; i < ARRAY_SIZE; i++)
526 {
527 assert (value[i] == int_range.min);
528 }
529 }
530
531 /* rounded to higher value */
532 static void
quant2_int_array(void)533 quant2_int_array (void)
534 {
535 SANE_Int value[ARRAY_SIZE];
536 SANE_Word info = 0;
537 SANE_Status status;
538 int i;
539
540 for (i = 0; i < ARRAY_SIZE; i++)
541 {
542 value[i] = int_range.min + int_range.quant - 1;
543 }
544 status = sanei_constrain_value (&array_opt, &value, &info);
545
546 /* check results */
547 assert (status == SANE_STATUS_GOOD);
548 assert (info == SANE_INFO_INEXACT);
549 for (i = 0; i < ARRAY_SIZE; i++)
550 {
551 assert (value[i] == int_range.min + int_range.quant);
552 }
553 }
554
555 static void
in_range_int_array(void)556 in_range_int_array (void)
557 {
558 SANE_Int value[ARRAY_SIZE];
559 SANE_Word info = 0;
560 SANE_Status status;
561 int i;
562
563 for (i = 0; i < ARRAY_SIZE; i++)
564 {
565 value[i] = int_range.min + int_range.quant;
566 }
567
568 status = sanei_constrain_value (&array_opt, &value, &info);
569
570 /* check results */
571 assert (status == SANE_STATUS_GOOD);
572 assert (info == 0);
573 for (i = 0; i < ARRAY_SIZE; i++)
574 {
575 assert (value[i] == int_range.min + int_range.quant);
576 }
577 }
578
579 static void
above_max_int_array(void)580 above_max_int_array (void)
581 {
582 SANE_Int value[ARRAY_SIZE];
583 SANE_Word info = 0;
584 SANE_Status status;
585 int i;
586
587 for (i = 0; i < ARRAY_SIZE; i++)
588 {
589 value[i] = int_range.max + 1;
590 }
591 status = sanei_constrain_value (&array_opt, &value, &info);
592
593 /* check results */
594 assert (status == SANE_STATUS_GOOD);
595 assert (info == SANE_INFO_INEXACT);
596 for (i = 0; i < ARRAY_SIZE; i++)
597 {
598 assert (value[i] == int_range.max);
599 }
600 }
601
602 static void
wrong_string_array(void)603 wrong_string_array (void)
604 {
605 SANE_Char value[9] = "wrong";
606 SANE_Word info = 0;
607 SANE_Status status;
608
609 status = sanei_constrain_value (&string_array_opt, &value, &info);
610
611 /* check results */
612 assert (status == SANE_STATUS_INVAL);
613 assert (info == 0);
614 }
615
616
617 static void
none_int(void)618 none_int (void)
619 {
620 SANE_Int value = 555;
621 SANE_Word info = 0;
622 SANE_Status status;
623
624 status = sanei_constrain_value (&none_opt, &value, &info);
625
626 /* check results */
627 assert (status == SANE_STATUS_GOOD);
628 assert (info == 0);
629 }
630
631
632 static void
none_bool_nok(void)633 none_bool_nok (void)
634 {
635 SANE_Bool value = 555;
636 SANE_Word info = 0;
637 SANE_Status status;
638
639 status = sanei_constrain_value (&none_bool_opt, &value, &info);
640
641 /* check results */
642 assert (status == SANE_STATUS_INVAL);
643 assert (info == 0);
644 }
645
646
647 static void
none_bool_ok(void)648 none_bool_ok (void)
649 {
650 SANE_Bool value = SANE_FALSE;
651 SANE_Word info = 0;
652 SANE_Status status;
653
654 status = sanei_constrain_value (&none_bool_opt, &value, &info);
655
656 /* check results */
657 assert (status == SANE_STATUS_GOOD);
658 assert (info == 0);
659 }
660
661 /**
662 * several partial match
663 */
664 static void
string_array_several(void)665 string_array_several (void)
666 {
667 SANE_Char value[9] = "Line";
668 SANE_Word info = 0;
669 SANE_Status status;
670
671 status = sanei_constrain_value (&string_array_opt, &value, &info);
672
673 /* check results */
674 assert (status == SANE_STATUS_INVAL);
675 assert (info == 0);
676 }
677
678 /**
679 * unique partial match
680 */
681 static void
partial_string_array(void)682 partial_string_array (void)
683 {
684 SANE_Char value[9] = "Linea";
685 SANE_Word info = 0;
686 SANE_Status status;
687
688 status = sanei_constrain_value (&string_array_opt, &value, &info);
689
690 /* check results */
691 assert (status == SANE_STATUS_GOOD);
692 assert (info == 0);
693 }
694
695 static void
string_array_ignorecase(void)696 string_array_ignorecase (void)
697 {
698 SANE_Char value[9] = "lineart";
699 SANE_Word info = 0;
700 SANE_Status status;
701
702 status = sanei_constrain_value (&string_array_opt, &value, &info);
703
704 /* check results */
705 assert (status == SANE_STATUS_GOOD);
706 assert (info == 0);
707 }
708
709 static void
string_array_ok(void)710 string_array_ok (void)
711 {
712 SANE_Char value[9] = "Lineart";
713 SANE_Word info = 0;
714 SANE_Status status;
715
716 status = sanei_constrain_value (&string_array_opt, &value, &info);
717
718 /* check results */
719 assert (status == SANE_STATUS_GOOD);
720 assert (info == 0);
721 }
722
723 /**
724 * run the test suite for sanei constrain related tests
725 */
726 static void
sanei_constrain_suite(void)727 sanei_constrain_suite (void)
728 {
729 /* to be compatible with pre-C99 compilers */
730 int_opt.constraint.range = &int_range;
731 fixed_opt.constraint.range = &fixed_range;
732 array_opt.constraint.range = &int_range;
733 word_array_opt.constraint.word_list = dpi_list;
734 string_array_opt.constraint.string_list = string_list;
735
736 /* tests for constrained int value */
737 min_int_value ();
738 max_int_value ();
739 below_min_int_value ();
740 above_max_int_value ();
741 quant1_int_value ();
742 quant2_int_value ();
743 in_range_int_value ();
744
745 /* tests for sane fixed constrained value */
746 min_fixed_value ();
747 max_fixed_value ();
748 below_min_fixed_value ();
749 above_max_fixed_value ();
750 quant1_fixed_value ();
751 quant2_fixed_value ();
752 in_range_fixed_value ();
753
754 /* tests for constrained int array */
755 min_int_array ();
756 max_int_array ();
757 below_min_int_array ();
758 above_max_int_array ();
759 quant1_int_array ();
760 quant2_int_array ();
761 in_range_int_array ();
762
763 /* tests for word lists */
764 above_max_word ();
765 below_max_word ();
766 closest_200_word ();
767 closest_300_word ();
768 exact_400_word ();
769
770 /* tests for string lists */
771 wrong_string_array ();
772 partial_string_array ();
773 string_array_ok ();
774 string_array_ignorecase ();
775 string_array_several ();
776
777 /* constraint none tests */
778 none_int ();
779 none_bool_nok ();
780 none_bool_ok ();
781 }
782
783 /**
784 * main function to run the test suites
785 */
786 int
main(void)787 main (void)
788 {
789 /* run suites */
790 sanei_constrain_suite ();
791
792 return 0;
793 }
794
795 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
796