New upstream version 0.19.15
Anthony Fok
2 years ago
9 | 9 | dupl: |
10 | 10 | threshold: 100 |
11 | 11 | goconst: |
12 | min-len: 2 | |
12 | min-len: 3 | |
13 | 13 | min-occurrences: 2 |
14 | 14 | |
15 | 15 | linters: |
16 | 16 | enable-all: true |
17 | 17 | disable: |
18 | 18 | - maligned |
19 | - lll | |
20 | - gochecknoinits | |
21 | - gochecknoglobals | |
22 | - nlreturn | |
23 | - testpackage | |
24 | - wrapcheck | |
25 | - gomnd | |
26 | - exhaustive | |
27 | - exhaustivestruct | |
28 | - goerr113 | |
29 | - wsl | |
30 | - whitespace | |
31 | - gofumpt | |
32 | - godot | |
33 | - nestif | |
34 | - godox | |
35 | - funlen | |
36 | - gci | |
37 | - gocognit | |
38 | - paralleltest | |
39 | - thelper | |
40 | - ifshort |
0 | language: go | |
1 | go: | |
2 | - 1.8 | |
3 | - 1.9.x | |
4 | - 1.10.x | |
5 | install: | |
6 | - go get -u github.com/stretchr/testify | |
7 | - go get -u github.com/mailru/easyjson | |
8 | - go get -u gopkg.in/yaml.v2 | |
9 | script: | |
10 | - go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./... | |
11 | 0 | after_success: |
12 | 1 | - bash <(curl -s https://codecov.io/bash) |
2 | go: | |
3 | - 1.14.x | |
4 | - 1.x | |
5 | arch: | |
6 | - amd64 | |
7 | jobs: | |
8 | include: | |
9 | # include arch ppc, but only for latest go version - skip testing for race | |
10 | - go: 1.x | |
11 | arch: ppc64le | |
12 | install: ~ | |
13 | script: | |
14 | - go test -v | |
15 | ||
16 | #- go: 1.x | |
17 | # arch: arm | |
18 | # install: ~ | |
19 | # script: | |
20 | # - go test -v | |
21 | ||
22 | # include linting job, but only for latest go version and amd64 arch | |
23 | - go: 1.x | |
24 | arch: amd64 | |
25 | install: | |
26 | go get github.com/golangci/golangci-lint/cmd/golangci-lint | |
27 | script: | |
28 | - golangci-lint run --new-from-rev master | |
29 | install: | |
30 | - GO111MODULE=off go get -u gotest.tools/gotestsum | |
31 | language: go | |
13 | 32 | notifications: |
14 | 33 | slack: |
15 | 34 | secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E= |
35 | script: | |
36 | - gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... |
1 | 1 | |
2 | 2 | [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) |
3 | 3 | [![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag) |
4 | [![GolangCI](https://golangci.com/badges/github.com/go-openapi/swag.svg)](https://golangci.com) | |
5 | 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag) |
6 | 5 | |
7 | Contains a bunch of helper functions: | |
6 | Contains a bunch of helper functions for go-openapi and go-swagger projects. | |
8 | 7 | |
9 | * convert between value and pointers for builtins | |
10 | * convert from string to builtin | |
8 | You may also use it standalone for your projects. | |
9 | ||
10 | * convert between value and pointers for builtin types | |
11 | * convert from string to builtin types (wraps strconv) | |
11 | 12 | * fast json concatenation |
12 | 13 | * search in path |
13 | 14 | * load from file or http |
14 | 15 | * name mangling |
16 | ||
17 | ||
18 | This repo has only few dependencies outside of the standard library: | |
19 | ||
20 | * YAML utilities depend on gopkg.in/yaml.v2 |
21 | 21 | |
22 | 22 | // same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER |
23 | 23 | const ( |
24 | maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 | |
25 | minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 | |
24 | maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 | |
25 | minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 | |
26 | epsilon float64 = 1e-9 | |
26 | 27 | ) |
27 | 28 | |
28 | 29 | // IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive |
30 | 31 | if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat { |
31 | 32 | return false |
32 | 33 | } |
33 | ||
34 | return f == float64(int64(f)) || f == float64(uint64(f)) | |
35 | } | |
36 | ||
37 | var evaluatesAsTrue = map[string]struct{}{ | |
38 | "true": {}, | |
39 | "1": {}, | |
40 | "yes": {}, | |
41 | "ok": {}, | |
42 | "y": {}, | |
43 | "on": {}, | |
44 | "selected": {}, | |
45 | "checked": {}, | |
46 | "t": {}, | |
47 | "enabled": {}, | |
34 | fa := math.Abs(f) | |
35 | g := float64(uint64(f)) | |
36 | ga := math.Abs(g) | |
37 | ||
38 | diff := math.Abs(f - g) | |
39 | ||
40 | // more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases | |
41 | switch { | |
42 | case f == g: // best case | |
43 | return true | |
44 | case f == float64(int64(f)) || f == float64(uint64(f)): // optimistic case | |
45 | return true | |
46 | case f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64: // very close to 0 values | |
47 | return diff < (epsilon * math.SmallestNonzeroFloat64) | |
48 | } | |
49 | // check the relative error | |
50 | return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon | |
51 | } | |
52 | ||
53 | var evaluatesAsTrue map[string]struct{} | |
54 | ||
55 | func init() { | |
56 | evaluatesAsTrue = map[string]struct{}{ | |
57 | "true": {}, | |
58 | "1": {}, | |
59 | "yes": {}, | |
60 | "ok": {}, | |
61 | "y": {}, | |
62 | "on": {}, | |
63 | "selected": {}, | |
64 | "checked": {}, | |
65 | "t": {}, | |
66 | "enabled": {}, | |
67 | } | |
48 | 68 | } |
49 | 69 | |
50 | 70 | // ConvertBool turn a string into a boolean |
67 | 87 | return strconv.ParseFloat(str, 64) |
68 | 88 | } |
69 | 89 | |
70 | // ConvertInt8 turn a string into int8 boolean | |
90 | // ConvertInt8 turn a string into an int8 | |
71 | 91 | func ConvertInt8(str string) (int8, error) { |
72 | 92 | i, err := strconv.ParseInt(str, 10, 8) |
73 | 93 | if err != nil { |
76 | 96 | return int8(i), nil |
77 | 97 | } |
78 | 98 | |
79 | // ConvertInt16 turn a string into a int16 | |
99 | // ConvertInt16 turn a string into an int16 | |
80 | 100 | func ConvertInt16(str string) (int16, error) { |
81 | 101 | i, err := strconv.ParseInt(str, 10, 16) |
82 | 102 | if err != nil { |
85 | 105 | return int16(i), nil |
86 | 106 | } |
87 | 107 | |
88 | // ConvertInt32 turn a string into a int32 | |
108 | // ConvertInt32 turn a string into an int32 | |
89 | 109 | func ConvertInt32(str string) (int32, error) { |
90 | 110 | i, err := strconv.ParseInt(str, 10, 32) |
91 | 111 | if err != nil { |
94 | 114 | return int32(i), nil |
95 | 115 | } |
96 | 116 | |
97 | // ConvertInt64 turn a string into a int64 | |
117 | // ConvertInt64 turn a string into an int64 | |
98 | 118 | func ConvertInt64(str string) (int64, error) { |
99 | 119 | return strconv.ParseInt(str, 10, 64) |
100 | 120 | } |
101 | 121 | |
102 | // ConvertUint8 turn a string into a uint8 | |
122 | // ConvertUint8 turn a string into an uint8 | |
103 | 123 | func ConvertUint8(str string) (uint8, error) { |
104 | 124 | i, err := strconv.ParseUint(str, 10, 8) |
105 | 125 | if err != nil { |
108 | 128 | return uint8(i), nil |
109 | 129 | } |
110 | 130 | |
111 | // ConvertUint16 turn a string into a uint16 | |
131 | // ConvertUint16 turn a string into an uint16 | |
112 | 132 | func ConvertUint16(str string) (uint16, error) { |
113 | 133 | i, err := strconv.ParseUint(str, 10, 16) |
114 | 134 | if err != nil { |
117 | 137 | return uint16(i), nil |
118 | 138 | } |
119 | 139 | |
120 | // ConvertUint32 turn a string into a uint32 | |
140 | // ConvertUint32 turn a string into an uint32 | |
121 | 141 | func ConvertUint32(str string) (uint32, error) { |
122 | 142 | i, err := strconv.ParseUint(str, 10, 32) |
123 | 143 | if err != nil { |
126 | 146 | return uint32(i), nil |
127 | 147 | } |
128 | 148 | |
129 | // ConvertUint64 turn a string into a uint64 | |
149 | // ConvertUint64 turn a string into an uint64 | |
130 | 150 | func ConvertUint64(str string) (uint64, error) { |
131 | 151 | return strconv.ParseUint(str, 10, 64) |
132 | 152 | } |
72 | 72 | |
73 | 73 | func TestConvertInt8(t *testing.T) { |
74 | 74 | validInts := []int8{0, 1, -1, math.MaxInt8, math.MinInt8} |
75 | invalidInts := []string{"1.233", "a", "false", strconv.Itoa(int(math.MaxInt64))} | |
75 | invalidInts := []string{"1.233", "a", "false", strconv.FormatInt(int64(math.MaxInt64), 10)} | |
76 | 76 | |
77 | 77 | for _, f := range validInts { |
78 | 78 | c, err := ConvertInt8(FormatInt8(f)) |
88 | 88 | |
89 | 89 | func TestConvertInt16(t *testing.T) { |
90 | 90 | validInts := []int16{0, 1, -1, math.MaxInt8, math.MinInt8, math.MaxInt16, math.MinInt16} |
91 | invalidInts := []string{"1.233", "a", "false", strconv.Itoa(int(math.MaxInt64))} | |
91 | invalidInts := []string{"1.233", "a", "false", strconv.FormatInt(int64(math.MaxInt64), 10)} | |
92 | 92 | |
93 | 93 | for _, f := range validInts { |
94 | 94 | c, err := ConvertInt16(FormatInt16(f)) |
104 | 104 | |
105 | 105 | func TestConvertInt32(t *testing.T) { |
106 | 106 | validInts := []int32{0, 1, -1, math.MaxInt8, math.MinInt8, math.MaxInt16, math.MinInt16, math.MinInt32, math.MaxInt32} |
107 | invalidInts := []string{"1.233", "a", "false", strconv.Itoa(int(math.MaxInt64))} | |
107 | invalidInts := []string{"1.233", "a", "false", strconv.FormatInt(int64(math.MaxInt64), 10)} | |
108 | 108 | |
109 | 109 | for _, f := range validInts { |
110 | 110 | c, err := ConvertInt32(FormatInt32(f)) |
206 | 206 | assert.True(t, IsFloat64AJSONInteger(1.0)) |
207 | 207 | assert.True(t, IsFloat64AJSONInteger(maxJSONFloat)) |
208 | 208 | assert.True(t, IsFloat64AJSONInteger(minJSONFloat)) |
209 | assert.True(t, IsFloat64AJSONInteger(1/0.01*67.15000001)) | |
210 | assert.False(t, IsFloat64AJSONInteger(math.SmallestNonzeroFloat64)) | |
211 | assert.False(t, IsFloat64AJSONInteger(math.SmallestNonzeroFloat64/2)) | |
212 | assert.True(t, IsFloat64AJSONInteger(math.SmallestNonzeroFloat64/3)) | |
213 | assert.True(t, IsFloat64AJSONInteger(math.SmallestNonzeroFloat64/4)) | |
209 | 214 | } |
210 | 215 | |
211 | 216 | func TestFormatBool(t *testing.T) { |
180 | 180 | return dst |
181 | 181 | } |
182 | 182 | |
183 | // Int32 returns a pointer to of the int64 value passed in. | |
183 | // Int32 returns a pointer to of the int32 value passed in. | |
184 | 184 | func Int32(v int32) *int32 { |
185 | 185 | return &v |
186 | 186 | } |
187 | 187 | |
188 | // Int32Value returns the value of the int64 pointer passed in or | |
188 | // Int32Value returns the value of the int32 pointer passed in or | |
189 | 189 | // 0 if the pointer is nil. |
190 | 190 | func Int32Value(v *int32) int32 { |
191 | 191 | if v != nil { |
194 | 194 | return 0 |
195 | 195 | } |
196 | 196 | |
197 | // Int32Slice converts a slice of int64 values into a slice of | |
197 | // Int32Slice converts a slice of int32 values into a slice of | |
198 | 198 | // int32 pointers |
199 | 199 | func Int32Slice(src []int32) []*int32 { |
200 | 200 | dst := make([]*int32, len(src)) |
298 | 298 | return dst |
299 | 299 | } |
300 | 300 | |
301 | // Uint returns a pouinter to of the uint value passed in. | |
301 | // Uint16 returns a pointer to of the uint16 value passed in. | |
302 | func Uint16(v uint16) *uint16 { | |
303 | return &v | |
304 | } | |
305 | ||
306 | // Uint16Value returns the value of the uint16 pointer passed in or | |
307 | // 0 if the pointer is nil. | |
308 | func Uint16Value(v *uint16) uint16 { | |
309 | if v != nil { | |
310 | return *v | |
311 | } | |
312 | ||
313 | return 0 | |
314 | } | |
315 | ||
316 | // Uint16Slice converts a slice of uint16 values into a slice of | |
317 | // uint16 pointers | |
318 | func Uint16Slice(src []uint16) []*uint16 { | |
319 | dst := make([]*uint16, len(src)) | |
320 | for i := 0; i < len(src); i++ { | |
321 | dst[i] = &(src[i]) | |
322 | } | |
323 | ||
324 | return dst | |
325 | } | |
326 | ||
327 | // Uint16ValueSlice converts a slice of uint16 pointers into a slice of | |
328 | // uint16 values | |
329 | func Uint16ValueSlice(src []*uint16) []uint16 { | |
330 | dst := make([]uint16, len(src)) | |
331 | ||
332 | for i := 0; i < len(src); i++ { | |
333 | if src[i] != nil { | |
334 | dst[i] = *(src[i]) | |
335 | } | |
336 | } | |
337 | ||
338 | return dst | |
339 | } | |
340 | ||
341 | // Uint16Map converts a string map of uint16 values into a string | |
342 | // map of uint16 pointers | |
343 | func Uint16Map(src map[string]uint16) map[string]*uint16 { | |
344 | dst := make(map[string]*uint16) | |
345 | ||
346 | for k, val := range src { | |
347 | v := val | |
348 | dst[k] = &v | |
349 | } | |
350 | ||
351 | return dst | |
352 | } | |
353 | ||
354 | // Uint16ValueMap converts a string map of uint16 pointers into a string | |
355 | // map of uint16 values | |
356 | func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { | |
357 | dst := make(map[string]uint16) | |
358 | ||
359 | for k, val := range src { | |
360 | if val != nil { | |
361 | dst[k] = *val | |
362 | } | |
363 | } | |
364 | ||
365 | return dst | |
366 | } | |
367 | ||
368 | // Uint returns a pointer to of the uint value passed in. | |
302 | 369 | func Uint(v uint) *uint { |
303 | 370 | return &v |
304 | 371 | } |
305 | 372 | |
306 | // UintValue returns the value of the uint pouinter passed in or | |
307 | // 0 if the pouinter is nil. | |
373 | // UintValue returns the value of the uint pointer passed in or | |
374 | // 0 if the pointer is nil. | |
308 | 375 | func UintValue(v *uint) uint { |
309 | 376 | if v != nil { |
310 | 377 | return *v |
312 | 379 | return 0 |
313 | 380 | } |
314 | 381 | |
315 | // UintSlice converts a slice of uint values uinto a slice of | |
316 | // uint pouinters | |
382 | // UintSlice converts a slice of uint values into a slice of | |
383 | // uint pointers | |
317 | 384 | func UintSlice(src []uint) []*uint { |
318 | 385 | dst := make([]*uint, len(src)) |
319 | 386 | for i := 0; i < len(src); i++ { |
322 | 389 | return dst |
323 | 390 | } |
324 | 391 | |
325 | // UintValueSlice converts a slice of uint pouinters uinto a slice of | |
392 | // UintValueSlice converts a slice of uint pointers into a slice of | |
326 | 393 | // uint values |
327 | 394 | func UintValueSlice(src []*uint) []uint { |
328 | 395 | dst := make([]uint, len(src)) |
334 | 401 | return dst |
335 | 402 | } |
336 | 403 | |
337 | // UintMap converts a string map of uint values uinto a string | |
338 | // map of uint pouinters | |
404 | // UintMap converts a string map of uint values into a string | |
405 | // map of uint pointers | |
339 | 406 | func UintMap(src map[string]uint) map[string]*uint { |
340 | 407 | dst := make(map[string]*uint) |
341 | 408 | for k, val := range src { |
345 | 412 | return dst |
346 | 413 | } |
347 | 414 | |
348 | // UintValueMap converts a string map of uint pouinters uinto a string | |
415 | // UintValueMap converts a string map of uint pointers into a string | |
349 | 416 | // map of uint values |
350 | 417 | func UintValueMap(src map[string]*uint) map[string]uint { |
351 | 418 | dst := make(map[string]uint) |
357 | 424 | return dst |
358 | 425 | } |
359 | 426 | |
360 | // Uint32 returns a pouinter to of the uint64 value passed in. | |
427 | // Uint32 returns a pointer to of the uint32 value passed in. | |
361 | 428 | func Uint32(v uint32) *uint32 { |
362 | 429 | return &v |
363 | 430 | } |
364 | 431 | |
365 | // Uint32Value returns the value of the uint64 pouinter passed in or | |
366 | // 0 if the pouinter is nil. | |
432 | // Uint32Value returns the value of the uint32 pointer passed in or | |
433 | // 0 if the pointer is nil. | |
367 | 434 | func Uint32Value(v *uint32) uint32 { |
368 | 435 | if v != nil { |
369 | 436 | return *v |
371 | 438 | return 0 |
372 | 439 | } |
373 | 440 | |
374 | // Uint32Slice converts a slice of uint64 values uinto a slice of | |
375 | // uint32 pouinters | |
441 | // Uint32Slice converts a slice of uint32 values into a slice of | |
442 | // uint32 pointers | |
376 | 443 | func Uint32Slice(src []uint32) []*uint32 { |
377 | 444 | dst := make([]*uint32, len(src)) |
378 | 445 | for i := 0; i < len(src); i++ { |
381 | 448 | return dst |
382 | 449 | } |
383 | 450 | |
384 | // Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of | |
451 | // Uint32ValueSlice converts a slice of uint32 pointers into a slice of | |
385 | 452 | // uint32 values |
386 | 453 | func Uint32ValueSlice(src []*uint32) []uint32 { |
387 | 454 | dst := make([]uint32, len(src)) |
393 | 460 | return dst |
394 | 461 | } |
395 | 462 | |
396 | // Uint32Map converts a string map of uint32 values uinto a string | |
397 | // map of uint32 pouinters | |
463 | // Uint32Map converts a string map of uint32 values into a string | |
464 | // map of uint32 pointers | |
398 | 465 | func Uint32Map(src map[string]uint32) map[string]*uint32 { |
399 | 466 | dst := make(map[string]*uint32) |
400 | 467 | for k, val := range src { |
404 | 471 | return dst |
405 | 472 | } |
406 | 473 | |
407 | // Uint32ValueMap converts a string map of uint32 pouinters uinto a string | |
474 | // Uint32ValueMap converts a string map of uint32 pointers into a string | |
408 | 475 | // map of uint32 values |
409 | 476 | func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { |
410 | 477 | dst := make(map[string]uint32) |
416 | 483 | return dst |
417 | 484 | } |
418 | 485 | |
419 | // Uint64 returns a pouinter to of the uint64 value passed in. | |
486 | // Uint64 returns a pointer to of the uint64 value passed in. | |
420 | 487 | func Uint64(v uint64) *uint64 { |
421 | 488 | return &v |
422 | 489 | } |
423 | 490 | |
424 | // Uint64Value returns the value of the uint64 pouinter passed in or | |
425 | // 0 if the pouinter is nil. | |
491 | // Uint64Value returns the value of the uint64 pointer passed in or | |
492 | // 0 if the pointer is nil. | |
426 | 493 | func Uint64Value(v *uint64) uint64 { |
427 | 494 | if v != nil { |
428 | 495 | return *v |
430 | 497 | return 0 |
431 | 498 | } |
432 | 499 | |
433 | // Uint64Slice converts a slice of uint64 values uinto a slice of | |
434 | // uint64 pouinters | |
500 | // Uint64Slice converts a slice of uint64 values into a slice of | |
501 | // uint64 pointers | |
435 | 502 | func Uint64Slice(src []uint64) []*uint64 { |
436 | 503 | dst := make([]*uint64, len(src)) |
437 | 504 | for i := 0; i < len(src); i++ { |
440 | 507 | return dst |
441 | 508 | } |
442 | 509 | |
443 | // Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of | |
510 | // Uint64ValueSlice converts a slice of uint64 pointers into a slice of | |
444 | 511 | // uint64 values |
445 | 512 | func Uint64ValueSlice(src []*uint64) []uint64 { |
446 | 513 | dst := make([]uint64, len(src)) |
452 | 519 | return dst |
453 | 520 | } |
454 | 521 | |
455 | // Uint64Map converts a string map of uint64 values uinto a string | |
456 | // map of uint64 pouinters | |
522 | // Uint64Map converts a string map of uint64 values into a string | |
523 | // map of uint64 pointers | |
457 | 524 | func Uint64Map(src map[string]uint64) map[string]*uint64 { |
458 | 525 | dst := make(map[string]*uint64) |
459 | 526 | for k, val := range src { |
463 | 530 | return dst |
464 | 531 | } |
465 | 532 | |
466 | // Uint64ValueMap converts a string map of uint64 pouinters uinto a string | |
533 | // Uint64ValueMap converts a string map of uint64 pointers into a string | |
467 | 534 | // map of uint64 values |
468 | 535 | func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { |
469 | 536 | dst := make(map[string]uint64) |
472 | 539 | dst[k] = *val |
473 | 540 | } |
474 | 541 | } |
542 | return dst | |
543 | } | |
544 | ||
545 | // Float32 returns a pointer to of the float32 value passed in. | |
546 | func Float32(v float32) *float32 { | |
547 | return &v | |
548 | } | |
549 | ||
550 | // Float32Value returns the value of the float32 pointer passed in or | |
551 | // 0 if the pointer is nil. | |
552 | func Float32Value(v *float32) float32 { | |
553 | if v != nil { | |
554 | return *v | |
555 | } | |
556 | ||
557 | return 0 | |
558 | } | |
559 | ||
560 | // Float32Slice converts a slice of float32 values into a slice of | |
561 | // float32 pointers | |
562 | func Float32Slice(src []float32) []*float32 { | |
563 | dst := make([]*float32, len(src)) | |
564 | ||
565 | for i := 0; i < len(src); i++ { | |
566 | dst[i] = &(src[i]) | |
567 | } | |
568 | ||
569 | return dst | |
570 | } | |
571 | ||
572 | // Float32ValueSlice converts a slice of float32 pointers into a slice of | |
573 | // float32 values | |
574 | func Float32ValueSlice(src []*float32) []float32 { | |
575 | dst := make([]float32, len(src)) | |
576 | ||
577 | for i := 0; i < len(src); i++ { | |
578 | if src[i] != nil { | |
579 | dst[i] = *(src[i]) | |
580 | } | |
581 | } | |
582 | ||
583 | return dst | |
584 | } | |
585 | ||
586 | // Float32Map converts a string map of float32 values into a string | |
587 | // map of float32 pointers | |
588 | func Float32Map(src map[string]float32) map[string]*float32 { | |
589 | dst := make(map[string]*float32) | |
590 | ||
591 | for k, val := range src { | |
592 | v := val | |
593 | dst[k] = &v | |
594 | } | |
595 | ||
596 | return dst | |
597 | } | |
598 | ||
599 | // Float32ValueMap converts a string map of float32 pointers into a string | |
600 | // map of float32 values | |
601 | func Float32ValueMap(src map[string]*float32) map[string]float32 { | |
602 | dst := make(map[string]float32) | |
603 | ||
604 | for k, val := range src { | |
605 | if val != nil { | |
606 | dst[k] = *val | |
607 | } | |
608 | } | |
609 | ||
475 | 610 | return dst |
476 | 611 | } |
477 | 612 |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | package swag |
1 | 15 | |
2 | 16 | import ( |
17 | "reflect" | |
3 | 18 | "testing" |
4 | 19 | "time" |
5 | 20 | |
6 | 21 | "github.com/stretchr/testify/assert" |
7 | 22 | ) |
23 | ||
24 | func assertSingleValue(t *testing.T, inElem, elem reflect.Value, expectPointer bool, idx int) { | |
25 | if !assert.Truef(t, | |
26 | (elem.Kind() == reflect.Ptr) == expectPointer, | |
27 | "Unexpected expectPointer=%t value type", expectPointer) { | |
28 | return | |
29 | } | |
30 | if inElem.Kind() == reflect.Ptr && !inElem.IsNil() { | |
31 | inElem = reflect.Indirect(inElem) | |
32 | } | |
33 | if elem.Kind() == reflect.Ptr && !elem.IsNil() { | |
34 | elem = reflect.Indirect(elem) | |
35 | } | |
36 | ||
37 | if !assert.Truef(t, | |
38 | (elem.Kind() == reflect.Ptr && elem.IsNil()) || IsZero(elem.Interface()) == | |
39 | (inElem.Kind() == reflect.Ptr && inElem.IsNil()) || IsZero(inElem.Interface()), | |
40 | "Unexpected nil pointer at idx %d", idx) { | |
41 | return | |
42 | } | |
43 | ||
44 | if !((elem.Kind() == reflect.Ptr && elem.IsNil()) || IsZero(elem.Interface())) { | |
45 | if !assert.IsTypef(t, inElem.Interface(), elem.Interface(), "Expected in/out to match types") { | |
46 | return | |
47 | } | |
48 | assert.EqualValuesf(t, inElem.Interface(), elem.Interface(), "Unexpected value at idx %d: %v", idx, elem.Interface()) | |
49 | } | |
50 | } | |
51 | ||
52 | // assertValues checks equivalent representation pointer vs values for single var, slices and maps | |
53 | func assertValues(t *testing.T, in, out interface{}, expectPointer bool, idx int) { | |
54 | vin := reflect.ValueOf(in) | |
55 | vout := reflect.ValueOf(out) | |
56 | switch vin.Kind() { | |
57 | case reflect.Slice, reflect.Map: | |
58 | if !assert.Equalf(t, vin.Kind(), vout.Kind(), "Unexpected output type at idx %d", idx) || | |
59 | !assert.Equalf(t, vin.Len(), vout.Len(), "Unexpected len at idx %d", idx) { | |
60 | break | |
61 | } | |
62 | var elem, inElem reflect.Value | |
63 | for i := 0; i < vin.Len(); i++ { | |
64 | if vin.Kind() == reflect.Slice { | |
65 | elem = vout.Index(i) | |
66 | inElem = vin.Index(i) | |
67 | } else if vin.Kind() == reflect.Map { | |
68 | keys := vin.MapKeys() | |
69 | elem = vout.MapIndex(keys[i]) | |
70 | inElem = vout.MapIndex(keys[i]) | |
71 | } | |
72 | assertSingleValue(t, inElem, elem, expectPointer, idx) | |
73 | } | |
74 | default: | |
75 | inElem := vin | |
76 | elem := vout | |
77 | assertSingleValue(t, inElem, elem, expectPointer, idx) | |
78 | } | |
79 | } | |
8 | 80 | |
9 | 81 | var testCasesStringSlice = [][]string{ |
10 | 82 | {"a", "b", "c", "d", "e"}, |
17 | 89 | continue |
18 | 90 | } |
19 | 91 | out := StringSlice(in) |
20 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
21 | for i := range out { | |
22 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
23 | } | |
92 | assertValues(t, in, out, true, idx) | |
24 | 93 | |
25 | 94 | out2 := StringValueSlice(out) |
26 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
27 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
95 | assertValues(t, in, out2, false, idx) | |
28 | 96 | } |
29 | 97 | } |
30 | 98 | |
38 | 106 | continue |
39 | 107 | } |
40 | 108 | out := StringValueSlice(in) |
41 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
42 | for i := range out { | |
43 | if in[i] == nil { | |
44 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
45 | } else { | |
46 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
47 | } | |
48 | } | |
109 | assertValues(t, in, out, false, idx) | |
49 | 110 | |
50 | 111 | out2 := StringSlice(out) |
51 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
52 | for i := range out2 { | |
53 | if in[i] == nil { | |
54 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
55 | } else { | |
56 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
57 | } | |
58 | } | |
112 | assertValues(t, in, out2, true, idx) | |
59 | 113 | } |
60 | 114 | } |
61 | 115 | |
69 | 123 | continue |
70 | 124 | } |
71 | 125 | out := StringMap(in) |
72 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
73 | for i := range out { | |
74 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
75 | } | |
126 | assertValues(t, in, out, true, idx) | |
76 | 127 | |
77 | 128 | out2 := StringValueMap(out) |
78 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
79 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
129 | assertValues(t, in, out2, false, idx) | |
80 | 130 | } |
81 | 131 | } |
82 | 132 | |
90 | 140 | continue |
91 | 141 | } |
92 | 142 | out := BoolSlice(in) |
93 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
94 | for i := range out { | |
95 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
96 | } | |
143 | assertValues(t, in, out, true, idx) | |
97 | 144 | |
98 | 145 | out2 := BoolValueSlice(out) |
99 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
100 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
101 | } | |
102 | } | |
103 | ||
104 | var testCasesBoolValueSlice = [][]*bool{} | |
146 | assertValues(t, in, out2, false, idx) | |
147 | } | |
148 | } | |
149 | ||
150 | var testCasesBoolValueSlice = [][]*bool{ | |
151 | {Bool(true), Bool(true), Bool(false), Bool(false)}, | |
152 | } | |
105 | 153 | |
106 | 154 | func TestBoolValueSlice(t *testing.T) { |
107 | 155 | for idx, in := range testCasesBoolValueSlice { |
109 | 157 | continue |
110 | 158 | } |
111 | 159 | out := BoolValueSlice(in) |
112 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
113 | for i := range out { | |
114 | if in[i] == nil { | |
115 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
116 | } else { | |
117 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
118 | } | |
119 | } | |
160 | assertValues(t, in, out, false, idx) | |
120 | 161 | |
121 | 162 | out2 := BoolSlice(out) |
122 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
123 | for i := range out2 { | |
124 | if in[i] == nil { | |
125 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
126 | } else { | |
127 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
128 | } | |
129 | } | |
163 | assertValues(t, in, out2, true, idx) | |
130 | 164 | } |
131 | 165 | } |
132 | 166 | |
140 | 174 | continue |
141 | 175 | } |
142 | 176 | out := BoolMap(in) |
143 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
144 | for i := range out { | |
145 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
146 | } | |
177 | assertValues(t, in, out, true, idx) | |
147 | 178 | |
148 | 179 | out2 := BoolValueMap(out) |
149 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
150 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
180 | assertValues(t, in, out2, false, idx) | |
151 | 181 | } |
152 | 182 | } |
153 | 183 | |
161 | 191 | continue |
162 | 192 | } |
163 | 193 | out := IntSlice(in) |
164 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
165 | for i := range out { | |
166 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
167 | } | |
194 | assertValues(t, in, out, true, idx) | |
168 | 195 | |
169 | 196 | out2 := IntValueSlice(out) |
170 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
171 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
172 | } | |
173 | } | |
174 | ||
175 | var testCasesIntValueSlice = [][]*int{} | |
197 | assertValues(t, in, out2, false, idx) | |
198 | } | |
199 | } | |
200 | ||
201 | var testCasesIntValueSlice = [][]*int{ | |
202 | {Int(1), Int(2), Int(3), Int(4)}, | |
203 | } | |
176 | 204 | |
177 | 205 | func TestIntValueSlice(t *testing.T) { |
178 | 206 | for idx, in := range testCasesIntValueSlice { |
180 | 208 | continue |
181 | 209 | } |
182 | 210 | out := IntValueSlice(in) |
183 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
184 | for i := range out { | |
185 | if in[i] == nil { | |
186 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
187 | } else { | |
188 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
189 | } | |
190 | } | |
211 | assertValues(t, in, out, false, idx) | |
191 | 212 | |
192 | 213 | out2 := IntSlice(out) |
193 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
194 | for i := range out2 { | |
195 | if in[i] == nil { | |
196 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
197 | } else { | |
198 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
199 | } | |
200 | } | |
214 | assertValues(t, in, out2, true, idx) | |
201 | 215 | } |
202 | 216 | } |
203 | 217 | |
211 | 225 | continue |
212 | 226 | } |
213 | 227 | out := IntMap(in) |
214 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
215 | for i := range out { | |
216 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
217 | } | |
228 | assertValues(t, in, out, true, idx) | |
218 | 229 | |
219 | 230 | out2 := IntValueMap(out) |
220 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
221 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
231 | assertValues(t, in, out2, false, idx) | |
222 | 232 | } |
223 | 233 | } |
224 | 234 | |
232 | 242 | continue |
233 | 243 | } |
234 | 244 | out := Int64Slice(in) |
235 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
236 | for i := range out { | |
237 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
238 | } | |
245 | assertValues(t, in, out, true, idx) | |
239 | 246 | |
240 | 247 | out2 := Int64ValueSlice(out) |
241 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
242 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
243 | } | |
244 | } | |
245 | ||
246 | var testCasesInt64ValueSlice = [][]*int64{} | |
248 | assertValues(t, in, out2, false, idx) | |
249 | } | |
250 | } | |
251 | ||
252 | var testCasesInt64ValueSlice = [][]*int64{ | |
253 | {Int64(1), Int64(2), Int64(3), Int64(4)}, | |
254 | } | |
247 | 255 | |
248 | 256 | func TestInt64ValueSlice(t *testing.T) { |
249 | 257 | for idx, in := range testCasesInt64ValueSlice { |
251 | 259 | continue |
252 | 260 | } |
253 | 261 | out := Int64ValueSlice(in) |
254 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
255 | for i := range out { | |
256 | if in[i] == nil { | |
257 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
258 | } else { | |
259 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
260 | } | |
261 | } | |
262 | assertValues(t, in, out, false, idx) | |
262 | 263 | |
263 | 264 | out2 := Int64Slice(out) |
264 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
265 | for i := range out2 { | |
266 | if in[i] == nil { | |
267 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
268 | } else { | |
269 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
270 | } | |
271 | } | |
265 | assertValues(t, in, out2, true, idx) | |
272 | 266 | } |
273 | 267 | } |
274 | 268 | |
282 | 276 | continue |
283 | 277 | } |
284 | 278 | out := Int64Map(in) |
285 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
286 | for i := range out { | |
287 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
288 | } | |
279 | assertValues(t, in, out, true, idx) | |
289 | 280 | |
290 | 281 | out2 := Int64ValueMap(out) |
291 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
292 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
282 | assertValues(t, in, out2, false, idx) | |
283 | } | |
284 | } | |
285 | ||
286 | var testCasesFloat32Slice = [][]float32{ | |
287 | {1, 2, 3, 4}, | |
288 | } | |
289 | ||
290 | func TestFloat32Slice(t *testing.T) { | |
291 | for idx, in := range testCasesFloat32Slice { | |
292 | if in == nil { | |
293 | continue | |
294 | } | |
295 | ||
296 | out := Float32Slice(in) | |
297 | assertValues(t, in, out, true, idx) | |
298 | ||
299 | out2 := Float32ValueSlice(out) | |
300 | assertValues(t, in, out2, false, idx) | |
293 | 301 | } |
294 | 302 | } |
295 | 303 | |
303 | 311 | continue |
304 | 312 | } |
305 | 313 | out := Float64Slice(in) |
306 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
307 | for i := range out { | |
308 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
309 | } | |
314 | assertValues(t, in, out, true, idx) | |
310 | 315 | |
311 | 316 | out2 := Float64ValueSlice(out) |
312 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
313 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
317 | assertValues(t, in, out2, false, idx) | |
314 | 318 | } |
315 | 319 | } |
316 | 320 | |
324 | 328 | continue |
325 | 329 | } |
326 | 330 | out := UintSlice(in) |
327 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
328 | for i := range out { | |
329 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
330 | } | |
331 | assertValues(t, in, out, true, idx) | |
331 | 332 | |
332 | 333 | out2 := UintValueSlice(out) |
333 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
334 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
334 | assertValues(t, in, out2, false, idx) | |
335 | 335 | } |
336 | 336 | } |
337 | 337 | |
343 | 343 | continue |
344 | 344 | } |
345 | 345 | out := UintValueSlice(in) |
346 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
347 | for i := range out { | |
348 | if in[i] == nil { | |
349 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
350 | } else { | |
351 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
352 | } | |
353 | } | |
346 | assertValues(t, in, out, true, idx) | |
354 | 347 | |
355 | 348 | out2 := UintSlice(out) |
356 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
357 | for i := range out2 { | |
358 | if in[i] == nil { | |
359 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
360 | } else { | |
361 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
362 | } | |
363 | } | |
349 | assertValues(t, in, out2, false, idx) | |
364 | 350 | } |
365 | 351 | } |
366 | 352 | |
374 | 360 | continue |
375 | 361 | } |
376 | 362 | out := UintMap(in) |
377 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
378 | for i := range out { | |
379 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
380 | } | |
363 | assertValues(t, in, out, true, idx) | |
381 | 364 | |
382 | 365 | out2 := UintValueMap(out) |
383 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
384 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
366 | assertValues(t, in, out2, false, idx) | |
367 | } | |
368 | } | |
369 | ||
370 | var testCasesUint16Slice = [][]uint16{ | |
371 | {1, 2, 3, 4}, | |
372 | } | |
373 | ||
374 | func TestUint16Slice(t *testing.T) { | |
375 | for idx, in := range testCasesUint16Slice { | |
376 | if in == nil { | |
377 | continue | |
378 | } | |
379 | ||
380 | out := Uint16Slice(in) | |
381 | assertValues(t, in, out, true, idx) | |
382 | ||
383 | out2 := Uint16ValueSlice(out) | |
384 | assertValues(t, in, out2, false, idx) | |
385 | } | |
386 | } | |
387 | ||
388 | var testCasesUint16ValueSlice = [][]*uint16{} | |
389 | ||
390 | func TestUint16ValueSlice(t *testing.T) { | |
391 | for idx, in := range testCasesUint16ValueSlice { | |
392 | if in == nil { | |
393 | continue | |
394 | } | |
395 | ||
396 | out := Uint16ValueSlice(in) | |
397 | assertValues(t, in, out, true, idx) | |
398 | ||
399 | out2 := Uint16Slice(out) | |
400 | assertValues(t, in, out2, false, idx) | |
401 | } | |
402 | } | |
403 | ||
404 | var testCasesUint16Map = []map[string]uint16{ | |
405 | {"a": 3, "b": 2, "c": 1}, | |
406 | } | |
407 | ||
408 | func TestUint16Map(t *testing.T) { | |
409 | for idx, in := range testCasesUint16Map { | |
410 | if in == nil { | |
411 | continue | |
412 | } | |
413 | ||
414 | out := Uint16Map(in) | |
415 | assertValues(t, in, out, true, idx) | |
416 | ||
417 | out2 := Uint16ValueMap(out) | |
418 | assertValues(t, in, out2, false, idx) | |
385 | 419 | } |
386 | 420 | } |
387 | 421 | |
395 | 429 | continue |
396 | 430 | } |
397 | 431 | out := Uint64Slice(in) |
398 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
399 | for i := range out { | |
400 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
401 | } | |
432 | assertValues(t, in, out, true, idx) | |
402 | 433 | |
403 | 434 | out2 := Uint64ValueSlice(out) |
404 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
405 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
435 | assertValues(t, in, out2, false, idx) | |
406 | 436 | } |
407 | 437 | } |
408 | 438 | |
414 | 444 | continue |
415 | 445 | } |
416 | 446 | out := Uint64ValueSlice(in) |
417 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
418 | for i := range out { | |
419 | if in[i] == nil { | |
420 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
421 | } else { | |
422 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
423 | } | |
424 | } | |
447 | assertValues(t, in, out, true, idx) | |
425 | 448 | |
426 | 449 | out2 := Uint64Slice(out) |
427 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
428 | for i := range out2 { | |
429 | if in[i] == nil { | |
430 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
431 | } else { | |
432 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
433 | } | |
434 | } | |
450 | assertValues(t, in, out2, false, idx) | |
435 | 451 | } |
436 | 452 | } |
437 | 453 | |
445 | 461 | continue |
446 | 462 | } |
447 | 463 | out := Uint64Map(in) |
448 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
449 | for i := range out { | |
450 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
451 | } | |
464 | assertValues(t, in, out, true, idx) | |
452 | 465 | |
453 | 466 | out2 := Uint64ValueMap(out) |
454 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
455 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
467 | assertValues(t, in, out2, false, idx) | |
468 | } | |
469 | } | |
470 | ||
471 | var testCasesFloat32ValueSlice = [][]*float32{} | |
472 | ||
473 | func TestFloat32ValueSlice(t *testing.T) { | |
474 | for idx, in := range testCasesFloat32ValueSlice { | |
475 | if in == nil { | |
476 | continue | |
477 | } | |
478 | ||
479 | out := Float32ValueSlice(in) | |
480 | assertValues(t, in, out, true, idx) | |
481 | ||
482 | out2 := Float32Slice(out) | |
483 | assertValues(t, in, out2, false, idx) | |
484 | } | |
485 | } | |
486 | ||
487 | var testCasesFloat32Map = []map[string]float32{ | |
488 | {"a": 3, "b": 2, "c": 1}, | |
489 | } | |
490 | ||
491 | func TestFloat32Map(t *testing.T) { | |
492 | for idx, in := range testCasesFloat32Map { | |
493 | if in == nil { | |
494 | continue | |
495 | } | |
496 | ||
497 | out := Float32Map(in) | |
498 | assertValues(t, in, out, true, idx) | |
499 | ||
500 | out2 := Float32ValueMap(out) | |
501 | assertValues(t, in, out2, false, idx) | |
456 | 502 | } |
457 | 503 | } |
458 | 504 | |
464 | 510 | continue |
465 | 511 | } |
466 | 512 | out := Float64ValueSlice(in) |
467 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
468 | for i := range out { | |
469 | if in[i] == nil { | |
470 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
471 | } else { | |
472 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
473 | } | |
474 | } | |
513 | assertValues(t, in, out, true, idx) | |
475 | 514 | |
476 | 515 | out2 := Float64Slice(out) |
477 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
478 | for i := range out2 { | |
479 | if in[i] == nil { | |
480 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
481 | } else { | |
482 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
483 | } | |
484 | } | |
516 | assertValues(t, in, out2, false, idx) | |
485 | 517 | } |
486 | 518 | } |
487 | 519 | |
495 | 527 | continue |
496 | 528 | } |
497 | 529 | out := Float64Map(in) |
498 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
499 | for i := range out { | |
500 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
501 | } | |
530 | assertValues(t, in, out, true, idx) | |
502 | 531 | |
503 | 532 | out2 := Float64ValueMap(out) |
504 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
505 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
533 | assertValues(t, in, out2, false, idx) | |
506 | 534 | } |
507 | 535 | } |
508 | 536 | |
516 | 544 | continue |
517 | 545 | } |
518 | 546 | out := TimeSlice(in) |
519 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
520 | for i := range out { | |
521 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
522 | } | |
547 | assertValues(t, in, out, true, idx) | |
523 | 548 | |
524 | 549 | out2 := TimeValueSlice(out) |
525 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
526 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
527 | } | |
528 | } | |
529 | ||
530 | var testCasesTimeValueSlice = [][]*time.Time{} | |
550 | assertValues(t, in, out2, false, idx) | |
551 | } | |
552 | } | |
553 | ||
554 | var testCasesTimeValueSlice = [][]*time.Time{ | |
555 | {Time(time.Now()), Time(time.Now().AddDate(100, 0, 0))}, | |
556 | } | |
531 | 557 | |
532 | 558 | func TestTimeValueSlice(t *testing.T) { |
533 | 559 | for idx, in := range testCasesTimeValueSlice { |
535 | 561 | continue |
536 | 562 | } |
537 | 563 | out := TimeValueSlice(in) |
538 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
539 | for i := range out { | |
540 | if in[i] == nil { | |
541 | assert.Empty(t, out[i], "Unexpected value at idx %d", idx) | |
542 | } else { | |
543 | assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) | |
544 | } | |
545 | } | |
564 | assertValues(t, in, out, false, idx) | |
546 | 565 | |
547 | 566 | out2 := TimeSlice(out) |
548 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
549 | for i := range out2 { | |
550 | if in[i] == nil { | |
551 | assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) | |
552 | } else { | |
553 | assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) | |
554 | } | |
555 | } | |
567 | assertValues(t, in, out2, true, idx) | |
556 | 568 | } |
557 | 569 | } |
558 | 570 | |
566 | 578 | continue |
567 | 579 | } |
568 | 580 | out := TimeMap(in) |
569 | assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) | |
570 | for i := range out { | |
571 | assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) | |
572 | } | |
581 | assertValues(t, in, out, true, idx) | |
573 | 582 | |
574 | 583 | out2 := TimeValueMap(out) |
575 | assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) | |
576 | assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) | |
577 | } | |
578 | } | |
584 | assertValues(t, in, out2, false, idx) | |
585 | } | |
586 | } | |
587 | ||
588 | var testCasesInt32Slice = [][]int32{ | |
589 | {1, 2, 3, 4}, | |
590 | } | |
591 | ||
592 | func TestInt32Slice(t *testing.T) { | |
593 | for idx, in := range testCasesInt32Slice { | |
594 | if in == nil { | |
595 | continue | |
596 | } | |
597 | out := Int32Slice(in) | |
598 | assertValues(t, in, out, true, idx) | |
599 | ||
600 | out2 := Int32ValueSlice(out) | |
601 | assertValues(t, in, out2, false, idx) | |
602 | } | |
603 | } | |
604 | ||
605 | var testCasesInt32ValueSlice = [][]*int32{ | |
606 | {Int32(1), Int32(2), Int32(3), Int32(4)}, | |
607 | } | |
608 | ||
609 | func TestInt32ValueSlice(t *testing.T) { | |
610 | for idx, in := range testCasesInt32ValueSlice { | |
611 | if in == nil { | |
612 | continue | |
613 | } | |
614 | out := Int32ValueSlice(in) | |
615 | assertValues(t, in, out, false, idx) | |
616 | ||
617 | out2 := Int32Slice(out) | |
618 | assertValues(t, in, out2, true, idx) | |
619 | } | |
620 | } | |
621 | ||
622 | var testCasesInt32Map = []map[string]int32{ | |
623 | {"a": 3, "b": 2, "c": 1}, | |
624 | } | |
625 | ||
626 | func TestInt32Map(t *testing.T) { | |
627 | for idx, in := range testCasesInt32Map { | |
628 | if in == nil { | |
629 | continue | |
630 | } | |
631 | out := Int32Map(in) | |
632 | assertValues(t, in, out, true, idx) | |
633 | ||
634 | out2 := Int32ValueMap(out) | |
635 | assertValues(t, in, out2, false, idx) | |
636 | } | |
637 | } | |
638 | ||
639 | var testCasesUint32Slice = [][]uint32{ | |
640 | {1, 2, 3, 4}, | |
641 | } | |
642 | ||
643 | func TestUint32Slice(t *testing.T) { | |
644 | for idx, in := range testCasesUint32Slice { | |
645 | if in == nil { | |
646 | continue | |
647 | } | |
648 | out := Uint32Slice(in) | |
649 | assertValues(t, in, out, true, idx) | |
650 | ||
651 | out2 := Uint32ValueSlice(out) | |
652 | assertValues(t, in, out2, false, idx) | |
653 | } | |
654 | } | |
655 | ||
656 | var testCasesUint32ValueSlice = [][]*uint32{ | |
657 | {Uint32(1), Uint32(2), Uint32(3), Uint32(4)}, | |
658 | } | |
659 | ||
660 | func TestUint32ValueSlice(t *testing.T) { | |
661 | for idx, in := range testCasesUint32ValueSlice { | |
662 | if in == nil { | |
663 | continue | |
664 | } | |
665 | out := Uint32ValueSlice(in) | |
666 | assertValues(t, in, out, false, idx) | |
667 | ||
668 | out2 := Uint32Slice(out) | |
669 | assertValues(t, in, out2, true, idx) | |
670 | } | |
671 | } | |
672 | ||
673 | var testCasesUint32Map = []map[string]uint32{ | |
674 | {"a": 3, "b": 2, "c": 1}, | |
675 | } | |
676 | ||
677 | func TestUint32Map(t *testing.T) { | |
678 | for idx, in := range testCasesUint32Map { | |
679 | if in == nil { | |
680 | continue | |
681 | } | |
682 | out := Uint32Map(in) | |
683 | assertValues(t, in, out, true, idx) | |
684 | ||
685 | out2 := Uint32ValueMap(out) | |
686 | assertValues(t, in, out2, false, idx) | |
687 | } | |
688 | } | |
689 | ||
690 | var testCasesString = []string{"a", "b", "c", "d", "e", ""} | |
691 | ||
692 | func TestStringValue(t *testing.T) { | |
693 | for idx, in := range testCasesString { | |
694 | out := String(in) | |
695 | assertValues(t, in, out, true, idx) | |
696 | ||
697 | out2 := StringValue(out) | |
698 | assertValues(t, in, out2, false, idx) | |
699 | } | |
700 | assert.Zerof(t, StringValue(nil), "expected conversion from nil to return zero value") | |
701 | } | |
702 | ||
703 | var testCasesBool = []bool{true, false} | |
704 | ||
705 | func TestBoolValue(t *testing.T) { | |
706 | for idx, in := range testCasesBool { | |
707 | out := Bool(in) | |
708 | assertValues(t, in, out, true, idx) | |
709 | ||
710 | out2 := BoolValue(out) | |
711 | assertValues(t, in, out2, false, idx) | |
712 | } | |
713 | assert.Zerof(t, BoolValue(nil), "expected conversion from nil to return zero value") | |
714 | } | |
715 | ||
716 | var testCasesInt = []int{1, 2, 3, 0} | |
717 | ||
718 | func TestIntValue(t *testing.T) { | |
719 | for idx, in := range testCasesInt { | |
720 | out := Int(in) | |
721 | assertValues(t, in, out, true, idx) | |
722 | ||
723 | out2 := IntValue(out) | |
724 | assertValues(t, in, out2, false, idx) | |
725 | } | |
726 | assert.Zerof(t, IntValue(nil), "expected conversion from nil to return zero value") | |
727 | } | |
728 | ||
729 | var testCasesInt32 = []int32{1, 2, 3, 0} | |
730 | ||
731 | func TestInt32Value(t *testing.T) { | |
732 | for idx, in := range testCasesInt32 { | |
733 | out := Int32(in) | |
734 | assertValues(t, in, out, true, idx) | |
735 | ||
736 | out2 := Int32Value(out) | |
737 | assertValues(t, in, out2, false, idx) | |
738 | } | |
739 | assert.Zerof(t, Int32Value(nil), "expected conversion from nil to return zero value") | |
740 | } | |
741 | ||
742 | var testCasesInt64 = []int64{1, 2, 3, 0} | |
743 | ||
744 | func TestInt64Value(t *testing.T) { | |
745 | for idx, in := range testCasesInt64 { | |
746 | out := Int64(in) | |
747 | assertValues(t, in, out, true, idx) | |
748 | ||
749 | out2 := Int64Value(out) | |
750 | assertValues(t, in, out2, false, idx) | |
751 | } | |
752 | assert.Zerof(t, Int64Value(nil), "expected conversion from nil to return zero value") | |
753 | } | |
754 | ||
755 | var testCasesUint = []uint{1, 2, 3, 0} | |
756 | ||
757 | func TestUintValue(t *testing.T) { | |
758 | for idx, in := range testCasesUint { | |
759 | out := Uint(in) | |
760 | assertValues(t, in, out, true, idx) | |
761 | ||
762 | out2 := UintValue(out) | |
763 | assertValues(t, in, out2, false, idx) | |
764 | } | |
765 | assert.Zerof(t, UintValue(nil), "expected conversion from nil to return zero value") | |
766 | } | |
767 | ||
768 | var testCasesUint32 = []uint32{1, 2, 3, 0} | |
769 | ||
770 | func TestUint32Value(t *testing.T) { | |
771 | for idx, in := range testCasesUint32 { | |
772 | out := Uint32(in) | |
773 | assertValues(t, in, out, true, idx) | |
774 | ||
775 | out2 := Uint32Value(out) | |
776 | assertValues(t, in, out2, false, idx) | |
777 | } | |
778 | assert.Zerof(t, Uint32Value(nil), "expected conversion from nil to return zero value") | |
779 | } | |
780 | ||
781 | var testCasesUint64 = []uint64{1, 2, 3, 0} | |
782 | ||
783 | func TestUint64Value(t *testing.T) { | |
784 | for idx, in := range testCasesUint64 { | |
785 | out := Uint64(in) | |
786 | assertValues(t, in, out, true, idx) | |
787 | ||
788 | out2 := Uint64Value(out) | |
789 | assertValues(t, in, out2, false, idx) | |
790 | } | |
791 | assert.Zerof(t, Uint64Value(nil), "expected conversion from nil to return zero value") | |
792 | } | |
793 | ||
794 | var testCasesFloat32 = []float32{1, 2, 3, 0} | |
795 | ||
796 | func TestFloat32Value(t *testing.T) { | |
797 | for idx, in := range testCasesFloat32 { | |
798 | out := Float32(in) | |
799 | assertValues(t, in, out, true, idx) | |
800 | ||
801 | out2 := Float32Value(out) | |
802 | assertValues(t, in, out2, false, idx) | |
803 | } | |
804 | ||
805 | assert.Zerof(t, Float32Value(nil), "expected conversion from nil to return zero value") | |
806 | } | |
807 | ||
808 | var testCasesFloat64 = []float64{1, 2, 3, 0} | |
809 | ||
810 | func TestFloat64Value(t *testing.T) { | |
811 | for idx, in := range testCasesFloat64 { | |
812 | out := Float64(in) | |
813 | assertValues(t, in, out, true, idx) | |
814 | ||
815 | out2 := Float64Value(out) | |
816 | assertValues(t, in, out2, false, idx) | |
817 | } | |
818 | assert.Zerof(t, Float64Value(nil), "expected conversion from nil to return zero value") | |
819 | } | |
820 | ||
821 | var testCasesTime = []time.Time{ | |
822 | time.Now().AddDate(-100, 0, 0), time.Now(), | |
823 | } | |
824 | ||
825 | func TestTimeValue(t *testing.T) { | |
826 | for idx, in := range testCasesTime { | |
827 | out := Time(in) | |
828 | assertValues(t, in, out, true, idx) | |
829 | ||
830 | out2 := TimeValue(out) | |
831 | assertValues(t, in, out2, false, idx) | |
832 | } | |
833 | assert.Zerof(t, TimeValue(nil), "expected conversion from nil to return zero value") | |
834 | } |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
14 | /* | |
15 | Package swag contains a bunch of helper functions for go-openapi and go-swagger projects. | |
16 | ||
17 | You may also use it standalone for your projects. | |
18 | ||
19 | * convert between value and pointers for builtin types | |
20 | * convert from string to builtin types (wraps strconv) | |
21 | * fast json concatenation | |
22 | * search in path | |
23 | * load from file or http | |
24 | * name mangling | |
25 | ||
26 | ||
27 | This repo has only few dependencies outside of the standard library: | |
28 | ||
29 | * YAML utilities depend on gopkg.in/yaml.v2 | |
30 | */ | |
31 | package swag |
0 | module github.com/go-openapi/swag | |
1 | ||
2 | require ( | |
3 | github.com/davecgh/go-spew v1.1.1 // indirect | |
4 | github.com/kr/text v0.2.0 // indirect | |
5 | github.com/mailru/easyjson v0.7.6 | |
6 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect | |
7 | github.com/stretchr/testify v1.6.1 | |
8 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect | |
9 | gopkg.in/yaml.v2 v2.4.0 | |
10 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect | |
11 | ) | |
12 | ||
13 | replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422 | |
14 | ||
15 | replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1 | |
16 | ||
17 | go 1.11 |
0 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | |
1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
4 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= | |
5 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= | |
6 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | |
7 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | |
8 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | |
9 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | |
10 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | |
11 | github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= | |
12 | github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= | |
13 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= | |
14 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | |
15 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |
16 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
17 | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= | |
18 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
19 | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | |
20 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
21 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
22 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= | |
23 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
24 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | |
25 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | |
26 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
27 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= | |
28 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
20 | 20 | "reflect" |
21 | 21 | "strings" |
22 | 22 | "sync" |
23 | "sync/atomic" | |
24 | 23 | |
25 | 24 | "github.com/mailru/easyjson/jlexer" |
26 | 25 | "github.com/mailru/easyjson/jwriter" |
34 | 33 | |
35 | 34 | const comma = byte(',') |
36 | 35 | |
37 | var atomicClosers atomic.Value | |
36 | var closers map[byte]byte | |
38 | 37 | |
39 | 38 | func init() { |
40 | atomicClosers.Store( | |
41 | map[byte]byte{ | |
42 | '{': '}', | |
43 | '[': ']', | |
44 | }) | |
39 | closers = map[byte]byte{ | |
40 | '{': '}', | |
41 | '[': ']', | |
42 | } | |
45 | 43 | } |
46 | 44 | |
47 | 45 | type ejMarshaler interface { |
52 | 50 | UnmarshalEasyJSON(w *jlexer.Lexer) |
53 | 51 | } |
54 | 52 | |
55 | // WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller | |
53 | // WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler | |
56 | 54 | // so it takes the fastest option available. |
57 | 55 | func WriteJSON(data interface{}) ([]byte, error) { |
58 | 56 | if d, ok := data.(ejMarshaler); ok { |
66 | 64 | return json.Marshal(data) |
67 | 65 | } |
68 | 66 | |
69 | // ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller | |
70 | // so it takes the fastes option available | |
67 | // ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler | |
68 | // so it takes the fastest option available | |
71 | 69 | func ReadJSON(data []byte, value interface{}) error { |
70 | trimmedData := bytes.Trim(data, "\x00") | |
72 | 71 | if d, ok := value.(ejUnmarshaler); ok { |
73 | jl := &jlexer.Lexer{Data: data} | |
72 | jl := &jlexer.Lexer{Data: trimmedData} | |
74 | 73 | d.UnmarshalEasyJSON(jl) |
75 | 74 | return jl.Error() |
76 | 75 | } |
77 | 76 | if d, ok := value.(json.Unmarshaler); ok { |
78 | return d.UnmarshalJSON(data) | |
79 | } | |
80 | return json.Unmarshal(data, value) | |
77 | return d.UnmarshalJSON(trimmedData) | |
78 | } | |
79 | return json.Unmarshal(trimmedData, value) | |
81 | 80 | } |
82 | 81 | |
83 | 82 | // DynamicJSONToStruct converts an untyped json structure into a struct |
99 | 98 | last := len(blobs) - 1 |
100 | 99 | for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) { |
101 | 100 | // strips trailing null objects |
102 | last = last - 1 | |
101 | last-- | |
103 | 102 | if last < 0 { |
104 | 103 | // there was nothing but "null"s or nil... |
105 | 104 | return nil |
112 | 111 | var opening, closing byte |
113 | 112 | var idx, a int |
114 | 113 | buf := bytes.NewBuffer(nil) |
115 | closers := atomicClosers.Load().(map[byte]byte) | |
116 | 114 | |
117 | 115 | for i, b := range blobs[:last+1] { |
118 | 116 | if b == nil || bytes.Equal(b, nullJSON) { |
190 | 188 | return json.Unmarshal(b, target) |
191 | 189 | } |
192 | 190 | |
193 | // NameProvider represents an object capabale of translating from go property names | |
191 | // NameProvider represents an object capable of translating from go property names | |
194 | 192 | // to json property names |
195 | 193 | // This type is thread-safe. |
196 | 194 | type NameProvider struct { |
263 | 261 | names = n.makeNameIndex(tpe) |
264 | 262 | } |
265 | 263 | |
266 | var res []string | |
264 | res := make([]string, 0, len(names.jsonNames)) | |
267 | 265 | for k := range names.jsonNames { |
268 | 266 | res = append(res, k) |
269 | 267 | } |
18 | 18 | "testing" |
19 | 19 | |
20 | 20 | "github.com/stretchr/testify/assert" |
21 | "github.com/stretchr/testify/require" | |
21 | 22 | ) |
22 | 23 | |
23 | 24 | type testNameStruct struct { |
166 | 167 | assert.Equal(t, ConcatJSON([]byte(`{"id":null}`), []byte(`null`)), []byte(`{"id":null}`)) |
167 | 168 | assert.Equal(t, ConcatJSON([]byte(`{"id":null}`), []byte(`null`), []byte(`{"name":"Rachel"}`)), []byte(`{"id":null,"name":"Rachel"}`)) |
168 | 169 | } |
170 | ||
171 | type SharedCounters struct { | |
172 | Counter1 int64 `json:"Counter1,omitempty"` | |
173 | Counter2 int64 `json:"Counter2:,omitempty"` | |
174 | } | |
175 | ||
176 | type AggregationObject struct { | |
177 | SharedCounters | |
178 | Count int64 `json:"Count,omitempty"` | |
179 | } | |
180 | ||
181 | func (m *AggregationObject) UnmarshalJSON(raw []byte) error { | |
182 | // AO0 | |
183 | var aO0 SharedCounters | |
184 | if err := ReadJSON(raw, &aO0); err != nil { | |
185 | return err | |
186 | } | |
187 | m.SharedCounters = aO0 | |
188 | ||
189 | // now for regular properties | |
190 | var propsAggregationObject struct { | |
191 | Count int64 `json:"Count,omitempty"` | |
192 | } | |
193 | if err := ReadJSON(raw, &propsAggregationObject); err != nil { | |
194 | return err | |
195 | } | |
196 | m.Count = propsAggregationObject.Count | |
197 | ||
198 | return nil | |
199 | } | |
200 | ||
201 | // MarshalJSON marshals this object to a JSON structure | |
202 | func (m AggregationObject) MarshalJSON() ([]byte, error) { | |
203 | _parts := make([][]byte, 0, 1) | |
204 | ||
205 | aO0, err := WriteJSON(m.SharedCounters) | |
206 | if err != nil { | |
207 | return nil, err | |
208 | } | |
209 | _parts = append(_parts, aO0) | |
210 | ||
211 | // now for regular properties | |
212 | var propsAggregationObject struct { | |
213 | Count int64 `json:"Count,omitempty"` | |
214 | } | |
215 | propsAggregationObject.Count = m.Count | |
216 | ||
217 | jsonDataPropsAggregationObject, errAggregationObject := WriteJSON(propsAggregationObject) | |
218 | if errAggregationObject != nil { | |
219 | return nil, errAggregationObject | |
220 | } | |
221 | _parts = append(_parts, jsonDataPropsAggregationObject) | |
222 | return ConcatJSON(_parts...), nil | |
223 | } | |
224 | ||
225 | func TestIssue2350(t *testing.T) { | |
226 | obj := AggregationObject{Count: 290, SharedCounters: SharedCounters{Counter1: 304, Counter2: 948}} | |
227 | ||
228 | rtjson, err := WriteJSON(obj) | |
229 | require.NoError(t, err) | |
230 | ||
231 | otjson, err := obj.MarshalJSON() | |
232 | require.NoError(t, err) | |
233 | require.JSONEq(t, string(rtjson), string(otjson)) | |
234 | ||
235 | var obj1 AggregationObject | |
236 | require.NoError(t, ReadJSON(rtjson, &obj1)) | |
237 | require.Equal(t, obj, obj1) | |
238 | ||
239 | var obj11 AggregationObject | |
240 | require.NoError(t, obj11.UnmarshalJSON(rtjson)) | |
241 | require.Equal(t, obj, obj11) | |
242 | ||
243 | jsons := `{"Counter1":123,"Counter2:":456,"Count":999}` | |
244 | var obj2 AggregationObject | |
245 | require.NoError(t, ReadJSON([]byte(jsons), &obj2)) | |
246 | require.Equal(t, AggregationObject{SharedCounters: SharedCounters{Counter1: 123, Counter2: 456}, Count: 999}, obj2) | |
247 | } |
18 | 18 | "io/ioutil" |
19 | 19 | "log" |
20 | 20 | "net/http" |
21 | "net/url" | |
21 | 22 | "path/filepath" |
23 | "runtime" | |
22 | 24 | "strings" |
23 | 25 | "time" |
24 | 26 | ) |
25 | 27 | |
26 | 28 | // LoadHTTPTimeout the default timeout for load requests |
27 | 29 | var LoadHTTPTimeout = 30 * time.Second |
30 | ||
31 | // LoadHTTPBasicAuthUsername the username to use when load requests require basic auth | |
32 | var LoadHTTPBasicAuthUsername = "" | |
33 | ||
34 | // LoadHTTPBasicAuthPassword the password to use when load requests require basic auth | |
35 | var LoadHTTPBasicAuthPassword = "" | |
36 | ||
37 | // LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests | |
38 | var LoadHTTPCustomHeaders = map[string]string{} | |
28 | 39 | |
29 | 40 | // LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in |
30 | 41 | func LoadFromFileOrHTTP(path string) ([]byte, error) { |
47 | 58 | if err != nil { |
48 | 59 | return nil, err |
49 | 60 | } |
61 | ||
62 | if strings.HasPrefix(pth, `file://`) { | |
63 | if runtime.GOOS == "windows" { | |
64 | // support for canonical file URIs on windows. | |
65 | // Zero tolerance here for dodgy URIs. | |
66 | u, _ := url.Parse(upth) | |
67 | if u.Host != "" { | |
68 | // assume UNC name (volume share) | |
69 | // file://host/share/folder\... ==> \\host\share\path\folder | |
70 | // NOTE: UNC port not yet supported | |
71 | upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`) | |
72 | } else { | |
73 | // file:///c:/folder/... ==> just remove the leading slash | |
74 | upth = strings.TrimPrefix(upth, `file:///`) | |
75 | } | |
76 | } else { | |
77 | upth = strings.TrimPrefix(upth, `file://`) | |
78 | } | |
79 | } | |
80 | ||
50 | 81 | return local(filepath.FromSlash(upth)) |
51 | 82 | } |
52 | 83 | } |
54 | 85 | func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { |
55 | 86 | return func(path string) ([]byte, error) { |
56 | 87 | client := &http.Client{Timeout: timeout} |
57 | req, err := http.NewRequest("GET", path, nil) | |
88 | req, err := http.NewRequest("GET", path, nil) // nolint: noctx | |
58 | 89 | if err != nil { |
59 | 90 | return nil, err |
60 | 91 | } |
92 | ||
93 | if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" { | |
94 | req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword) | |
95 | } | |
96 | ||
97 | for key, val := range LoadHTTPCustomHeaders { | |
98 | req.Header.Set(key, val) | |
99 | } | |
100 | ||
61 | 101 | resp, err := client.Do(req) |
62 | 102 | defer func() { |
63 | 103 | if resp != nil { |
21 | 21 | "github.com/stretchr/testify/assert" |
22 | 22 | ) |
23 | 23 | |
24 | const ( | |
25 | validUsername = "fake-user" | |
26 | validPassword = "correct-password" | |
27 | invalidPassword = "incorrect-password" | |
28 | sharedHeaderKey = "X-Myapp" | |
29 | sharedHeaderValue = "MySecretKey" | |
30 | ) | |
31 | ||
24 | 32 | func TestLoadFromHTTP(t *testing.T) { |
25 | 33 | |
26 | 34 | _, err := LoadFromFileOrHTTP("httx://12394:abd") |
36 | 44 | |
37 | 45 | ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { |
38 | 46 | rw.WriteHeader(http.StatusOK) |
39 | rw.Write([]byte("the content")) | |
47 | _, _ = rw.Write([]byte("the content")) | |
40 | 48 | })) |
41 | 49 | defer ts2.Close() |
42 | 50 | |
43 | 51 | d, err := LoadFromFileOrHTTP(ts2.URL) |
44 | 52 | assert.NoError(t, err) |
45 | 53 | assert.Equal(t, []byte("the content"), d) |
46 | } | |
54 | ||
55 | ts3 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
56 | u, p, ok := r.BasicAuth() | |
57 | if ok && u == validUsername && p == validPassword { | |
58 | rw.WriteHeader(http.StatusOK) | |
59 | } else { | |
60 | rw.WriteHeader(http.StatusForbidden) | |
61 | } | |
62 | })) | |
63 | defer ts3.Close() | |
64 | ||
65 | // no auth | |
66 | _, err = LoadFromFileOrHTTP(ts3.URL) | |
67 | assert.Error(t, err) | |
68 | ||
69 | // basic auth, invalide credentials | |
70 | LoadHTTPBasicAuthUsername = validUsername | |
71 | LoadHTTPBasicAuthPassword = invalidPassword | |
72 | ||
73 | _, err = LoadFromFileOrHTTP(ts3.URL) | |
74 | assert.Error(t, err) | |
75 | ||
76 | // basic auth, valid credentials | |
77 | LoadHTTPBasicAuthUsername = validUsername | |
78 | LoadHTTPBasicAuthPassword = validPassword | |
79 | ||
80 | _, err = LoadFromFileOrHTTP(ts3.URL) | |
81 | assert.NoError(t, err) | |
82 | ||
83 | ts4 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
84 | myHeaders := r.Header[sharedHeaderKey] | |
85 | ok := false | |
86 | for _, v := range myHeaders { | |
87 | if v == sharedHeaderValue { | |
88 | ok = true | |
89 | break | |
90 | } | |
91 | } | |
92 | if ok { | |
93 | rw.WriteHeader(http.StatusOK) | |
94 | } else { | |
95 | rw.WriteHeader(http.StatusForbidden) | |
96 | } | |
97 | })) | |
98 | defer ts4.Close() | |
99 | ||
100 | _, err = LoadFromFileOrHTTP(ts4.URL) | |
101 | assert.Error(t, err) | |
102 | ||
103 | LoadHTTPCustomHeaders[sharedHeaderKey] = sharedHeaderValue | |
104 | ||
105 | _, err = LoadFromFileOrHTTP(ts4.URL) | |
106 | assert.NoError(t, err) | |
107 | ||
108 | // clean up for future tests | |
109 | LoadHTTPBasicAuthUsername = "" | |
110 | LoadHTTPBasicAuthPassword = "" | |
111 | LoadHTTPCustomHeaders = map[string]string{} | |
112 | } | |
113 | ||
114 | func TestLoadHTTPBytes(t *testing.T) { | |
115 | _, err := LoadFromFileOrHTTP("httx://12394:abd") | |
116 | assert.Error(t, err) | |
117 | ||
118 | serv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
119 | rw.WriteHeader(http.StatusNotFound) | |
120 | })) | |
121 | defer serv.Close() | |
122 | ||
123 | _, err = LoadFromFileOrHTTP(serv.URL) | |
124 | assert.Error(t, err) | |
125 | ||
126 | ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
127 | rw.WriteHeader(http.StatusOK) | |
128 | _, _ = rw.Write([]byte("the content")) | |
129 | })) | |
130 | defer ts2.Close() | |
131 | ||
132 | d, err := LoadFromFileOrHTTP(ts2.URL) | |
133 | assert.NoError(t, err) | |
134 | assert.Equal(t, []byte("the content"), d) | |
135 | } | |
136 | ||
137 | func TestLoadStrategy(t *testing.T) { | |
138 | ||
139 | loader := func(p string) ([]byte, error) { | |
140 | return []byte(yamlPetStore), nil | |
141 | } | |
142 | remLoader := func(p string) ([]byte, error) { | |
143 | return []byte("not it"), nil | |
144 | } | |
145 | ||
146 | ld := LoadStrategy("blah", loader, remLoader) | |
147 | b, _ := ld("") | |
148 | assert.Equal(t, []byte(yamlPetStore), b) | |
149 | ||
150 | serv := httptest.NewServer(http.HandlerFunc(yamlPestoreServer)) | |
151 | defer serv.Close() | |
152 | ||
153 | s, err := YAMLDoc(serv.URL) | |
154 | assert.NoError(t, err) | |
155 | assert.NotNil(t, s) | |
156 | ||
157 | ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
158 | rw.WriteHeader(http.StatusNotFound) | |
159 | _, _ = rw.Write([]byte("\n")) | |
160 | })) | |
161 | defer ts2.Close() | |
162 | _, err = YAMLDoc(ts2.URL) | |
163 | assert.Error(t, err) | |
164 | } | |
165 | ||
166 | func TestLoadStrategyFile(t *testing.T) { | |
167 | const ( | |
168 | thisIsIt = "thisIsIt" | |
169 | ) | |
170 | ||
171 | called, pth := false, "" | |
172 | loader := func(p string) ([]byte, error) { | |
173 | called = true | |
174 | pth = p | |
175 | return []byte(thisIsIt), nil | |
176 | } | |
177 | remLoader := func(p string) ([]byte, error) { | |
178 | return []byte("not it"), nil | |
179 | } | |
180 | ||
181 | ld := LoadStrategy("blah", loader, remLoader) | |
182 | ||
183 | b, _ := ld("file:///a/c/myfile.yaml") | |
184 | assert.True(t, called) | |
185 | assert.Equal(t, "/a/c/myfile.yaml", pth) | |
186 | assert.Equal(t, []byte(thisIsIt), b) | |
187 | ||
188 | called, pth = false, "" | |
189 | b, _ = ld(`file://C:\a\c\myfile.yaml`) | |
190 | assert.True(t, called) | |
191 | assert.Equal(t, `C:\a\c\myfile.yaml`, pth) | |
192 | assert.Equal(t, []byte(thisIsIt), b) | |
193 | ||
194 | called, pth = false, "" | |
195 | b, _ = ld(`file://C%3A%5Ca%5Cc%5Cmyfile.yaml`) | |
196 | assert.True(t, called) | |
197 | assert.Equal(t, `C:\a\c\myfile.yaml`, pth) | |
198 | assert.Equal(t, []byte(thisIsIt), b) | |
199 | } |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
14 | package swag | |
15 | ||
16 | import "unicode" | |
17 | ||
18 | type ( | |
19 | nameLexem interface { | |
20 | GetUnsafeGoName() string | |
21 | GetOriginal() string | |
22 | IsInitialism() bool | |
23 | } | |
24 | ||
25 | initialismNameLexem struct { | |
26 | original string | |
27 | matchedInitialism string | |
28 | } | |
29 | ||
30 | casualNameLexem struct { | |
31 | original string | |
32 | } | |
33 | ) | |
34 | ||
35 | func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem { | |
36 | return &initialismNameLexem{ | |
37 | original: original, | |
38 | matchedInitialism: matchedInitialism, | |
39 | } | |
40 | } | |
41 | ||
42 | func newCasualNameLexem(original string) *casualNameLexem { | |
43 | return &casualNameLexem{ | |
44 | original: original, | |
45 | } | |
46 | } | |
47 | ||
48 | func (l *initialismNameLexem) GetUnsafeGoName() string { | |
49 | return l.matchedInitialism | |
50 | } | |
51 | ||
52 | func (l *casualNameLexem) GetUnsafeGoName() string { | |
53 | var first rune | |
54 | var rest string | |
55 | for i, orig := range l.original { | |
56 | if i == 0 { | |
57 | first = orig | |
58 | continue | |
59 | } | |
60 | if i > 0 { | |
61 | rest = l.original[i:] | |
62 | break | |
63 | } | |
64 | } | |
65 | if len(l.original) > 1 { | |
66 | return string(unicode.ToUpper(first)) + lower(rest) | |
67 | } | |
68 | ||
69 | return l.original | |
70 | } | |
71 | ||
72 | func (l *initialismNameLexem) GetOriginal() string { | |
73 | return l.original | |
74 | } | |
75 | ||
76 | func (l *casualNameLexem) GetOriginal() string { | |
77 | return l.original | |
78 | } | |
79 | ||
80 | func (l *initialismNameLexem) IsInitialism() bool { | |
81 | return true | |
82 | } | |
83 | ||
84 | func (l *casualNameLexem) IsInitialism() bool { | |
85 | return false | |
86 | } |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | package swag |
1 | 15 | |
2 | 16 | import ( |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | package swag |
1 | 15 | |
2 | 16 | import ( |
24 | 24 | "github.com/stretchr/testify/assert" |
25 | 25 | ) |
26 | 26 | |
27 | func makeDirStructure(t *testing.T, tgt string) (string, string, error) { | |
27 | func makeDirStructure(tgt string) (string, string, error) { | |
28 | 28 | if tgt == "" { |
29 | 29 | tgt = "pkgpaths" |
30 | 30 | } |
65 | 65 | } |
66 | 66 | |
67 | 67 | func TestFindPackage(t *testing.T) { |
68 | pth, pth2, err := makeDirStructure(t, "") | |
68 | pth, pth2, err := makeDirStructure("") | |
69 | 69 | if err != nil { |
70 | 70 | t.Fatal(err) |
71 | 71 | } |
96 | 96 | assert.Empty(t, pkg) |
97 | 97 | } |
98 | 98 | |
99 | // nolint: unparam | |
99 | 100 | func assertPath(t testing.TB, expected, actual string) bool { |
100 | 101 | fp, err := filepath.EvalSymlinks(expected) |
101 | 102 | if assert.NoError(t, err) { |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | // +build go1.8 |
1 | 15 | |
2 | 16 | package swag |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | // +build go1.9 |
1 | 15 | |
2 | 16 | package swag |
47 | 61 | result = append(result, k) |
48 | 62 | return true |
49 | 63 | }) |
50 | sort.Sort(sort.Reverse(byLength(result))) | |
64 | sort.Sort(sort.Reverse(byInitialism(result))) | |
51 | 65 | return |
52 | 66 | } |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | // +build !go1.8 |
1 | 15 | |
2 | 16 | package swag |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
0 | 14 | // +build !go1.9 |
1 | 15 | |
2 | 16 | package swag |
49 | 63 | for k := range m.index { |
50 | 64 | result = append(result, k) |
51 | 65 | } |
52 | sort.Sort(sort.Reverse(byLength(result))) | |
66 | sort.Sort(sort.Reverse(byInitialism(result))) | |
53 | 67 | return |
54 | 68 | } |
0 | // Copyright 2015 go-swagger maintainers | |
1 | // | |
2 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | // you may not use this file except in compliance with the License. | |
4 | // You may obtain a copy of the License at | |
5 | // | |
6 | // http://www.apache.org/licenses/LICENSE-2.0 | |
7 | // | |
8 | // Unless required by applicable law or agreed to in writing, software | |
9 | // distributed under the License is distributed on an "AS IS" BASIS, | |
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | // See the License for the specific language governing permissions and | |
12 | // limitations under the License. | |
13 | ||
14 | package swag | |
15 | ||
16 | import ( | |
17 | "unicode" | |
18 | ) | |
19 | ||
20 | var nameReplaceTable = map[rune]string{ | |
21 | '@': "At ", | |
22 | '&': "And ", | |
23 | '|': "Pipe ", | |
24 | '$': "Dollar ", | |
25 | '!': "Bang ", | |
26 | '-': "", | |
27 | '_': "", | |
28 | } | |
29 | ||
30 | type ( | |
31 | splitter struct { | |
32 | postSplitInitialismCheck bool | |
33 | initialisms []string | |
34 | } | |
35 | ||
36 | splitterOption func(*splitter) *splitter | |
37 | ) | |
38 | ||
39 | // split calls the splitter; splitter provides more control and post options | |
40 | func split(str string) []string { | |
41 | lexems := newSplitter().split(str) | |
42 | result := make([]string, 0, len(lexems)) | |
43 | ||
44 | for _, lexem := range lexems { | |
45 | result = append(result, lexem.GetOriginal()) | |
46 | } | |
47 | ||
48 | return result | |
49 | ||
50 | } | |
51 | ||
52 | func (s *splitter) split(str string) []nameLexem { | |
53 | return s.toNameLexems(str) | |
54 | } | |
55 | ||
56 | func newSplitter(options ...splitterOption) *splitter { | |
57 | splitter := &splitter{ | |
58 | postSplitInitialismCheck: false, | |
59 | initialisms: initialisms, | |
60 | } | |
61 | ||
62 | for _, option := range options { | |
63 | splitter = option(splitter) | |
64 | } | |
65 | ||
66 | return splitter | |
67 | } | |
68 | ||
69 | // withPostSplitInitialismCheck allows to catch initialisms after main split process | |
70 | func withPostSplitInitialismCheck(s *splitter) *splitter { | |
71 | s.postSplitInitialismCheck = true | |
72 | return s | |
73 | } | |
74 | ||
75 | type ( | |
76 | initialismMatch struct { | |
77 | start, end int | |
78 | body []rune | |
79 | complete bool | |
80 | } | |
81 | initialismMatches []*initialismMatch | |
82 | ) | |
83 | ||
84 | func (s *splitter) toNameLexems(name string) []nameLexem { | |
85 | nameRunes := []rune(name) | |
86 | matches := s.gatherInitialismMatches(nameRunes) | |
87 | return s.mapMatchesToNameLexems(nameRunes, matches) | |
88 | } | |
89 | ||
90 | func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches { | |
91 | matches := make(initialismMatches, 0) | |
92 | ||
93 | for currentRunePosition, currentRune := range nameRunes { | |
94 | newMatches := make(initialismMatches, 0, len(matches)) | |
95 | ||
96 | // check current initialism matches | |
97 | for _, match := range matches { | |
98 | if keepCompleteMatch := match.complete; keepCompleteMatch { | |
99 | newMatches = append(newMatches, match) | |
100 | continue | |
101 | } | |
102 | ||
103 | // drop failed match | |
104 | currentMatchRune := match.body[currentRunePosition-match.start] | |
105 | if !s.initialismRuneEqual(currentMatchRune, currentRune) { | |
106 | continue | |
107 | } | |
108 | ||
109 | // try to complete ongoing match | |
110 | if currentRunePosition-match.start == len(match.body)-1 { | |
111 | // we are close; the next step is to check the symbol ahead | |
112 | // if it is a small letter, then it is not the end of match | |
113 | // but beginning of the next word | |
114 | ||
115 | if currentRunePosition < len(nameRunes)-1 { | |
116 | nextRune := nameRunes[currentRunePosition+1] | |
117 | if newWord := unicode.IsLower(nextRune); newWord { | |
118 | // oh ok, it was the start of a new word | |
119 | continue | |
120 | } | |
121 | } | |
122 | ||
123 | match.complete = true | |
124 | match.end = currentRunePosition | |
125 | } | |
126 | ||
127 | newMatches = append(newMatches, match) | |
128 | } | |
129 | ||
130 | // check for new initialism matches | |
131 | for _, initialism := range s.initialisms { | |
132 | initialismRunes := []rune(initialism) | |
133 | if s.initialismRuneEqual(initialismRunes[0], currentRune) { | |
134 | newMatches = append(newMatches, &initialismMatch{ | |
135 | start: currentRunePosition, | |
136 | body: initialismRunes, | |
137 | complete: false, | |
138 | }) | |
139 | } | |
140 | } | |
141 | ||
142 | matches = newMatches | |
143 | } | |
144 | ||
145 | return matches | |
146 | } | |
147 | ||
148 | func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem { | |
149 | nameLexems := make([]nameLexem, 0) | |
150 | ||
151 | var lastAcceptedMatch *initialismMatch | |
152 | for _, match := range matches { | |
153 | if !match.complete { | |
154 | continue | |
155 | } | |
156 | ||
157 | if firstMatch := lastAcceptedMatch == nil; firstMatch { | |
158 | nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...) | |
159 | nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) | |
160 | ||
161 | lastAcceptedMatch = match | |
162 | ||
163 | continue | |
164 | } | |
165 | ||
166 | if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch { | |
167 | continue | |
168 | } | |
169 | ||
170 | middle := nameRunes[lastAcceptedMatch.end+1 : match.start] | |
171 | nameLexems = append(nameLexems, s.breakCasualString(middle)...) | |
172 | nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) | |
173 | ||
174 | lastAcceptedMatch = match | |
175 | } | |
176 | ||
177 | // we have not found any accepted matches | |
178 | if lastAcceptedMatch == nil { | |
179 | return s.breakCasualString(nameRunes) | |
180 | } | |
181 | ||
182 | if lastAcceptedMatch.end+1 != len(nameRunes) { | |
183 | rest := nameRunes[lastAcceptedMatch.end+1:] | |
184 | nameLexems = append(nameLexems, s.breakCasualString(rest)...) | |
185 | } | |
186 | ||
187 | return nameLexems | |
188 | } | |
189 | ||
190 | func (s *splitter) initialismRuneEqual(a, b rune) bool { | |
191 | return a == b | |
192 | } | |
193 | ||
194 | func (s *splitter) breakInitialism(original string) nameLexem { | |
195 | return newInitialismNameLexem(original, original) | |
196 | } | |
197 | ||
198 | func (s *splitter) breakCasualString(str []rune) []nameLexem { | |
199 | segments := make([]nameLexem, 0) | |
200 | currentSegment := "" | |
201 | ||
202 | addCasualNameLexem := func(original string) { | |
203 | segments = append(segments, newCasualNameLexem(original)) | |
204 | } | |
205 | ||
206 | addInitialismNameLexem := func(original, match string) { | |
207 | segments = append(segments, newInitialismNameLexem(original, match)) | |
208 | } | |
209 | ||
210 | addNameLexem := func(original string) { | |
211 | if s.postSplitInitialismCheck { | |
212 | for _, initialism := range s.initialisms { | |
213 | if upper(initialism) == upper(original) { | |
214 | addInitialismNameLexem(original, initialism) | |
215 | return | |
216 | } | |
217 | } | |
218 | } | |
219 | ||
220 | addCasualNameLexem(original) | |
221 | } | |
222 | ||
223 | for _, rn := range string(str) { | |
224 | if replace, found := nameReplaceTable[rn]; found { | |
225 | if currentSegment != "" { | |
226 | addNameLexem(currentSegment) | |
227 | currentSegment = "" | |
228 | } | |
229 | ||
230 | if replace != "" { | |
231 | addNameLexem(replace) | |
232 | } | |
233 | ||
234 | continue | |
235 | } | |
236 | ||
237 | if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { | |
238 | if currentSegment != "" { | |
239 | addNameLexem(currentSegment) | |
240 | currentSegment = "" | |
241 | } | |
242 | ||
243 | continue | |
244 | } | |
245 | ||
246 | if unicode.IsUpper(rn) { | |
247 | if currentSegment != "" { | |
248 | addNameLexem(currentSegment) | |
249 | } | |
250 | currentSegment = "" | |
251 | } | |
252 | ||
253 | currentSegment += string(rn) | |
254 | } | |
255 | ||
256 | if currentSegment != "" { | |
257 | addNameLexem(currentSegment) | |
258 | } | |
259 | ||
260 | return segments | |
261 | } |
14 | 14 | package swag |
15 | 15 | |
16 | 16 | import ( |
17 | "math" | |
18 | 17 | "reflect" |
19 | "regexp" | |
20 | 18 | "strings" |
21 | "sync" | |
22 | 19 | "unicode" |
23 | 20 | ) |
24 | 21 | |
28 | 25 | // initialisms is a slice of sorted initialisms |
29 | 26 | var initialisms []string |
30 | 27 | |
31 | var once sync.Once | |
32 | ||
33 | 28 | var isInitialism func(string) bool |
29 | ||
30 | // GoNamePrefixFunc sets an optional rule to prefix go names | |
31 | // which do not start with a letter. | |
32 | // | |
33 | // e.g. to help convert "123" into "{prefix}123" | |
34 | // | |
35 | // The default is to prefix with "X" | |
36 | var GoNamePrefixFunc func(string) string | |
34 | 37 | |
35 | 38 | func init() { |
36 | 39 | // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 |
48 | 51 | "HTTP": true, |
49 | 52 | "ID": true, |
50 | 53 | "IP": true, |
54 | "IPv4": true, | |
55 | "IPv6": true, | |
51 | 56 | "JSON": true, |
52 | 57 | "LHS": true, |
53 | 58 | "OAI": true, |
78 | 83 | |
79 | 84 | // a thread-safe index of initialisms |
80 | 85 | commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms) |
86 | initialisms = commonInitialisms.sorted() | |
81 | 87 | |
82 | 88 | // a test function |
83 | 89 | isInitialism = commonInitialisms.isInitialism |
84 | 90 | } |
85 | 91 | |
86 | func ensureSorted() { | |
87 | initialisms = commonInitialisms.sorted() | |
88 | } | |
89 | ||
90 | // JoinByFormat joins a string array by a known format: | |
92 | const ( | |
93 | // collectionFormatComma = "csv" | |
94 | collectionFormatSpace = "ssv" | |
95 | collectionFormatTab = "tsv" | |
96 | collectionFormatPipe = "pipes" | |
97 | collectionFormatMulti = "multi" | |
98 | ) | |
99 | ||
100 | // JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): | |
91 | 101 | // ssv: space separated value |
92 | 102 | // tsv: tab separated value |
93 | 103 | // pipes: pipe (|) separated value |
98 | 108 | } |
99 | 109 | var sep string |
100 | 110 | switch format { |
101 | case "ssv": | |
111 | case collectionFormatSpace: | |
102 | 112 | sep = " " |
103 | case "tsv": | |
113 | case collectionFormatTab: | |
104 | 114 | sep = "\t" |
105 | case "pipes": | |
115 | case collectionFormatPipe: | |
106 | 116 | sep = "|" |
107 | case "multi": | |
117 | case collectionFormatMulti: | |
108 | 118 | return data |
109 | 119 | default: |
110 | 120 | sep = "," |
117 | 127 | // tsv: tab separated value |
118 | 128 | // pipes: pipe (|) separated value |
119 | 129 | // csv: comma separated value (default) |
130 | // | |
120 | 131 | func SplitByFormat(data, format string) []string { |
121 | 132 | if data == "" { |
122 | 133 | return nil |
123 | 134 | } |
124 | 135 | var sep string |
125 | 136 | switch format { |
126 | case "ssv": | |
137 | case collectionFormatSpace: | |
127 | 138 | sep = " " |
128 | case "tsv": | |
139 | case collectionFormatTab: | |
129 | 140 | sep = "\t" |
130 | case "pipes": | |
141 | case collectionFormatPipe: | |
131 | 142 | sep = "|" |
132 | case "multi": | |
143 | case collectionFormatMulti: | |
133 | 144 | return nil |
134 | 145 | default: |
135 | 146 | sep = "," |
143 | 154 | return result |
144 | 155 | } |
145 | 156 | |
146 | type byLength []string | |
147 | ||
148 | func (s byLength) Len() int { | |
157 | type byInitialism []string | |
158 | ||
159 | func (s byInitialism) Len() int { | |
149 | 160 | return len(s) |
150 | 161 | } |
151 | func (s byLength) Swap(i, j int) { | |
162 | func (s byInitialism) Swap(i, j int) { | |
152 | 163 | s[i], s[j] = s[j], s[i] |
153 | 164 | } |
154 | func (s byLength) Less(i, j int) bool { | |
155 | return len(s[i]) < len(s[j]) | |
156 | } | |
157 | ||
158 | // Prepares strings by splitting by caps, spaces, dashes, and underscore | |
159 | func split(str string) (words []string) { | |
160 | repl := strings.NewReplacer( | |
161 | "@", "At ", | |
162 | "&", "And ", | |
163 | "|", "Pipe ", | |
164 | "$", "Dollar ", | |
165 | "!", "Bang ", | |
166 | "-", " ", | |
167 | "_", " ", | |
168 | ) | |
169 | ||
170 | rex1 := regexp.MustCompile(`(\p{Lu})`) | |
171 | rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`) | |
172 | ||
173 | str = trim(str) | |
174 | ||
175 | // Convert dash and underscore to spaces | |
176 | str = repl.Replace(str) | |
177 | ||
178 | // Split when uppercase is found (needed for Snake) | |
179 | str = rex1.ReplaceAllString(str, " $1") | |
180 | ||
181 | // check if consecutive single char things make up an initialism | |
182 | once.Do(ensureSorted) | |
183 | for _, k := range initialisms { | |
184 | str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1) | |
185 | } | |
186 | // Get the final list of words | |
187 | words = rex2.FindAllString(str, -1) | |
188 | ||
189 | return | |
165 | func (s byInitialism) Less(i, j int) bool { | |
166 | if len(s[i]) != len(s[j]) { | |
167 | return len(s[i]) < len(s[j]) | |
168 | } | |
169 | ||
170 | return strings.Compare(s[i], s[j]) > 0 | |
190 | 171 | } |
191 | 172 | |
192 | 173 | // Removes leading whitespaces |
206 | 187 | |
207 | 188 | // Camelize an uppercased word |
208 | 189 | func Camelize(word string) (camelized string) { |
209 | for pos, ru := range word { | |
190 | for pos, ru := range []rune(word) { | |
210 | 191 | if pos > 0 { |
211 | 192 | camelized += string(unicode.ToLower(ru)) |
212 | 193 | } else { |
218 | 199 | |
219 | 200 | // ToFileName lowercases and underscores a go type name |
220 | 201 | func ToFileName(name string) string { |
221 | var out []string | |
222 | ||
223 | for _, w := range split(name) { | |
202 | in := split(name) | |
203 | out := make([]string, 0, len(in)) | |
204 | ||
205 | for _, w := range in { | |
224 | 206 | out = append(out, lower(w)) |
225 | 207 | } |
226 | 208 | |
229 | 211 | |
230 | 212 | // ToCommandName lowercases and underscores a go type name |
231 | 213 | func ToCommandName(name string) string { |
232 | var out []string | |
233 | for _, w := range split(name) { | |
214 | in := split(name) | |
215 | out := make([]string, 0, len(in)) | |
216 | ||
217 | for _, w := range in { | |
234 | 218 | out = append(out, lower(w)) |
235 | 219 | } |
236 | 220 | return strings.Join(out, "-") |
238 | 222 | |
239 | 223 | // ToHumanNameLower represents a code name as a human series of words |
240 | 224 | func ToHumanNameLower(name string) string { |
241 | var out []string | |
242 | for _, w := range split(name) { | |
243 | if !isInitialism(upper(w)) { | |
244 | out = append(out, lower(w)) | |
225 | in := newSplitter(withPostSplitInitialismCheck).split(name) | |
226 | out := make([]string, 0, len(in)) | |
227 | ||
228 | for _, w := range in { | |
229 | if !w.IsInitialism() { | |
230 | out = append(out, lower(w.GetOriginal())) | |
245 | 231 | } else { |
246 | out = append(out, w) | |
247 | } | |
248 | } | |
232 | out = append(out, w.GetOriginal()) | |
233 | } | |
234 | } | |
235 | ||
249 | 236 | return strings.Join(out, " ") |
250 | 237 | } |
251 | 238 | |
252 | 239 | // ToHumanNameTitle represents a code name as a human series of words with the first letters titleized |
253 | 240 | func ToHumanNameTitle(name string) string { |
254 | var out []string | |
255 | for _, w := range split(name) { | |
256 | uw := upper(w) | |
257 | if !isInitialism(uw) { | |
258 | out = append(out, upper(w[:1])+lower(w[1:])) | |
241 | in := newSplitter(withPostSplitInitialismCheck).split(name) | |
242 | ||
243 | out := make([]string, 0, len(in)) | |
244 | for _, w := range in { | |
245 | original := w.GetOriginal() | |
246 | if !w.IsInitialism() { | |
247 | out = append(out, Camelize(original)) | |
259 | 248 | } else { |
260 | out = append(out, w) | |
249 | out = append(out, original) | |
261 | 250 | } |
262 | 251 | } |
263 | 252 | return strings.Join(out, " ") |
265 | 254 | |
266 | 255 | // ToJSONName camelcases a name which can be underscored or pascal cased |
267 | 256 | func ToJSONName(name string) string { |
268 | var out []string | |
269 | for i, w := range split(name) { | |
257 | in := split(name) | |
258 | out := make([]string, 0, len(in)) | |
259 | ||
260 | for i, w := range in { | |
270 | 261 | if i == 0 { |
271 | 262 | out = append(out, lower(w)) |
272 | 263 | continue |
273 | 264 | } |
274 | out = append(out, upper(w[:1])+lower(w[1:])) | |
265 | out = append(out, Camelize(w)) | |
275 | 266 | } |
276 | 267 | return strings.Join(out, "") |
277 | 268 | } |
290 | 281 | |
291 | 282 | // ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes |
292 | 283 | func ToGoName(name string) string { |
293 | var out []string | |
294 | for _, w := range split(name) { | |
295 | uw := upper(w) | |
296 | mod := int(math.Min(float64(len(uw)), 2)) | |
297 | if !isInitialism(uw) && !isInitialism(uw[:len(uw)-mod]) { | |
298 | uw = upper(w[:1]) + lower(w[1:]) | |
299 | } | |
300 | out = append(out, uw) | |
301 | } | |
302 | ||
303 | result := strings.Join(out, "") | |
284 | lexems := newSplitter(withPostSplitInitialismCheck).split(name) | |
285 | ||
286 | result := "" | |
287 | for _, lexem := range lexems { | |
288 | goName := lexem.GetUnsafeGoName() | |
289 | ||
290 | // to support old behavior | |
291 | if lexem.IsInitialism() { | |
292 | goName = upper(goName) | |
293 | } | |
294 | result += goName | |
295 | } | |
296 | ||
304 | 297 | if len(result) > 0 { |
305 | ud := upper(result[:1]) | |
306 | ru := []rune(ud) | |
307 | if unicode.IsUpper(ru[0]) { | |
308 | result = ud + result[1:] | |
309 | } else { | |
310 | result = "X" + ud + result[1:] | |
311 | } | |
312 | } | |
298 | // Only prefix with X when the first character isn't an ascii letter | |
299 | first := []rune(result)[0] | |
300 | if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) { | |
301 | if GoNamePrefixFunc == nil { | |
302 | return "X" + result | |
303 | } | |
304 | result = GoNamePrefixFunc(name) + result | |
305 | } | |
306 | first = []rune(result)[0] | |
307 | if unicode.IsLetter(first) && !unicode.IsUpper(first) { | |
308 | result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...)) | |
309 | } | |
310 | } | |
311 | ||
313 | 312 | return result |
313 | } | |
314 | ||
315 | // ContainsStrings searches a slice of strings for a case-sensitive match | |
316 | func ContainsStrings(coll []string, item string) bool { | |
317 | for _, a := range coll { | |
318 | if a == item { | |
319 | return true | |
320 | } | |
321 | } | |
322 | return false | |
314 | 323 | } |
315 | 324 | |
316 | 325 | // ContainsStringsCI searches a slice of strings for a case-insensitive match |
360 | 369 | // AddInitialisms add additional initialisms |
361 | 370 | func AddInitialisms(words ...string) { |
362 | 371 | for _, word := range words { |
363 | //commonInitialisms[upper(word)] = true | |
372 | // commonInitialisms[upper(word)] = true | |
364 | 373 | commonInitialisms.add(upper(word)) |
365 | 374 | } |
366 | 375 | // sort again |
15 | 15 | |
16 | 16 | import ( |
17 | 17 | "fmt" |
18 | "log" | |
18 | 19 | "strings" |
19 | 20 | "testing" |
20 | 21 | "time" |
22 | "unicode" | |
23 | ||
24 | "github.com/stretchr/testify/require" | |
21 | 25 | |
22 | 26 | "github.com/stretchr/testify/assert" |
23 | 27 | ) |
32 | 36 | AddInitialisms("elb", "cap", "capwd", "wd") |
33 | 37 | } |
34 | 38 | |
39 | func TestIndexOfInitialismsSorted(t *testing.T) { | |
40 | configuredInitialisms := map[string]bool{ | |
41 | "ACL": true, | |
42 | "API": true, | |
43 | "ASCII": true, | |
44 | "CPU": true, | |
45 | "CSS": true, | |
46 | "DNS": true, | |
47 | "VM": true, | |
48 | "XML": true, | |
49 | "XMPP": true, | |
50 | "XSRF": true, | |
51 | "XSS": true, | |
52 | } | |
53 | ||
54 | goldenSample := []string{ | |
55 | "ASCII", | |
56 | "XMPP", | |
57 | "XSRF", | |
58 | "ACL", | |
59 | "API", | |
60 | "CPU", | |
61 | "CSS", | |
62 | "DNS", | |
63 | "XML", | |
64 | "XSS", | |
65 | "VM", | |
66 | } | |
67 | for i := 0; i < 50; i++ { | |
68 | sample := newIndexOfInitialisms().load(configuredInitialisms).sorted() | |
69 | failMsg := "equal sorted initialisms should be always equal" | |
70 | ||
71 | if !assert.Equal(t, goldenSample, sample, failMsg) { | |
72 | t.FailNow() | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
77 | func TestHighUnicode(t *testing.T) { | |
78 | ss := "日本語sample 2 Text" | |
79 | rss := []rune(ss) | |
80 | ||
81 | log.Println("title:", unicode.IsTitle(rss[0])) | |
82 | require.False(t, rss[0] < unicode.MaxASCII && unicode.IsLetter(rss[0])) | |
83 | } | |
84 | ||
35 | 85 | func TestToGoName(t *testing.T) { |
36 | 86 | samples := []translationSample{ |
87 | {"@Type", "AtType"}, | |
88 | {"Sample@where", "SampleAtWhere"}, | |
89 | {"Id", "ID"}, | |
90 | {"SomethingTTLSeconds", "SomethingTTLSeconds"}, | |
37 | 91 | {"sample text", "SampleText"}, |
92 | {"IPv6Address", "IPV6Address"}, | |
93 | {"IPv4Address", "IPV4Address"}, | |
38 | 94 | {"sample-text", "SampleText"}, |
39 | 95 | {"sample_text", "SampleText"}, |
40 | 96 | {"sampleText", "SampleText"}, |
43 | 99 | {"日本語sample 2 Text", "X日本語sample2Text"}, |
44 | 100 | {"日本語findThingById", "X日本語findThingByID"}, |
45 | 101 | {"findTHINGSbyID", "FindTHINGSbyID"}, |
102 | {"x-isAnOptionalHeader0", "XIsAnOptionalHeader0"}, | |
46 | 103 | } |
47 | 104 | |
48 | 105 | for _, k := range commonInitialisms.sorted() { |
106 | k = upper(k) | |
107 | ||
49 | 108 | samples = append(samples, |
50 | 109 | translationSample{"sample " + lower(k) + " text", "Sample" + k + "Text"}, |
51 | 110 | translationSample{"sample-" + lower(k) + "-text", "Sample" + k + "Text"}, |
62 | 121 | } |
63 | 122 | |
64 | 123 | for _, sample := range samples { |
65 | assert.Equal(t, sample.out, ToGoName(sample.str)) | |
124 | result := ToGoName(sample.str) | |
125 | assert.Equal(t, sample.out, result, | |
126 | "ToGoName(%q) == %q but %q", sample.str, sample.out, result) | |
127 | } | |
128 | } | |
129 | ||
130 | func BenchmarkToGoName(b *testing.B) { | |
131 | samples := []string{ | |
132 | "sample text", | |
133 | "sample-text", | |
134 | "sample_text", | |
135 | "sampleText", | |
136 | "sample 2 Text", | |
137 | "findThingById", | |
138 | "日本語sample 2 Text", | |
139 | "日本語findThingById", | |
140 | "findTHINGSbyID", | |
141 | } | |
142 | for i := 0; i < b.N; i++ { | |
143 | for _, s := range samples { | |
144 | ToGoName(s) | |
145 | } | |
66 | 146 | } |
67 | 147 | } |
68 | 148 | |
75 | 155 | assert.False(t, ContainsStringsCI(list, "nuts")) |
76 | 156 | } |
77 | 157 | |
158 | func TestContainsStrings(t *testing.T) { | |
159 | list := []string{"hello", "world", "and", "such"} | |
160 | ||
161 | assert.True(t, ContainsStrings(list, "hello")) | |
162 | assert.False(t, ContainsStrings(list, "hELLo")) | |
163 | assert.True(t, ContainsStrings(list, "world")) | |
164 | assert.False(t, ContainsStrings(list, "World")) | |
165 | assert.True(t, ContainsStrings(list, "and")) | |
166 | assert.False(t, ContainsStrings(list, "AND")) | |
167 | assert.False(t, ContainsStrings(list, "nuts")) | |
168 | } | |
169 | ||
170 | const ( | |
171 | collectionFormatComma = "csv" | |
172 | ) | |
173 | ||
78 | 174 | func TestSplitByFormat(t *testing.T) { |
79 | 175 | expected := []string{"one", "two", "three"} |
80 | for _, fmt := range []string{"csv", "pipes", "tsv", "ssv", "multi"} { | |
176 | for _, fmt := range []string{collectionFormatComma, collectionFormatPipe, collectionFormatTab, collectionFormatSpace, collectionFormatMulti} { | |
81 | 177 | |
82 | 178 | var actual []string |
83 | 179 | switch fmt { |
84 | case "multi": | |
180 | case collectionFormatMulti: | |
85 | 181 | assert.Nil(t, SplitByFormat("", fmt)) |
86 | 182 | assert.Nil(t, SplitByFormat("blah", fmt)) |
87 | case "ssv": | |
183 | case collectionFormatSpace: | |
88 | 184 | actual = SplitByFormat(strings.Join(expected, " "), fmt) |
89 | 185 | assert.EqualValues(t, expected, actual) |
90 | case "pipes": | |
186 | case collectionFormatPipe: | |
91 | 187 | actual = SplitByFormat(strings.Join(expected, "|"), fmt) |
92 | 188 | assert.EqualValues(t, expected, actual) |
93 | case "tsv": | |
189 | case collectionFormatTab: | |
94 | 190 | actual = SplitByFormat(strings.Join(expected, "\t"), fmt) |
95 | 191 | assert.EqualValues(t, expected, actual) |
96 | 192 | default: |
101 | 197 | } |
102 | 198 | |
103 | 199 | func TestJoinByFormat(t *testing.T) { |
104 | for _, fmt := range []string{"csv", "pipes", "tsv", "ssv", "multi"} { | |
200 | for _, fmt := range []string{collectionFormatComma, collectionFormatPipe, collectionFormatTab, collectionFormatSpace, collectionFormatMulti} { | |
105 | 201 | |
106 | 202 | lval := []string{"one", "two", "three"} |
107 | 203 | var expected []string |
108 | 204 | switch fmt { |
109 | case "multi": | |
205 | case collectionFormatMulti: | |
110 | 206 | expected = lval |
111 | case "ssv": | |
207 | case collectionFormatSpace: | |
112 | 208 | expected = []string{strings.Join(lval, " ")} |
113 | case "pipes": | |
209 | case collectionFormatPipe: | |
114 | 210 | expected = []string{strings.Join(lval, "|")} |
115 | case "tsv": | |
211 | case collectionFormatTab: | |
116 | 212 | expected = []string{strings.Join(lval, "\t")} |
117 | 213 | default: |
118 | 214 | expected = []string{strings.Join(lval, ",")} |
127 | 223 | {"SampleText", "sample_text"}, |
128 | 224 | {"FindThingByID", "find_thing_by_id"}, |
129 | 225 | {"CAPWD.folwdBylc", "capwd_folwd_bylc"}, |
130 | {"CAPWDfolwdBylc", "capwdfolwd_bylc"}, | |
226 | {"CAPWDfolwdBylc", "cap_w_dfolwd_bylc"}, | |
131 | 227 | {"CAP_WD_folwdBylc", "cap_wd_folwd_bylc"}, |
132 | 228 | {"TypeOAI_alias", "type_oai_alias"}, |
133 | 229 | {"Type_OAI_alias", "type_oai_alias"}, |
143 | 239 | } |
144 | 240 | |
145 | 241 | for _, sample := range samples { |
146 | assert.Equal(t, sample.out, ToFileName(sample.str)) | |
242 | result := ToFileName(sample.str) | |
243 | assert.Equal(t, sample.out, ToFileName(sample.str), | |
244 | "ToFileName(%q) == %q but got %q", sample.str, sample.out, result) | |
147 | 245 | } |
148 | 246 | } |
149 | 247 | |
167 | 265 | |
168 | 266 | func TestToHumanName(t *testing.T) { |
169 | 267 | samples := []translationSample{ |
268 | {"Id", "Id"}, | |
170 | 269 | {"SampleText", "sample text"}, |
171 | 270 | {"FindThingByID", "find thing by ID"}, |
172 | 271 | {"elbHTTPLoadBalancer", "elb HTTP load balancer"}, |
290 | 389 | assert.Equal(t, it.Expected, IsZero(it.Data), fmt.Sprintf("%#v", it.Data)) |
291 | 390 | } |
292 | 391 | } |
392 | ||
393 | func TestCamelize(t *testing.T) { | |
394 | samples := []translationSample{ | |
395 | {"SampleText", "Sampletext"}, | |
396 | {"FindThingByID", "Findthingbyid"}, | |
397 | {"CAPWD.folwdBylc", "Capwd.folwdbylc"}, | |
398 | {"CAPWDfolwdBylc", "Capwdfolwdbylc"}, | |
399 | {"CAP_WD_folwdBylc", "Cap_wd_folwdbylc"}, | |
400 | {"TypeOAI_alias", "Typeoai_alias"}, | |
401 | {"Type_OAI_alias", "Type_oai_alias"}, | |
402 | {"Type_OAIAlias", "Type_oaialias"}, | |
403 | {"ELB.HTTPLoadBalancer", "Elb.httploadbalancer"}, | |
404 | {"elbHTTPLoadBalancer", "Elbhttploadbalancer"}, | |
405 | {"ELBHTTPLoadBalancer", "Elbhttploadbalancer"}, | |
406 | {"12ab", "12ab"}, | |
407 | } | |
408 | ||
409 | for _, sample := range samples { | |
410 | res := Camelize(sample.str) | |
411 | assert.Equalf(t, sample.out, res, "expected Camelize(%q)=%q, got %q", sample.str, sample.out, res) | |
412 | } | |
413 | } | |
414 | ||
415 | func TestToHumanNameTitle(t *testing.T) { | |
416 | samples := []translationSample{ | |
417 | {"SampleText", "Sample Text"}, | |
418 | {"FindThingByID", "Find Thing By ID"}, | |
419 | {"CAPWD.folwdBylc", "CAPWD Folwd Bylc"}, | |
420 | {"CAPWDfolwdBylc", "CAP W Dfolwd Bylc"}, | |
421 | {"CAP_WD_folwdBylc", "CAP WD Folwd Bylc"}, | |
422 | {"TypeOAI_alias", "Type OAI Alias"}, | |
423 | {"Type_OAI_alias", "Type OAI Alias"}, | |
424 | {"Type_OAIAlias", "Type OAI Alias"}, | |
425 | {"ELB.HTTPLoadBalancer", "ELB HTTP Load Balancer"}, | |
426 | {"elbHTTPLoadBalancer", "elb HTTP Load Balancer"}, | |
427 | {"ELBHTTPLoadBalancer", "ELB HTTP Load Balancer"}, | |
428 | } | |
429 | ||
430 | for _, sample := range samples { | |
431 | res := ToHumanNameTitle(sample.str) | |
432 | assert.Equalf(t, sample.out, res, "expected ToHumanNameTitle(%q)=%q, got %q", sample.str, sample.out, res) | |
433 | } | |
434 | } | |
435 | ||
436 | func TestToVarName(t *testing.T) { | |
437 | samples := []translationSample{ | |
438 | {"SampleText", "sampleText"}, | |
439 | {"FindThingByID", "findThingByID"}, | |
440 | {"CAPWD.folwdBylc", "cAPWDFolwdBylc"}, | |
441 | {"CAPWDfolwdBylc", "cAPWDfolwdBylc"}, | |
442 | {"CAP_WD_folwdBylc", "cAPWDFolwdBylc"}, | |
443 | {"TypeOAI_alias", "typeOAIAlias"}, | |
444 | {"Type_OAI_alias", "typeOAIAlias"}, | |
445 | {"Type_OAIAlias", "typeOAIAlias"}, | |
446 | {"ELB.HTTPLoadBalancer", "eLBHTTPLoadBalancer"}, | |
447 | {"elbHTTPLoadBalancer", "eLBHTTPLoadBalancer"}, | |
448 | {"ELBHTTPLoadBalancer", "eLBHTTPLoadBalancer"}, | |
449 | {"Id", "id"}, | |
450 | {"HTTP", "http"}, | |
451 | {"A", "a"}, | |
452 | } | |
453 | ||
454 | for _, sample := range samples { | |
455 | res := ToVarName(sample.str) | |
456 | assert.Equalf(t, sample.out, res, "expected ToVarName(%q)=%q, got %q", sample.str, sample.out, res) | |
457 | } | |
458 | } | |
459 | ||
460 | func TestToGoNameUnicode(t *testing.T) { | |
461 | defer func() { GoNamePrefixFunc = nil }() | |
462 | GoNamePrefixFunc = func(name string) string { | |
463 | // this is the pascalize func from go-swagger codegen | |
464 | arg := []rune(name) | |
465 | if len(arg) == 0 || arg[0] > '9' { | |
466 | return "" | |
467 | } | |
468 | if arg[0] == '+' { | |
469 | return "Plus" | |
470 | } | |
471 | if arg[0] == '-' { | |
472 | return "Minus" | |
473 | } | |
474 | ||
475 | return "Nr" | |
476 | } | |
477 | ||
478 | samples := []translationSample{ | |
479 | {"123_a", "Nr123a"}, | |
480 | {"!123_a", "Bang123a"}, | |
481 | {"+123_a", "Plus123a"}, | |
482 | {"abc", "Abc"}, | |
483 | {"éabc", "Éabc"}, | |
484 | {":éabc", "Éabc"}, | |
485 | // TODO: non unicode char | |
486 | } | |
487 | ||
488 | for _, sample := range samples { | |
489 | assert.Equal(t, sample.out, ToGoName(sample.str)) | |
490 | } | |
491 | } |
21 | 21 | |
22 | 22 | "github.com/mailru/easyjson/jlexer" |
23 | 23 | "github.com/mailru/easyjson/jwriter" |
24 | ||
25 | 24 | yaml "gopkg.in/yaml.v2" |
26 | 25 | ) |
27 | 26 | |
143 | 142 | } |
144 | 143 | |
145 | 144 | func transformData(input interface{}) (out interface{}, err error) { |
145 | format := func(t interface{}) (string, error) { | |
146 | switch k := t.(type) { | |
147 | case string: | |
148 | return k, nil | |
149 | case uint: | |
150 | return strconv.FormatUint(uint64(k), 10), nil | |
151 | case uint8: | |
152 | return strconv.FormatUint(uint64(k), 10), nil | |
153 | case uint16: | |
154 | return strconv.FormatUint(uint64(k), 10), nil | |
155 | case uint32: | |
156 | return strconv.FormatUint(uint64(k), 10), nil | |
157 | case uint64: | |
158 | return strconv.FormatUint(k, 10), nil | |
159 | case int: | |
160 | return strconv.Itoa(k), nil | |
161 | case int8: | |
162 | return strconv.FormatInt(int64(k), 10), nil | |
163 | case int16: | |
164 | return strconv.FormatInt(int64(k), 10), nil | |
165 | case int32: | |
166 | return strconv.FormatInt(int64(k), 10), nil | |
167 | case int64: | |
168 | return strconv.FormatInt(k, 10), nil | |
169 | default: | |
170 | return "", fmt.Errorf("unexpected map key type, got: %T", k) | |
171 | } | |
172 | } | |
173 | ||
146 | 174 | switch in := input.(type) { |
147 | 175 | case yaml.MapSlice: |
148 | 176 | |
149 | 177 | o := make(JSONMapSlice, len(in)) |
150 | 178 | for i, mi := range in { |
151 | 179 | var nmi JSONMapItem |
152 | switch k := mi.Key.(type) { | |
153 | case string: | |
154 | nmi.Key = k | |
155 | case int: | |
156 | nmi.Key = strconv.Itoa(k) | |
157 | default: | |
158 | return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key) | |
180 | if nmi.Key, err = format(mi.Key); err != nil { | |
181 | return nil, err | |
159 | 182 | } |
160 | 183 | |
161 | 184 | v, ert := transformData(mi.Value) |
170 | 193 | o := make(JSONMapSlice, 0, len(in)) |
171 | 194 | for ke, va := range in { |
172 | 195 | var nmi JSONMapItem |
173 | switch k := ke.(type) { | |
174 | case string: | |
175 | nmi.Key = k | |
176 | case int: | |
177 | nmi.Key = strconv.Itoa(k) | |
178 | default: | |
179 | return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke) | |
196 | if nmi.Key, err = format(ke); err != nil { | |
197 | return nil, err | |
180 | 198 | } |
181 | 199 | |
182 | 200 | v, ert := transformData(va) |
16 | 16 | import ( |
17 | 17 | "encoding/json" |
18 | 18 | "net/http" |
19 | "net/http/httptest" | |
20 | 19 | "testing" |
21 | 20 | |
21 | "github.com/stretchr/testify/assert" | |
22 | 22 | yaml "gopkg.in/yaml.v2" |
23 | ||
24 | "github.com/stretchr/testify/assert" | |
25 | 23 | ) |
26 | 24 | |
27 | 25 | /* currently unused: |
32 | 30 | return nil, errors.New("expected") |
33 | 31 | } |
34 | 32 | */ |
35 | ||
36 | func TestLoadHTTPBytes(t *testing.T) { | |
37 | _, err := LoadFromFileOrHTTP("httx://12394:abd") | |
38 | assert.Error(t, err) | |
39 | ||
40 | serv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
41 | rw.WriteHeader(http.StatusNotFound) | |
42 | })) | |
43 | defer serv.Close() | |
44 | ||
45 | _, err = LoadFromFileOrHTTP(serv.URL) | |
46 | assert.Error(t, err) | |
47 | ||
48 | ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
49 | rw.WriteHeader(http.StatusOK) | |
50 | rw.Write([]byte("the content")) | |
51 | })) | |
52 | defer ts2.Close() | |
53 | ||
54 | d, err := LoadFromFileOrHTTP(ts2.URL) | |
55 | assert.NoError(t, err) | |
56 | assert.Equal(t, []byte("the content"), d) | |
57 | } | |
58 | 33 | |
59 | 34 | func TestYAMLToJSON(t *testing.T) { |
60 | 35 | |
64 | 39 | 'y': some value |
65 | 40 | ` |
66 | 41 | var data yaml.MapSlice |
67 | yaml.Unmarshal([]byte(sd), &data) | |
42 | _ = yaml.Unmarshal([]byte(sd), &data) | |
68 | 43 | |
69 | 44 | d, err := YAMLToJSON(data) |
70 | 45 | if assert.NoError(t, err) { |
119 | 94 | assert.Equal(t, json.RawMessage(`{"description":"object created"}`), d) |
120 | 95 | } |
121 | 96 | |
122 | func TestLoadStrategy(t *testing.T) { | |
123 | ||
124 | loader := func(p string) ([]byte, error) { | |
125 | return []byte(yamlPetStore), nil | |
126 | } | |
127 | remLoader := func(p string) ([]byte, error) { | |
128 | return []byte("not it"), nil | |
129 | } | |
130 | ||
131 | ld := LoadStrategy("blah", loader, remLoader) | |
132 | b, _ := ld("") | |
133 | assert.Equal(t, []byte(yamlPetStore), b) | |
134 | ||
135 | serv := httptest.NewServer(http.HandlerFunc(yamlPestoreServer)) | |
136 | defer serv.Close() | |
137 | ||
138 | s, err := YAMLDoc(serv.URL) | |
139 | assert.NoError(t, err) | |
140 | assert.NotNil(t, s) | |
141 | ||
142 | ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | |
143 | rw.WriteHeader(http.StatusNotFound) | |
144 | rw.Write([]byte("\n")) | |
145 | })) | |
146 | defer ts2.Close() | |
147 | _, err = YAMLDoc(ts2.URL) | |
148 | assert.Error(t, err) | |
149 | } | |
150 | ||
151 | 97 | var yamlPestoreServer = func(rw http.ResponseWriter, r *http.Request) { |
152 | 98 | rw.WriteHeader(http.StatusOK) |
153 | rw.Write([]byte(yamlPetStore)) | |
99 | _, _ = rw.Write([]byte(yamlPetStore)) | |
154 | 100 | } |
155 | 101 | |
156 | 102 | func TestWithYKey(t *testing.T) { |
181 | 127 | } |
182 | 128 | |
183 | 129 | } |
130 | } | |
131 | ||
132 | func TestMapKeyTypes(t *testing.T) { | |
133 | d := yaml.MapSlice{ | |
134 | yaml.MapItem{Key: 12345, Value: "int"}, | |
135 | yaml.MapItem{Key: int8(1), Value: "int8"}, | |
136 | yaml.MapItem{Key: int16(12345), Value: "int16"}, | |
137 | yaml.MapItem{Key: int32(12345678), Value: "int32"}, | |
138 | yaml.MapItem{Key: int64(12345678910), Value: "int64"}, | |
139 | yaml.MapItem{Key: uint(12345), Value: "uint"}, | |
140 | yaml.MapItem{Key: uint8(1), Value: "uint8"}, | |
141 | yaml.MapItem{Key: uint16(12345), Value: "uint16"}, | |
142 | yaml.MapItem{Key: uint32(12345678), Value: "uint32"}, | |
143 | yaml.MapItem{Key: uint64(12345678910), Value: "uint64"}, | |
144 | } | |
145 | _, err := YAMLToJSON(d) | |
146 | assert.NoError(t, err) | |
147 | ||
148 | dm := map[interface{}]interface{}{ | |
149 | 12345: "int", | |
150 | int8(1): "int8", | |
151 | int16(12345): "int16", | |
152 | int32(12345678): "int32", | |
153 | int64(12345678910): "int64", | |
154 | uint(12345): "uint", | |
155 | uint8(1): "uint8", | |
156 | uint16(12345): "uint16", | |
157 | uint32(12345678): "uint32", | |
158 | uint64(12345678910): "uint64", | |
159 | } | |
160 | _, err = YAMLToJSON(dm) | |
161 | assert.NoError(t, err) | |
184 | 162 | } |
185 | 163 | |
186 | 164 | const withQuotedYKey = `consumes: |