1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package loads
16
17 import (
18 "encoding/json"
19 "path/filepath"
20 "regexp"
21 "strconv"
22 "strings"
23 "testing"
24
25 "github.com/stretchr/testify/assert"
26 "github.com/stretchr/testify/require"
27 )
28
29 func TestUnknownSpecVersion(t *testing.T) {
30 _, err := Analyzed([]byte{}, "0.9")
31 require.Error(t, err)
32 }
33
34 func TestDefaultsTo20(t *testing.T) {
35 d, err := Analyzed(PetStoreJSONMessage, "")
36 require.NoError(t, err)
37 require.NotNil(t, d)
38
39 assert.Equal(t, "2.0", d.Version())
40
41 assert.Equal(t, "/api", d.BasePath())
42 }
43
44 func TestLoadsYAMLContent(t *testing.T) {
45 d, err := Analyzed(json.RawMessage([]byte(YAMLSpec)), "")
46 require.NoError(t, err)
47 require.NotNil(t, d)
48
49 sw := d.Spec()
50 assert.Equal(t, "1.0.0", sw.Info.Version)
51 }
52
53
54 func TestRegressionExpand(t *testing.T) {
55 swaggerFile := "fixtures/yaml/swagger/1/2/3/4/swagger.yaml"
56 document, err := Spec(swaggerFile)
57 require.NoError(t, err)
58 require.NotNil(t, document)
59
60 d, err := document.Expanded()
61 require.NoError(t, err)
62 require.NotNil(t, d)
63
64 b, _ := d.Spec().MarshalJSON()
65 assert.JSONEq(t, expectedExpanded, string(b))
66 }
67
68 func TestCascadingRefExpand(t *testing.T) {
69 swaggerFile := "fixtures/yaml/swagger/spec.yml"
70 document, err := Spec(swaggerFile)
71 require.NoError(t, err)
72 require.NotNil(t, document)
73
74 d, err := document.Expanded()
75 require.NoError(t, err)
76 require.NotNil(t, d)
77
78 b, _ := d.Spec().MarshalJSON()
79 assert.JSONEq(t, cascadeRefExpanded, string(b))
80 }
81
82 func TestFailsInvalidJSON(t *testing.T) {
83 _, err := Analyzed(json.RawMessage([]byte("{]")), "")
84
85 require.Error(t, err)
86 }
87
88
89 func TestIssue1846(t *testing.T) {
90 swaggerFile := "fixtures/bugs/1816/fixture-1816.yaml"
91 document, err := Spec(swaggerFile)
92 require.NoError(t, err)
93 require.NotNil(t, document)
94
95 sp, err := cloneSpec(document.Spec())
96 require.NoError(t, err)
97
98 jazon, _ := json.MarshalIndent(sp, "", " ")
99 rex := regexp.MustCompile(`"\$ref":\s*"(.+)"`)
100 m := rex.FindAllStringSubmatch(string(jazon), -1)
101 require.NotNil(t, m)
102
103 for _, matched := range m {
104 subMatch := matched[1]
105 require.Truef(t,
106 strings.HasPrefix(subMatch, "#/definitions") || strings.HasPrefix(subMatch, "#/responses"),
107 "expected $ref to point either to definitions or responses section, got: %s", matched[0])
108 }
109 }
110
111 func TestEmbedded(t *testing.T) {
112 swaggerFile := "fixtures/yaml/swagger/spec.yml"
113 document, err := Spec(swaggerFile)
114 require.NoError(t, err)
115 require.NotNil(t, document)
116
117 raw, err := json.Marshal(document.Raw())
118 require.NoError(t, err)
119
120 spc, err := json.Marshal(document.Spec())
121 require.NoError(t, err)
122
123 d, err := Embedded(raw, spc)
124 require.NoError(t, err)
125 require.NotNil(t, d)
126
127 rawEmbedded, err := json.Marshal(d.Raw())
128 require.NoError(t, err)
129
130 spcEmbedded, err := json.Marshal(d.Spec())
131 require.NoError(t, err)
132
133 assert.JSONEq(t, string(raw), string(rawEmbedded))
134 assert.JSONEq(t, string(spc), string(spcEmbedded))
135 }
136
137 func TestDocument(t *testing.T) {
138 document, err := Embedded(PetStoreJSONMessage, PetStoreJSONMessage)
139 require.NoError(t, err)
140
141 require.Equal(t, "petstore.swagger.wordnik.com", document.Host())
142
143 orig, err := json.Marshal(document.OrigSpec())
144 require.NoError(t, err)
145
146 require.JSONEq(t, string(PetStoreJSONMessage), string(orig))
147
148 cloned, err := json.Marshal(document.Pristine().Spec())
149 require.NoError(t, err)
150
151 require.JSONEq(t, string(PetStoreJSONMessage), string(cloned))
152
153 spc := document.Spec()
154 spc.Definitions = nil
155
156 before := document.Spec()
157 require.Empty(t, before.Definitions)
158
159 reset := document.ResetDefinitions()
160
161 afterReset, err := json.Marshal(reset.Spec())
162 require.NoError(t, err)
163
164 require.JSONEq(t, string(PetStoreJSONMessage), string(afterReset))
165 }
166
167 func BenchmarkAnalyzed(b *testing.B) {
168 d := []byte(`{
169 "swagger": "2.0",
170 "info": {
171 "version": "1.0.0",
172 "title": "Swagger Petstore",
173 "contact": {
174 "name": "Wordnik API Team",
175 "url": "http://developer.wordnik.com"
176 },
177 "license": {
178 "name": "Creative Commons 4.0 International",
179 "url": "http://creativecommons.org/licenses/by/4.0/"
180 }
181 },
182 "host": "petstore.swagger.wordnik.com",
183 "basePath": "/api",
184 "schemes": [
185 "http"
186 ],
187 "paths": {
188 "/pets": {
189 "get": {
190 "security": [
191 {
192 "basic": []
193 }
194 ],
195 "tags": [ "Pet Operations" ],
196 "operationId": "getAllPets",
197 "parameters": [
198 {
199 "name": "status",
200 "in": "query",
201 "description": "The status to filter by",
202 "type": "string"
203 },
204 {
205 "name": "limit",
206 "in": "query",
207 "description": "The maximum number of results to return",
208 "type": "integer",
209 "format": "int64"
210 }
211 ],
212 "summary": "Finds all pets in the system",
213 "responses": {
214 "200": {
215 "description": "Pet response",
216 "schema": {
217 "type": "array",
218 "items": {
219 "$ref": "#/definitions/Pet"
220 }
221 }
222 },
223 "default": {
224 "description": "Unexpected error",
225 "schema": {
226 "$ref": "#/definitions/Error"
227 }
228 }
229 }
230 },
231 "post": {
232 "security": [
233 {
234 "basic": []
235 }
236 ],
237 "tags": [ "Pet Operations" ],
238 "operationId": "createPet",
239 "summary": "Creates a new pet",
240 "consumes": ["application/x-yaml"],
241 "produces": ["application/x-yaml"],
242 "parameters": [
243 {
244 "name": "pet",
245 "in": "body",
246 "description": "The Pet to create",
247 "required": true,
248 "schema": {
249 "$ref": "#/definitions/newPet"
250 }
251 }
252 ],
253 "responses": {
254 "200": {
255 "description": "Created Pet response",
256 "schema": {
257 "$ref": "#/definitions/Pet"
258 }
259 },
260 "default": {
261 "description": "Unexpected error",
262 "schema": {
263 "$ref": "#/definitions/Error"
264 }
265 }
266 }
267 }
268 }`)
269
270 for i := 0; i < 1000; i++ {
271 d = append(d, []byte(`,
272 "/pets/`)...)
273 d = strconv.AppendInt(d, int64(i), 10)
274 d = append(d, []byte(`": {
275 "delete": {
276 "security": [
277 {
278 "apiKey": []
279 }
280 ],
281 "description": "Deletes the Pet by id",
282 "operationId": "deletePet",
283 "parameters": [
284 {
285 "name": "id",
286 "in": "path",
287 "description": "ID of pet to delete",
288 "required": true,
289 "type": "integer",
290 "format": "int64"
291 }
292 ],
293 "responses": {
294 "204": {
295 "description": "pet deleted"
296 },
297 "default": {
298 "description": "unexpected error",
299 "schema": {
300 "$ref": "#/definitions/Error"
301 }
302 }
303 }
304 },
305 "get": {
306 "tags": [ "Pet Operations" ],
307 "operationId": "getPetById",
308 "summary": "Finds the pet by id",
309 "responses": {
310 "200": {
311 "description": "Pet response",
312 "schema": {
313 "$ref": "#/definitions/Pet"
314 }
315 },
316 "default": {
317 "description": "Unexpected error",
318 "schema": {
319 "$ref": "#/definitions/Error"
320 }
321 }
322 }
323 },
324 "parameters": [
325 {
326 "name": "id",
327 "in": "path",
328 "description": "ID of pet",
329 "required": true,
330 "type": "integer",
331 "format": "int64"
332 }
333 ]
334 }`)...)
335 }
336
337 d = append(d, []byte(`
338 },
339 "definitions": {
340 "Category": {
341 "id": "Category",
342 "properties": {
343 "id": {
344 "format": "int64",
345 "type": "integer"
346 },
347 "name": {
348 "type": "string"
349 }
350 }
351 },
352 "Pet": {
353 "id": "Pet",
354 "properties": {
355 "category": {
356 "$ref": "#/definitions/Category"
357 },
358 "id": {
359 "description": "unique identifier for the pet",
360 "format": "int64",
361 "maximum": 100.0,
362 "minimum": 0.0,
363 "type": "integer"
364 },
365 "name": {
366 "type": "string"
367 },
368 "photoUrls": {
369 "items": {
370 "type": "string"
371 },
372 "type": "array"
373 },
374 "status": {
375 "description": "pet status in the store",
376 "enum": [
377 "available",
378 "pending",
379 "sold"
380 ],
381 "type": "string"
382 },
383 "tags": {
384 "items": {
385 "$ref": "#/definitions/Tag"
386 },
387 "type": "array"
388 }
389 },
390 "required": [
391 "id",
392 "name"
393 ]
394 },
395 "newPet": {
396 "anyOf": [
397 {
398 "$ref": "#/definitions/Pet"
399 },
400 {
401 "required": [
402 "name"
403 ]
404 }
405 ]
406 },
407 "Tag": {
408 "id": "Tag",
409 "properties": {
410 "id": {
411 "format": "int64",
412 "type": "integer"
413 },
414 "name": {
415 "type": "string"
416 }
417 }
418 },
419 "Error": {
420 "required": [
421 "code",
422 "message"
423 ],
424 "properties": {
425 "code": {
426 "type": "integer",
427 "format": "int32"
428 },
429 "message": {
430 "type": "string"
431 }
432 }
433 }
434 },
435 "consumes": [
436 "application/json",
437 "application/xml"
438 ],
439 "produces": [
440 "application/json",
441 "application/xml",
442 "text/plain",
443 "text/html"
444 ],
445 "securityDefinitions": {
446 "basic": {
447 "type": "basic"
448 },
449 "apiKey": {
450 "type": "apiKey",
451 "in": "header",
452 "name": "X-API-KEY"
453 }
454 }
455 }
456 `)...)
457 rm := json.RawMessage(d)
458 b.ResetTimer()
459 for i := 0; i < b.N; i++ {
460 _, err := Analyzed(rm, "")
461 if err != nil {
462 b.Fatal(err)
463 }
464 }
465 }
466
467 const YAMLSpec = `swagger: '2.0'
468
469 info:
470 version: "1.0.0"
471 title: Simple Search API
472 description: |
473 A very simple api description that makes a x-www-form-urlencoded only API to submit searches.
474
475 produces:
476 - application/json
477
478 consumes:
479 - application/json
480
481 paths:
482 /search:
483 post:
484 operationId: search
485 summary: searches tasks
486 description: searches the task titles and descriptions for a match
487 consumes:
488 - application/x-www-form-urlencoded
489 parameters:
490 - name: q
491 in: formData
492 type: string
493 description: the search string
494 required: true
495 /tasks:
496 get:
497 operationId: getTasks
498 summary: Gets Task objects.
499 description: |
500 Optional query param of **size** determines
501 size of returned array
502 tags:
503 - tasks
504 parameters:
505 - name: size
506 in: query
507 description: Size of task list
508 type: integer
509 format: int32
510 default: 20
511 - name: completed
512 in: query
513 description: when true shows completed tasks
514 type: boolean
515
516 responses:
517 default:
518 description: Generic Error
519 200:
520 description: Successful response
521 headers:
522 X-Rate-Limit:
523 type: integer
524 format: int32
525 X-Rate-Limit-Remaining:
526 type: integer
527 format: int32
528 default: 42
529 X-Rate-Limit-Reset:
530 type: integer
531 format: int32
532 default: "1449875311"
533 X-Rate-Limit-Reset-Human:
534 type: string
535 default: 3 days
536 X-Rate-Limit-Reset-Human-Number:
537 type: string
538 default: 3
539 Access-Control-Allow-Origin:
540 type: string
541 default: "*"
542 schema:
543 type: array
544 items:
545 $ref: "#/definitions/Task"
546 post:
547 operationId: createTask
548 summary: Creates a 'Task' object.
549 description: |
550 Validates the content property for length etc.
551 parameters:
552 - name: body
553 in: body
554 schema:
555 $ref: "#/definitions/Task"
556 tags:
557 - tasks
558 responses:
559 default:
560 description: Generic Error
561 201:
562 description: Task Created
563
564 /tasks/{id}:
565 parameters:
566 - name: id
567 in: path
568 type: integer
569 format: int32
570 description: The id of the task
571 required: true
572 minimum: 1
573 put:
574 operationId: updateTask
575 summary: updates a task.
576 description: |
577 Validates the content property for length etc.
578 tags:
579 - tasks
580 parameters:
581 - name: body
582 in: body
583 description: the updated task
584 schema:
585 $ref: "#/definitions/Task"
586 responses:
587 default:
588 description: Generic Error
589 200:
590 description: Task updated
591 schema:
592 $ref: "#/definitions/Task"
593 delete:
594 operationId: deleteTask
595 summary: deletes a task
596 description: |
597 Deleting a task is irrevocable.
598 tags:
599 - tasks
600 responses:
601 default:
602 description: Generic Error
603 204:
604 description: Task Deleted
605
606
607 definitions:
608 Task:
609 title: A Task object
610 description: |
611 This describes a task. Tasks require a content property to be set.
612 required:
613 - content
614 type: object
615 properties:
616 id:
617 title: the unique id of the task
618 description: |
619 This id property is autogenerated when a task is created.
620 type: integer
621 format: int64
622 readOnly: true
623 content:
624 title: The content of the task
625 description: |
626 Task content can contain [GFM](https://help.github.com/articles/github-flavored-markdown/).
627 type: string
628 minLength: 5
629 completed:
630 title: when true this task is completed
631 type: boolean
632 creditcard:
633 title: the credit card format usage
634 type: string
635 format: creditcard
636 createdAt:
637 title: task creation time
638 type: string
639 format: date-time
640 readOnly: true
641 `
642
643
644 var PetStoreJSONMessage = json.RawMessage([]byte(PetStore20))
645
646
647 const PetStore20 = `{
648 "swagger": "2.0",
649 "info": {
650 "version": "1.0.0",
651 "title": "Swagger Petstore",
652 "contact": {
653 "name": "Wordnik API Team",
654 "url": "http://developer.wordnik.com"
655 },
656 "license": {
657 "name": "Creative Commons 4.0 International",
658 "url": "http://creativecommons.org/licenses/by/4.0/"
659 }
660 },
661 "host": "petstore.swagger.wordnik.com",
662 "basePath": "/api",
663 "schemes": [
664 "http"
665 ],
666 "paths": {
667 "/pets": {
668 "get": {
669 "security": [
670 {
671 "basic": []
672 }
673 ],
674 "tags": [ "Pet Operations" ],
675 "operationId": "getAllPets",
676 "parameters": [
677 {
678 "name": "status",
679 "in": "query",
680 "description": "The status to filter by",
681 "type": "string"
682 },
683 {
684 "name": "limit",
685 "in": "query",
686 "description": "The maximum number of results to return",
687 "type": "integer",
688 "format": "int64"
689 }
690 ],
691 "summary": "Finds all pets in the system",
692 "responses": {
693 "200": {
694 "description": "Pet response",
695 "schema": {
696 "type": "array",
697 "items": {
698 "$ref": "#/definitions/Pet"
699 }
700 }
701 },
702 "default": {
703 "description": "Unexpected error",
704 "schema": {
705 "$ref": "#/definitions/Error"
706 }
707 }
708 }
709 },
710 "post": {
711 "security": [
712 {
713 "basic": []
714 }
715 ],
716 "tags": [ "Pet Operations" ],
717 "operationId": "createPet",
718 "summary": "Creates a new pet",
719 "consumes": ["application/x-yaml"],
720 "produces": ["application/x-yaml"],
721 "parameters": [
722 {
723 "name": "pet",
724 "in": "body",
725 "description": "The Pet to create",
726 "required": true,
727 "schema": {
728 "$ref": "#/definitions/newPet"
729 }
730 }
731 ],
732 "responses": {
733 "200": {
734 "description": "Created Pet response",
735 "schema": {
736 "$ref": "#/definitions/Pet"
737 }
738 },
739 "default": {
740 "description": "Unexpected error",
741 "schema": {
742 "$ref": "#/definitions/Error"
743 }
744 }
745 }
746 }
747 },
748 "/pets/{id}": {
749 "delete": {
750 "security": [
751 {
752 "apiKey": []
753 }
754 ],
755 "description": "Deletes the Pet by id",
756 "operationId": "deletePet",
757 "parameters": [
758 {
759 "name": "id",
760 "in": "path",
761 "description": "ID of pet to delete",
762 "required": true,
763 "type": "integer",
764 "format": "int64"
765 }
766 ],
767 "responses": {
768 "204": {
769 "description": "pet deleted"
770 },
771 "default": {
772 "description": "unexpected error",
773 "schema": {
774 "$ref": "#/definitions/Error"
775 }
776 }
777 }
778 },
779 "get": {
780 "tags": [ "Pet Operations" ],
781 "operationId": "getPetById",
782 "summary": "Finds the pet by id",
783 "responses": {
784 "200": {
785 "description": "Pet response",
786 "schema": {
787 "$ref": "#/definitions/Pet"
788 }
789 },
790 "default": {
791 "description": "Unexpected error",
792 "schema": {
793 "$ref": "#/definitions/Error"
794 }
795 }
796 }
797 },
798 "parameters": [
799 {
800 "name": "id",
801 "in": "path",
802 "description": "ID of pet",
803 "required": true,
804 "type": "integer",
805 "format": "int64"
806 }
807 ]
808 }
809 },
810 "definitions": {
811 "Category": {
812 "id": "Category",
813 "properties": {
814 "id": {
815 "format": "int64",
816 "type": "integer"
817 },
818 "name": {
819 "type": "string"
820 }
821 }
822 },
823 "Pet": {
824 "id": "Pet",
825 "properties": {
826 "category": {
827 "$ref": "#/definitions/Category"
828 },
829 "id": {
830 "description": "unique identifier for the pet",
831 "format": "int64",
832 "maximum": 100.0,
833 "minimum": 0.0,
834 "type": "integer"
835 },
836 "name": {
837 "type": "string"
838 },
839 "photoUrls": {
840 "items": {
841 "type": "string"
842 },
843 "type": "array"
844 },
845 "status": {
846 "description": "pet status in the store",
847 "enum": [
848 "available",
849 "pending",
850 "sold"
851 ],
852 "type": "string"
853 },
854 "tags": {
855 "items": {
856 "$ref": "#/definitions/Tag"
857 },
858 "type": "array"
859 }
860 },
861 "required": [
862 "id",
863 "name"
864 ]
865 },
866 "newPet": {
867 "anyOf": [
868 {
869 "$ref": "#/definitions/Pet"
870 },
871 {
872 "required": [
873 "name"
874 ]
875 }
876 ]
877 },
878 "Tag": {
879 "id": "Tag",
880 "properties": {
881 "id": {
882 "format": "int64",
883 "type": "integer"
884 },
885 "name": {
886 "type": "string"
887 }
888 }
889 },
890 "Error": {
891 "required": [
892 "code",
893 "message"
894 ],
895 "properties": {
896 "code": {
897 "type": "integer",
898 "format": "int32"
899 },
900 "message": {
901 "type": "string"
902 }
903 }
904 }
905 },
906 "consumes": [
907 "application/json",
908 "application/xml"
909 ],
910 "produces": [
911 "application/json",
912 "application/xml",
913 "text/plain",
914 "text/html"
915 ],
916 "securityDefinitions": {
917 "basic": {
918 "type": "basic"
919 },
920 "apiKey": {
921 "type": "apiKey",
922 "in": "header",
923 "name": "X-API-KEY"
924 }
925 }
926 }
927 `
928
929 const expectedExpanded = `
930 {
931 "produces":[
932 "application/json",
933 "plain/text"
934 ],
935 "schemes":[
936 "https",
937 "http"
938 ],
939 "swagger":"2.0",
940 "info":{
941 "description":"Something",
942 "title":"Something",
943 "contact":{
944 "name":"Somebody",
945 "url":"https://url.com",
946 "email":"email@url.com"
947 },
948 "version":"v1"
949 },
950 "host":"security.sonusnet.com",
951 "basePath":"/api",
952 "paths":{
953 "/whatnot":{
954 "get":{
955 "description":"Get something",
956 "responses":{
957 "200":{
958 "description":"The something",
959 "schema":{
960 "description":"A collection of service events",
961 "type":"object",
962 "properties":{
963 "page":{
964 "description":"A description of a paged result",
965 "type":"object",
966 "properties":{
967 "page":{
968 "description":"the page that was requested",
969 "type":"integer"
970 },
971 "page_items":{
972 "description":"the number of items per page requested",
973 "type":"integer"
974 },
975 "pages":{
976 "description":"the total number of pages available",
977 "type":"integer"
978 },
979 "total_items":{
980 "description":"the total number of items available",
981 "type":"integer",
982 "format":"int64"
983 }
984 }
985 },
986 "something":{
987 "description":"Something",
988 "type":"object",
989 "properties":{
990 "p1":{
991 "description":"A string",
992 "type":"string"
993 },
994 "p2":{
995 "description":"An integer",
996 "type":"integer"
997 }
998 }
999 }
1000 }
1001 }
1002 },
1003 "500":{
1004 "description":"Oops"
1005 }
1006 }
1007 }
1008 }
1009 },
1010 "definitions":{
1011 "Something":{
1012 "description":"A collection of service events",
1013 "type":"object",
1014 "properties":{
1015 "page":{
1016 "description":"A description of a paged result",
1017 "type":"object",
1018 "properties":{
1019 "page":{
1020 "description":"the page that was requested",
1021 "type":"integer"
1022 },
1023 "page_items":{
1024 "description":"the number of items per page requested",
1025 "type":"integer"
1026 },
1027 "pages":{
1028 "description":"the total number of pages available",
1029 "type":"integer"
1030 },
1031 "total_items":{
1032 "description":"the total number of items available",
1033 "type":"integer",
1034 "format":"int64"
1035 }
1036 }
1037 },
1038 "something":{
1039 "description":"Something",
1040 "type":"object",
1041 "properties":{
1042 "p1":{
1043 "description":"A string",
1044 "type":"string"
1045 },
1046 "p2":{
1047 "description":"An integer",
1048 "type":"integer"
1049 }
1050 }
1051 }
1052 }
1053 }
1054 }
1055 }
1056 `
1057
1058 const cascadeRefExpanded = `
1059 {
1060 "swagger": "2.0",
1061 "consumes":[
1062 "application/json"
1063 ],
1064 "produces":[
1065 "application/json"
1066 ],
1067 "schemes":[
1068 "http"
1069 ],
1070 "host": "api.example.com",
1071 "info":{
1072 "description":"recursively following JSON references",
1073 "title":"test 1",
1074 "contact":{
1075 "name":"Fred"
1076 },
1077 "version":"0.1.1"
1078 },
1079 "paths":{
1080 "/getAll":{
1081 "get":{
1082 "operationId":"getAll",
1083 "parameters":[
1084 {
1085 "description":"max number of results",
1086 "name":"a",
1087 "in":"body",
1088 "schema":{
1089 "type":"string"
1090 }
1091 }
1092 ],
1093 "responses":{
1094 "200":{
1095 "description":"Success",
1096 "schema":{
1097 "type":"array",
1098 "items":{
1099 "type":"string"
1100 }
1101 }
1102 }
1103 }
1104 }
1105 }
1106 },
1107 "definitions":{
1108 "a":{
1109 "type":"string"
1110 },
1111 "b":{
1112 "type":"array",
1113 "items":{
1114 "type":"string"
1115 }
1116 }
1117 }
1118 }
1119 `
1120
1121 func TestSpecCircular(t *testing.T) {
1122 swaggerFile := "fixtures/json/resources/pathLoaderIssue.json"
1123 document, err := Spec(swaggerFile)
1124 require.NoError(t, err)
1125 require.NotNil(t, document)
1126 }
1127
1128 func TestIssueSpec145(t *testing.T) {
1129 t.Run("with remote $ref", func(t *testing.T) {
1130 docPath := filepath.Join("fixtures", "bugs", "145", "Program Files (x86)", "AppName", "todos.json")
1131
1132 t.Run("with Spec loader", func(t *testing.T) {
1133 document, err := Spec(docPath)
1134 require.NoError(t, err)
1135 require.NotNil(t, document)
1136
1137 _, err = document.Expanded()
1138 require.NoError(t, err)
1139 })
1140
1141 t.Run("with JSONSpec loader", func(t *testing.T) {
1142 document, err := JSONSpec(docPath)
1143 require.NoError(t, err)
1144 require.NotNil(t, document)
1145
1146 _, err = document.Expanded()
1147 require.NoError(t, err)
1148 })
1149 })
1150
1151 t.Run("with self-contained root", func(t *testing.T) {
1152 docPath := filepath.Join("fixtures", "bugs", "145", "Program Files (x86)", "AppName", "todos-expanded.json")
1153
1154 t.Run("with Spec loader", func(t *testing.T) {
1155 document, err := Spec(docPath)
1156 require.NoError(t, err)
1157 require.NotNil(t, document)
1158
1159 require.Equal(t, docPath, document.SpecFilePath())
1160
1161 expanded, err := document.Expanded()
1162 require.NoError(t, err)
1163
1164 require.Equal(t, docPath, expanded.SpecFilePath())
1165 })
1166
1167 t.Run("with JSONSpec loader", func(t *testing.T) {
1168 document, err := JSONSpec(docPath)
1169 require.NoError(t, err)
1170 require.NotNil(t, document)
1171
1172 _, err = document.Expanded()
1173 require.NoError(t, err)
1174
1175 t.Run("with Pristine", func(t *testing.T) {
1176 pristine := document.Pristine()
1177
1178 require.Equal(t, document.SpecFilePath(), pristine.SpecFilePath())
1179 })
1180 })
1181 })
1182 }
1183
View as plain text