github.com/emreu/go-swagger@v0.22.1/codescan/parser_test.go (about) 1 package codescan 2 3 import ( 4 "fmt" 5 "go/ast" 6 "regexp" 7 "strings" 8 "testing" 9 10 "github.com/go-openapi/spec" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 // only used within this group of tests but never used within actual code base. 15 func newSchemaAnnotationParser(goName string) *schemaAnnotationParser { 16 return &schemaAnnotationParser{GoName: goName, rx: rxModelOverride} 17 } 18 19 type schemaAnnotationParser struct { 20 GoName string 21 Name string 22 rx *regexp.Regexp 23 } 24 25 func (sap *schemaAnnotationParser) Matches(line string) bool { 26 return sap.rx.MatchString(line) 27 } 28 29 func (sap *schemaAnnotationParser) Parse(lines []string) error { 30 if sap.Name != "" { 31 return nil 32 } 33 34 if len(lines) > 0 { 35 for _, line := range lines { 36 matches := sap.rx.FindStringSubmatch(line) 37 if len(matches) > 1 && len(matches[1]) > 0 { 38 sap.Name = matches[1] 39 return nil 40 } 41 } 42 } 43 return nil 44 } 45 46 func TestSectionedParser_TitleDescription(t *testing.T) { 47 text := `This has a title, separated by a whitespace line 48 49 In this example the punctuation for the title should not matter for swagger. 50 For go it will still make a difference though. 51 ` 52 text2 := `This has a title without whitespace. 53 The punctuation here does indeed matter. But it won't for go. 54 ` 55 56 text3 := `This has a title, and markdown in the description 57 58 See how markdown works now, we can have lists: 59 60 + first item 61 + second item 62 + third item 63 64 [Links works too](http://localhost) 65 ` 66 67 text4 := `This has whitespace sensitive markdown in the description 68 69 |+ first item 70 | + nested item 71 | + also nested item 72 73 Sample code block: 74 75 | fmt.Println("Hello World!") 76 77 ` 78 79 var err error 80 81 st := §ionedParser{} 82 st.setTitle = func(lines []string) {} 83 err = st.Parse(ascg(text)) 84 assert.NoError(t, err) 85 86 assert.EqualValues(t, []string{"This has a title, separated by a whitespace line"}, st.Title()) 87 assert.EqualValues(t, []string{"In this example the punctuation for the title should not matter for swagger.", "For go it will still make a difference though."}, st.Description()) 88 89 st = §ionedParser{} 90 st.setTitle = func(lines []string) {} 91 err = st.Parse(ascg(text2)) 92 assert.NoError(t, err) 93 94 assert.EqualValues(t, []string{"This has a title without whitespace."}, st.Title()) 95 assert.EqualValues(t, []string{"The punctuation here does indeed matter. But it won't for go."}, st.Description()) 96 97 st = §ionedParser{} 98 st.setTitle = func(lines []string) {} 99 err = st.Parse(ascg(text3)) 100 assert.NoError(t, err) 101 102 assert.EqualValues(t, []string{"This has a title, and markdown in the description"}, st.Title()) 103 assert.EqualValues(t, []string{"See how markdown works now, we can have lists:", "", "+ first item", "+ second item", "+ third item", "", "[Links works too](http://localhost)"}, st.Description()) 104 105 st = §ionedParser{} 106 st.setTitle = func(lines []string) {} 107 err = st.Parse(ascg(text4)) 108 assert.NoError(t, err) 109 110 assert.EqualValues(t, []string{"This has whitespace sensitive markdown in the description"}, st.Title()) 111 assert.EqualValues(t, []string{"+ first item", " + nested item", " + also nested item", "", "Sample code block:", "", " fmt.Println(\"Hello World!\")"}, st.Description()) 112 } 113 114 func dummyBuilder() schemaValidations { 115 return schemaValidations{new(spec.Schema)} 116 } 117 118 func TestSectionedParser_TagsDescription(t *testing.T) { 119 block := `This has a title without whitespace. 120 The punctuation here does indeed matter. But it won't for go. 121 minimum: 10 122 maximum: 20 123 ` 124 block2 := `This has a title without whitespace. 125 The punctuation here does indeed matter. But it won't for go. 126 127 minimum: 10 128 maximum: 20 129 ` 130 131 var err error 132 133 st := §ionedParser{} 134 st.setTitle = func(lines []string) {} 135 st.taggers = []tagParser{ 136 {"Maximum", false, false, nil, &setMaximum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMaximumFmt, ""))}}, 137 {"Minimum", false, false, nil, &setMinimum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMinimumFmt, ""))}}, 138 {"MultipleOf", false, false, nil, &setMultipleOf{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMultipleOfFmt, ""))}}, 139 } 140 141 err = st.Parse(ascg(block)) 142 assert.NoError(t, err) 143 assert.EqualValues(t, []string{"This has a title without whitespace."}, st.Title()) 144 assert.EqualValues(t, []string{"The punctuation here does indeed matter. But it won't for go."}, st.Description()) 145 assert.Len(t, st.matched, 2) 146 _, ok := st.matched["Maximum"] 147 assert.True(t, ok) 148 _, ok = st.matched["Minimum"] 149 assert.True(t, ok) 150 151 st = §ionedParser{} 152 st.setTitle = func(lines []string) {} 153 st.taggers = []tagParser{ 154 {"Maximum", false, false, nil, &setMaximum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMaximumFmt, ""))}}, 155 {"Minimum", false, false, nil, &setMinimum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMinimumFmt, ""))}}, 156 {"MultipleOf", false, false, nil, &setMultipleOf{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMultipleOfFmt, ""))}}, 157 } 158 159 err = st.Parse(ascg(block2)) 160 assert.NoError(t, err) 161 assert.EqualValues(t, []string{"This has a title without whitespace."}, st.Title()) 162 assert.EqualValues(t, []string{"The punctuation here does indeed matter. But it won't for go."}, st.Description()) 163 assert.Len(t, st.matched, 2) 164 _, ok = st.matched["Maximum"] 165 assert.True(t, ok) 166 _, ok = st.matched["Minimum"] 167 assert.True(t, ok) 168 } 169 170 func TestSectionedParser_Empty(t *testing.T) { 171 block := `swagger:response someResponse` 172 173 var err error 174 175 st := §ionedParser{} 176 st.setTitle = func(lines []string) {} 177 ap := newSchemaAnnotationParser("SomeResponse") 178 ap.rx = rxResponseOverride 179 st.annotation = ap 180 181 err = st.Parse(ascg(block)) 182 assert.NoError(t, err) 183 assert.Empty(t, st.Title()) 184 assert.Empty(t, st.Description()) 185 assert.Empty(t, st.taggers) 186 assert.Equal(t, "SomeResponse", ap.GoName) 187 assert.Equal(t, "someResponse", ap.Name) 188 } 189 190 func TestSectionedParser_SkipSectionAnnotation(t *testing.T) { 191 block := `swagger:model someModel 192 193 This has a title without whitespace. 194 The punctuation here does indeed matter. But it won't for go. 195 196 minimum: 10 197 maximum: 20 198 ` 199 var err error 200 201 st := §ionedParser{} 202 st.setTitle = func(lines []string) {} 203 ap := newSchemaAnnotationParser("SomeModel") 204 st.annotation = ap 205 st.taggers = []tagParser{ 206 {"Maximum", false, false, nil, &setMaximum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMaximumFmt, ""))}}, 207 {"Minimum", false, false, nil, &setMinimum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMinimumFmt, ""))}}, 208 {"MultipleOf", false, false, nil, &setMultipleOf{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMultipleOfFmt, ""))}}, 209 } 210 211 err = st.Parse(ascg(block)) 212 assert.NoError(t, err) 213 assert.EqualValues(t, []string{"This has a title without whitespace."}, st.Title()) 214 assert.EqualValues(t, []string{"The punctuation here does indeed matter. But it won't for go."}, st.Description()) 215 assert.Len(t, st.matched, 2) 216 _, ok := st.matched["Maximum"] 217 assert.True(t, ok) 218 _, ok = st.matched["Minimum"] 219 assert.True(t, ok) 220 assert.Equal(t, "SomeModel", ap.GoName) 221 assert.Equal(t, "someModel", ap.Name) 222 } 223 224 func TestSectionedParser_TerminateOnNewAnnotation(t *testing.T) { 225 block := `swagger:model someModel 226 227 This has a title without whitespace. 228 The punctuation here does indeed matter. But it won't for go. 229 230 minimum: 10 231 swagger:meta 232 maximum: 20 233 ` 234 var err error 235 236 st := §ionedParser{} 237 st.setTitle = func(lines []string) {} 238 ap := newSchemaAnnotationParser("SomeModel") 239 st.annotation = ap 240 st.taggers = []tagParser{ 241 {"Maximum", false, false, nil, &setMaximum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMaximumFmt, ""))}}, 242 {"Minimum", false, false, nil, &setMinimum{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMinimumFmt, ""))}}, 243 {"MultipleOf", false, false, nil, &setMultipleOf{dummyBuilder(), regexp.MustCompile(fmt.Sprintf(rxMultipleOfFmt, ""))}}, 244 } 245 246 err = st.Parse(ascg(block)) 247 assert.NoError(t, err) 248 assert.EqualValues(t, []string{"This has a title without whitespace."}, st.Title()) 249 assert.EqualValues(t, []string{"The punctuation here does indeed matter. But it won't for go."}, st.Description()) 250 assert.Len(t, st.matched, 1) 251 _, ok := st.matched["Maximum"] 252 assert.False(t, ok) 253 _, ok = st.matched["Minimum"] 254 assert.True(t, ok) 255 assert.Equal(t, "SomeModel", ap.GoName) 256 assert.Equal(t, "someModel", ap.Name) 257 } 258 259 func ascg(txt string) *ast.CommentGroup { 260 var cg ast.CommentGroup 261 for _, line := range strings.Split(txt, "\n") { 262 var cmt ast.Comment 263 cmt.Text = "// " + line 264 cg.List = append(cg.List, &cmt) 265 } 266 return &cg 267 } 268 269 func TestShouldAcceptTag(t *testing.T) { 270 var tagTests = []struct { 271 tags []string 272 includeTags map[string]bool 273 excludeTags map[string]bool 274 expected bool 275 }{ 276 {nil, nil, nil, true}, 277 {[]string{"app"}, map[string]bool{"app": true}, nil, true}, 278 {[]string{"app"}, nil, map[string]bool{"app": true}, false}, 279 } 280 for _, tt := range tagTests { 281 actual := shouldAcceptTag(tt.tags, tt.includeTags, tt.excludeTags) 282 assert.Equal(t, tt.expected, actual) 283 } 284 } 285 286 func TestShouldAcceptPkg(t *testing.T) { 287 var pkgTests = []struct { 288 path string 289 includePkgs []string 290 excludePkgs []string 291 expected bool 292 }{ 293 {"", nil, nil, true}, 294 {"", nil, []string{"app"}, true}, 295 {"", []string{"app"}, nil, false}, 296 {"app", []string{"app"}, nil, true}, 297 {"app", nil, []string{"app"}, false}, 298 {"vendor/app", []string{"app"}, nil, true}, 299 {"vendor/app", nil, []string{"app"}, false}, 300 } 301 for _, tt := range pkgTests { 302 actual := shouldAcceptPkg(tt.path, tt.includePkgs, tt.excludePkgs) 303 assert.Equal(t, tt.expected, actual) 304 } 305 }