this repo has no description
1-- in.cue --
2import (
3 "encoding/json"
4 "encoding/openapi"
5)
6
7// Basic schema marshaling test
8basic: {
9 config: openapi.#Config & {
10 version: "3.0.0"
11 info: {
12 title: "Test API"
13 version: "1.0.0"
14 }
15 }
16 schema: {
17 // A User is a person identified by their name and age.
18 #User: {
19 name: string
20 age: int
21 }
22 }
23 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
24}
25
26// Self-contained schema test
27selfContained: {
28 config: openapi.#Config & {
29 version: "3.0.0"
30 info: {
31 title: "Test API"
32 version: "1.0.0"
33 }
34 selfContained: true
35 }
36 schema: {
37 #Person: {
38 name: string
39 address: #Address
40 }
41 #Address: {
42 street: string
43 city: string
44 }
45 }
46 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
47}
48
49// Expand references test
50expandReferences: {
51 config: openapi.#Config & {
52 version: "3.0.0"
53 info: {
54 title: "Test API"
55 version: "1.0.0"
56 }
57 expandReferences: true
58 }
59 schema: {
60 #Product: {
61 id: int
62 name: string
63 category: #Category
64 subcategory: #Category
65 }
66 #Category: {
67 name: string
68 id: int
69 }
70 }
71 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
72}
73
74// Test with constraints and validation
75constraints: {
76 config: openapi.#Config & {
77 version: "3.0.0"
78 info: {
79 title: "Validation API"
80 version: "1.0.0"
81 }
82 }
83 schema: {
84 #User: {
85 name: string & len(_) > 0
86 age: int & >=0 & <=120
87 email: string & =~"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
88 }
89 }
90 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
91}
92
93// Test with optional and required fields
94optional: {
95 config: openapi.#Config & {
96 version: "3.0.0"
97 info: {
98 title: "Optional Fields API"
99 version: "1.0.0"
100 }
101 }
102 schema: {
103 #User: {
104 name!: string
105 age?: int
106 email?: string
107 metadata?: {...}
108 }
109 }
110 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
111}
112
113// Test with arrays and objects
114collections: {
115 config: openapi.#Config & {
116 version: "3.0.0"
117 info: {
118 title: "Collections API"
119 version: "1.0.0"
120 }
121 }
122 schema: {
123 #UserList: {
124 users: [...#User]
125 total: int
126 }
127 #User: {
128 id: int
129 name: string
130 tags: [...string]
131 }
132 }
133 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
134}
135
136// Test with enums and unions
137enums: {
138 config: openapi.#Config & {
139 version: "3.0.0"
140 info: {
141 title: "Enums API"
142 version: "1.0.0"
143 }
144 }
145 schema: {
146 #Status: "active" | "inactive" | "pending"
147 #Priority: 1 | 2 | 3
148 #Task: {
149 id: int
150 status: #Status
151 priority: #Priority
152 }
153 }
154 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
155}
156
157// Test error handling - invalid version
158invalidVersion: {
159 config: openapi.#Config & {
160 version: "invalid.version"
161 info: {
162 title: "Test API"
163 version: "1.0.0"
164 }
165 }
166 schema: {
167 #User: {
168 name: string
169 }
170 }
171 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
172}
173
174// Test minimal config
175minimal: {
176 config: openapi.#Config & {
177 version: "3.0.0"
178 info: {
179 title: "Minimal API"
180 version: "1.0"
181 }
182 }
183 schema: {
184 #Simple: {
185 value: string
186 }
187 }
188 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
189}
190
191// Test with nested structures
192nested: {
193 config: openapi.#Config & {
194 version: "3.0.0"
195 info: {
196 title: "Nested API"
197 version: "1.0.0"
198 }
199 }
200 schema: {
201 #Company: {
202 name: string
203 departments: [...#Department]
204 }
205 #Department: {
206 name: string
207 manager: #Employee
208 employees: [...#Employee]
209 }
210 #Employee: {
211 id: int
212 name: string
213 position: string
214 }
215 }
216 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
217}
218-- out/openapi-v3 --
219Errors:
220invalidVersion.config.version: conflicting values "3.0.0" and "invalid.version":
221 ./in.cue:158:10
222 ./in.cue:159:12
223 encoding/openapi:3:21
224
225Result:
226import (
227 "encoding/json"
228 "encoding/openapi"
229)
230
231// Basic schema marshaling test
232basic: {
233 config: {
234 version: "3.0.0"
235 info: {
236 title: "Test API"
237 version: "1.0.0"
238 summary?: string
239 description?: string
240 termsOfService?: string
241 contact?: {
242 name?: string
243 url?: string
244 email?: string
245 }
246 license?: {
247 name!: string
248 url?: string
249 }
250 }
251 selfContained: *false | bool
252 expandReferences: *false | bool
253 }
254 schema: {
255 // A User is a person identified by their name and age.
256 #User: {
257 name: string
258 age: int
259 }
260 }
261 result: """
262 {
263 "openapi": "3.0.0",
264 "info": {
265 "title": "Test API",
266 "version": "1.0.0"
267 },
268 "paths": {},
269 "components": {
270 "schemas": {
271 "User": {
272 "description": "A User is a person identified by their name and age.",
273 "type": "object",
274 "required": [
275 "name",
276 "age"
277 ],
278 "properties": {
279 "name": {
280 "type": "string"
281 },
282 "age": {
283 "type": "integer"
284 }
285 }
286 }
287 }
288 }
289 }
290 """
291}
292
293// Self-contained schema test
294selfContained: {
295 config: {
296 version: "3.0.0"
297 info: {
298 title: "Test API"
299 version: "1.0.0"
300 summary?: string
301 description?: string
302 termsOfService?: string
303 contact?: {
304 name?: string
305 url?: string
306 email?: string
307 }
308 license?: {
309 name!: string
310 url?: string
311 }
312 }
313 selfContained: true
314 expandReferences: *false | bool
315 }
316 schema: {
317 #Person: {
318 name: string
319 address: {
320 street: string
321 city: string
322 }
323 }
324 #Address: {
325 street: string
326 city: string
327 }
328 }
329 result: """
330 {
331 "openapi": "3.0.0",
332 "info": {
333 "title": "Test API",
334 "version": "1.0.0"
335 },
336 "paths": {},
337 "components": {
338 "schemas": {
339 "Address": {
340 "type": "object",
341 "required": [
342 "street",
343 "city"
344 ],
345 "properties": {
346 "street": {
347 "type": "string"
348 },
349 "city": {
350 "type": "string"
351 }
352 }
353 },
354 "Person": {
355 "type": "object",
356 "required": [
357 "name",
358 "address"
359 ],
360 "properties": {
361 "name": {
362 "type": "string"
363 },
364 "address": {
365 "$ref": "#/components/schemas/selfContained.schema.Address"
366 }
367 }
368 },
369 "selfContained.schema.Address": {
370 "type": "object",
371 "required": [
372 "street",
373 "city"
374 ],
375 "properties": {
376 "street": {
377 "type": "string"
378 },
379 "city": {
380 "type": "string"
381 }
382 }
383 }
384 }
385 }
386 }
387 """
388}
389
390// Expand references test
391expandReferences: {
392 config: {
393 version: "3.0.0"
394 info: {
395 title: "Test API"
396 version: "1.0.0"
397 summary?: string
398 description?: string
399 termsOfService?: string
400 contact?: {
401 name?: string
402 url?: string
403 email?: string
404 }
405 license?: {
406 name!: string
407 url?: string
408 }
409 }
410 selfContained: *false | bool
411 expandReferences: true
412 }
413 schema: {
414 #Product: {
415 id: int
416 name: string
417 category: {
418 name: string
419 id: int
420 }
421 subcategory: {
422 name: string
423 id: int
424 }
425 }
426 #Category: {
427 name: string
428 id: int
429 }
430 }
431 result: """
432 {
433 "openapi": "3.0.0",
434 "info": {
435 "title": "Test API",
436 "version": "1.0.0"
437 },
438 "paths": {},
439 "components": {
440 "schemas": {
441 "Category": {
442 "type": "object",
443 "required": [
444 "name",
445 "id"
446 ],
447 "properties": {
448 "name": {
449 "type": "string"
450 },
451 "id": {
452 "type": "integer"
453 }
454 }
455 },
456 "Product": {
457 "type": "object",
458 "required": [
459 "id",
460 "name",
461 "category",
462 "subcategory"
463 ],
464 "properties": {
465 "id": {
466 "type": "integer"
467 },
468 "name": {
469 "type": "string"
470 },
471 "category": {
472 "type": "object",
473 "required": [
474 "name",
475 "id"
476 ],
477 "properties": {
478 "name": {
479 "type": "string"
480 },
481 "id": {
482 "type": "integer"
483 }
484 }
485 },
486 "subcategory": {
487 "type": "object",
488 "required": [
489 "name",
490 "id"
491 ],
492 "properties": {
493 "name": {
494 "type": "string"
495 },
496 "id": {
497 "type": "integer"
498 }
499 }
500 }
501 }
502 }
503 }
504 }
505 }
506 """
507}
508
509// Test with constraints and validation
510constraints: {
511 config: {
512 version: "3.0.0"
513 info: {
514 title: "Validation API"
515 version: "1.0.0"
516 summary?: string
517 description?: string
518 termsOfService?: string
519 contact?: {
520 name?: string
521 url?: string
522 email?: string
523 }
524 license?: {
525 name!: string
526 url?: string
527 }
528 }
529 selfContained: *false | bool
530 expandReferences: *false | bool
531 }
532 schema: {
533 #User: {
534 name: string & len(_) > 0
535 age: uint & <=120
536 email: =~"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
537 }
538 }
539 result: json.Indent(openapi.MarshalSchema(config, schema), "", " ")
540}
541
542// Test with optional and required fields
543optional: {
544 config: {
545 version: "3.0.0"
546 info: {
547 title: "Optional Fields API"
548 version: "1.0.0"
549 summary?: string
550 description?: string
551 termsOfService?: string
552 contact?: {
553 name?: string
554 url?: string
555 email?: string
556 }
557 license?: {
558 name!: string
559 url?: string
560 }
561 }
562 selfContained: *false | bool
563 expandReferences: *false | bool
564 }
565 schema: {
566 #User: {
567 name!: string
568 age?: int
569 email?: string
570 metadata?: {}
571 }
572 }
573 result: """
574 {
575 "openapi": "3.0.0",
576 "info": {
577 "title": "Optional Fields API",
578 "version": "1.0.0"
579 },
580 "paths": {},
581 "components": {
582 "schemas": {
583 "User": {
584 "type": "object",
585 "required": [
586 "name"
587 ],
588 "properties": {
589 "name": {
590 "type": "string"
591 },
592 "age": {
593 "type": "integer"
594 },
595 "email": {
596 "type": "string"
597 },
598 "metadata": {
599 "type": "object"
600 }
601 }
602 }
603 }
604 }
605 }
606 """
607}
608
609// Test with arrays and objects
610collections: {
611 config: {
612 version: "3.0.0"
613 info: {
614 title: "Collections API"
615 version: "1.0.0"
616 summary?: string
617 description?: string
618 termsOfService?: string
619 contact?: {
620 name?: string
621 url?: string
622 email?: string
623 }
624 license?: {
625 name!: string
626 url?: string
627 }
628 }
629 selfContained: *false | bool
630 expandReferences: *false | bool
631 }
632 schema: {
633 #UserList: {
634 users: [...{
635 id: int
636 name: string
637 tags: [...string]
638 }]
639 total: int
640 }
641 #User: {
642 id: int
643 name: string
644 tags: [...string]
645 }
646 }
647 result: """
648 {
649 "openapi": "3.0.0",
650 "info": {
651 "title": "Collections API",
652 "version": "1.0.0"
653 },
654 "paths": {},
655 "components": {
656 "schemas": {
657 "User": {
658 "type": "object",
659 "required": [
660 "id",
661 "name",
662 "tags"
663 ],
664 "properties": {
665 "id": {
666 "type": "integer"
667 },
668 "name": {
669 "type": "string"
670 },
671 "tags": {
672 "type": "array",
673 "items": {
674 "type": "string"
675 }
676 }
677 }
678 },
679 "UserList": {
680 "type": "object",
681 "required": [
682 "users",
683 "total"
684 ],
685 "properties": {
686 "users": {
687 "type": "array",
688 "items": {
689 "$ref": "#/components/schemas/collections.schema.User"
690 }
691 },
692 "total": {
693 "type": "integer"
694 }
695 }
696 },
697 "collections.schema.User": {
698 "type": "object",
699 "required": [
700 "id",
701 "name",
702 "tags"
703 ],
704 "properties": {
705 "id": {
706 "type": "integer"
707 },
708 "name": {
709 "type": "string"
710 },
711 "tags": {
712 "type": "array",
713 "items": {
714 "type": "string"
715 }
716 }
717 }
718 }
719 }
720 }
721 }
722 """
723}
724
725// Test with enums and unions
726enums: {
727 config: {
728 version: "3.0.0"
729 info: {
730 title: "Enums API"
731 version: "1.0.0"
732 summary?: string
733 description?: string
734 termsOfService?: string
735 contact?: {
736 name?: string
737 url?: string
738 email?: string
739 }
740 license?: {
741 name!: string
742 url?: string
743 }
744 }
745 selfContained: *false | bool
746 expandReferences: *false | bool
747 }
748 schema: {
749 #Status: "active" | "inactive" | "pending"
750 #Priority: 1 | 2 | 3
751 #Task: {
752 id: int
753 status: "active" | "inactive" | "pending"
754 priority: 1 | 2 | 3
755 }
756 }
757 result: """
758 {
759 "openapi": "3.0.0",
760 "info": {
761 "title": "Enums API",
762 "version": "1.0.0"
763 },
764 "paths": {},
765 "components": {
766 "schemas": {
767 "Priority": {
768 "type": "integer",
769 "enum": [
770 1,
771 2,
772 3
773 ]
774 },
775 "Status": {
776 "type": "string",
777 "enum": [
778 "active",
779 "inactive",
780 "pending"
781 ]
782 },
783 "Task": {
784 "type": "object",
785 "required": [
786 "id",
787 "status",
788 "priority"
789 ],
790 "properties": {
791 "id": {
792 "type": "integer"
793 },
794 "status": {
795 "$ref": "#/components/schemas/enums.schema.Status"
796 },
797 "priority": {
798 "$ref": "#/components/schemas/enums.schema.Priority"
799 }
800 }
801 },
802 "enums.schema.Priority": {
803 "type": "integer",
804 "enum": [
805 1,
806 2,
807 3
808 ]
809 },
810 "enums.schema.Status": {
811 "type": "string",
812 "enum": [
813 "active",
814 "inactive",
815 "pending"
816 ]
817 }
818 }
819 }
820 }
821 """
822}
823
824// Test error handling - invalid version
825invalidVersion: {
826 config: {
827 version: _|_ // invalidVersion.config.version: conflicting values "3.0.0" and "invalid.version"
828 info: {
829 title: "Test API"
830 version: "1.0.0"
831 summary?: string
832 description?: string
833 termsOfService?: string
834 contact?: {
835 name?: string
836 url?: string
837 email?: string
838 }
839 license?: {
840 name!: string
841 url?: string
842 }
843 }
844 selfContained: *false | bool
845 expandReferences: *false | bool
846 }
847 schema: {
848 #User: {
849 name: string
850 }
851 }
852 result: _|_ // invalidVersion.config.version: conflicting values "3.0.0" and "invalid.version"
853}
854
855// Test minimal config
856minimal: {
857 config: {
858 version: "3.0.0"
859 info: {
860 title: "Minimal API"
861 version: "1.0"
862 summary?: string
863 description?: string
864 termsOfService?: string
865 contact?: {
866 name?: string
867 url?: string
868 email?: string
869 }
870 license?: {
871 name!: string
872 url?: string
873 }
874 }
875 selfContained: *false | bool
876 expandReferences: *false | bool
877 }
878 schema: {
879 #Simple: {
880 value: string
881 }
882 }
883 result: """
884 {
885 "openapi": "3.0.0",
886 "info": {
887 "title": "Minimal API",
888 "version": "1.0"
889 },
890 "paths": {},
891 "components": {
892 "schemas": {
893 "Simple": {
894 "type": "object",
895 "required": [
896 "value"
897 ],
898 "properties": {
899 "value": {
900 "type": "string"
901 }
902 }
903 }
904 }
905 }
906 }
907 """
908}
909
910// Test with nested structures
911nested: {
912 config: {
913 version: "3.0.0"
914 info: {
915 title: "Nested API"
916 version: "1.0.0"
917 summary?: string
918 description?: string
919 termsOfService?: string
920 contact?: {
921 name?: string
922 url?: string
923 email?: string
924 }
925 license?: {
926 name!: string
927 url?: string
928 }
929 }
930 selfContained: *false | bool
931 expandReferences: *false | bool
932 }
933 schema: {
934 #Company: {
935 name: string
936 departments: [...{
937 name: string
938 manager: {
939 id: int
940 name: string
941 position: string
942 }
943 employees: [...{
944 id: int
945 name: string
946 position: string
947 }]
948 }]
949 }
950 #Department: {
951 name: string
952 manager: {
953 id: int
954 name: string
955 position: string
956 }
957 employees: [...{
958 id: int
959 name: string
960 position: string
961 }]
962 }
963 #Employee: {
964 id: int
965 name: string
966 position: string
967 }
968 }
969 result: """
970 {
971 "openapi": "3.0.0",
972 "info": {
973 "title": "Nested API",
974 "version": "1.0.0"
975 },
976 "paths": {},
977 "components": {
978 "schemas": {
979 "Company": {
980 "type": "object",
981 "required": [
982 "name",
983 "departments"
984 ],
985 "properties": {
986 "name": {
987 "type": "string"
988 },
989 "departments": {
990 "type": "array",
991 "items": {
992 "$ref": "#/components/schemas/nested.schema.Department"
993 }
994 }
995 }
996 },
997 "Department": {
998 "type": "object",
999 "required": [
1000 "name",
1001 "manager",
1002 "employees"
1003 ],
1004 "properties": {
1005 "name": {
1006 "type": "string"
1007 },
1008 "manager": {
1009 "$ref": "#/components/schemas/nested.schema.Employee"
1010 },
1011 "employees": {
1012 "type": "array",
1013 "items": {
1014 "$ref": "#/components/schemas/nested.schema.Employee"
1015 }
1016 }
1017 }
1018 },
1019 "Employee": {
1020 "type": "object",
1021 "required": [
1022 "id",
1023 "name",
1024 "position"
1025 ],
1026 "properties": {
1027 "id": {
1028 "type": "integer"
1029 },
1030 "name": {
1031 "type": "string"
1032 },
1033 "position": {
1034 "type": "string"
1035 }
1036 }
1037 },
1038 "nested.schema.Department": {
1039 "type": "object",
1040 "required": [
1041 "name",
1042 "manager",
1043 "employees"
1044 ],
1045 "properties": {
1046 "name": {
1047 "type": "string"
1048 },
1049 "manager": {
1050 "$ref": "#/components/schemas/nested.schema.Employee"
1051 },
1052 "employees": {
1053 "type": "array",
1054 "items": {
1055 "$ref": "#/components/schemas/nested.schema.Employee"
1056 }
1057 }
1058 }
1059 },
1060 "nested.schema.Employee": {
1061 "type": "object",
1062 "required": [
1063 "id",
1064 "name",
1065 "position"
1066 ],
1067 "properties": {
1068 "id": {
1069 "type": "integer"
1070 },
1071 "name": {
1072 "type": "string"
1073 },
1074 "position": {
1075 "type": "string"
1076 }
1077 }
1078 }
1079 }
1080 }
1081 }
1082 """
1083}