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