├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Godeps
├── Godeps.json
├── Readme
└── _workspace
│ ├── .gitignore
│ └── src
│ ├── github.com
│ └── stretchr
│ │ └── testify
│ │ ├── assert
│ │ ├── assertions.go
│ │ ├── assertions_test.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── forward_assertions.go
│ │ ├── forward_assertions_test.go
│ │ ├── http_assertions.go
│ │ └── http_assertions_test.go
│ │ └── require
│ │ ├── doc.go
│ │ ├── forward_requirements.go
│ │ ├── forward_requirements_test.go
│ │ ├── requirements.go
│ │ └── requirements_test.go
│ └── gopkg.in
│ └── yaml.v2
│ ├── LICENSE
│ ├── LICENSE.libyaml
│ ├── README.md
│ ├── apic.go
│ ├── decode.go
│ ├── decode_test.go
│ ├── emitterc.go
│ ├── encode.go
│ ├── encode_test.go
│ ├── parserc.go
│ ├── readerc.go
│ ├── resolve.go
│ ├── scannerc.go
│ ├── sorter.go
│ ├── suite_test.go
│ ├── writerc.go
│ ├── yaml.go
│ ├── yamlh.go
│ └── yamlprivateh.go
├── LICENSE
├── Makefile
├── README.md
├── _docs
├── codes.yml
├── headers.yml
└── methods.yml
├── httpdoc
├── codes.go
├── codes_test.go
├── doc.go
├── doc_test.go
├── errors.go
├── headers.go
├── methods.go
├── resource.go
└── version.go
└── main.go
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.tgz
3 | .*.sw*
4 | .DS_Store
5 | /bin/*
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.2
4 | - 1.3
5 | - 1.4
6 | - tip
7 | install:
8 | - go get golang.org/x/tools/cmd/vet
9 | - go get .
10 | script:
11 | - make check
12 | notifications:
13 | email: false
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # httpdoc Changelog
2 |
3 | ## 0.1.0 (2018/03/05)
4 |
5 | Initial release.
6 | The code has been unchanged for the past three years but I only noticed I
7 | forgot to tag a version.
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to httpdoc
2 |
3 | ## Documentation
4 |
5 | The documentation is written in [YAML][] files under `_docs/`. It’s primarily
6 | intended for Web developers, not as a complete reference of the HTTP standard.
7 |
8 | Please keep the language simple, with the following rules:
9 |
10 | - Acknowledge your sources, and add them in the `refs` section of any resource
11 | - Keep the text width under 79 characters, including indentation
12 | - Unlike the RFCs, we use lower-cased verbs, like “should” and “must” instead
13 | of “SHOULD” and “MUST”.
14 |
15 | [YAML]: http://en.wikipedia.org/wiki/YAML
16 |
--------------------------------------------------------------------------------
/Godeps/Godeps.json:
--------------------------------------------------------------------------------
1 | {
2 | "ImportPath": "github.com/bfontaine/httpdoc",
3 | "GoVersion": "go1.4.2",
4 | "Packages": [
5 | "./..."
6 | ],
7 | "Deps": [
8 | {
9 | "ImportPath": "github.com/stretchr/testify/assert",
10 | "Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325"
11 | },
12 | {
13 | "ImportPath": "github.com/stretchr/testify/require",
14 | "Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325"
15 | },
16 | {
17 | "ImportPath": "gopkg.in/yaml.v2",
18 | "Rev": "49c95bdc21843256fb6c4e0d370a05f24a0bf213"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/Godeps/Readme:
--------------------------------------------------------------------------------
1 | This directory tree is generated automatically by godep.
2 |
3 | Please do not edit.
4 |
5 | See https://github.com/tools/godep for more information.
6 |
--------------------------------------------------------------------------------
/Godeps/_workspace/.gitignore:
--------------------------------------------------------------------------------
1 | /pkg
2 | /bin
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "errors"
5 | "regexp"
6 | "testing"
7 | "time"
8 | )
9 |
10 | // AssertionTesterInterface defines an interface to be used for testing assertion methods
11 | type AssertionTesterInterface interface {
12 | TestMethod()
13 | }
14 |
15 | // AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface
16 | type AssertionTesterConformingObject struct {
17 | }
18 |
19 | func (a *AssertionTesterConformingObject) TestMethod() {
20 | }
21 |
22 | // AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface
23 | type AssertionTesterNonConformingObject struct {
24 | }
25 |
26 | func TestObjectsAreEqual(t *testing.T) {
27 |
28 | if !ObjectsAreEqual("Hello World", "Hello World") {
29 | t.Error("objectsAreEqual should return true")
30 | }
31 | if !ObjectsAreEqual(123, 123) {
32 | t.Error("objectsAreEqual should return true")
33 | }
34 | if !ObjectsAreEqual(123.5, 123.5) {
35 | t.Error("objectsAreEqual should return true")
36 | }
37 | if !ObjectsAreEqual([]byte("Hello World"), []byte("Hello World")) {
38 | t.Error("objectsAreEqual should return true")
39 | }
40 | if !ObjectsAreEqual(nil, nil) {
41 | t.Error("objectsAreEqual should return true")
42 | }
43 | if ObjectsAreEqual(map[int]int{5: 10}, map[int]int{10: 20}) {
44 | t.Error("objectsAreEqual should return false")
45 | }
46 | if ObjectsAreEqual('x', "x") {
47 | t.Error("objectsAreEqual should return false")
48 | }
49 | if ObjectsAreEqual("x", 'x') {
50 | t.Error("objectsAreEqual should return false")
51 | }
52 | if ObjectsAreEqual(0, 0.1) {
53 | t.Error("objectsAreEqual should return false")
54 | }
55 | if ObjectsAreEqual(0.1, 0) {
56 | t.Error("objectsAreEqual should return false")
57 | }
58 | if ObjectsAreEqual(uint32(10), int32(10)) {
59 | t.Error("objectsAreEqual should return false")
60 | }
61 | if !ObjectsAreEqualValues(uint32(10), int32(10)) {
62 | t.Error("ObjectsAreEqualValues should return true")
63 | }
64 |
65 | }
66 |
67 | func TestImplements(t *testing.T) {
68 |
69 | mockT := new(testing.T)
70 |
71 | if !Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
72 | t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface")
73 | }
74 | if Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
75 | t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
76 | }
77 |
78 | }
79 |
80 | func TestIsType(t *testing.T) {
81 |
82 | mockT := new(testing.T)
83 |
84 | if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
85 | t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
86 | }
87 | if IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
88 | t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
89 | }
90 |
91 | }
92 |
93 | func TestEqual(t *testing.T) {
94 |
95 | mockT := new(testing.T)
96 |
97 | if !Equal(mockT, "Hello World", "Hello World") {
98 | t.Error("Equal should return true")
99 | }
100 | if !Equal(mockT, 123, 123) {
101 | t.Error("Equal should return true")
102 | }
103 | if !Equal(mockT, 123.5, 123.5) {
104 | t.Error("Equal should return true")
105 | }
106 | if !Equal(mockT, []byte("Hello World"), []byte("Hello World")) {
107 | t.Error("Equal should return true")
108 | }
109 | if !Equal(mockT, nil, nil) {
110 | t.Error("Equal should return true")
111 | }
112 | if !Equal(mockT, int32(123), int32(123)) {
113 | t.Error("Equal should return true")
114 | }
115 | if !Equal(mockT, uint64(123), uint64(123)) {
116 | t.Error("Equal should return true")
117 | }
118 | funcA := func() int { return 42 }
119 | if !Equal(mockT, funcA, funcA) {
120 | t.Error("Equal should return true")
121 | }
122 |
123 | }
124 |
125 | func TestNotNil(t *testing.T) {
126 |
127 | mockT := new(testing.T)
128 |
129 | if !NotNil(mockT, new(AssertionTesterConformingObject)) {
130 | t.Error("NotNil should return true: object is not nil")
131 | }
132 | if NotNil(mockT, nil) {
133 | t.Error("NotNil should return false: object is nil")
134 | }
135 |
136 | }
137 |
138 | func TestNil(t *testing.T) {
139 |
140 | mockT := new(testing.T)
141 |
142 | if !Nil(mockT, nil) {
143 | t.Error("Nil should return true: object is nil")
144 | }
145 | if Nil(mockT, new(AssertionTesterConformingObject)) {
146 | t.Error("Nil should return false: object is not nil")
147 | }
148 |
149 | }
150 |
151 | func TestTrue(t *testing.T) {
152 |
153 | mockT := new(testing.T)
154 |
155 | if !True(mockT, true) {
156 | t.Error("True should return true")
157 | }
158 | if True(mockT, false) {
159 | t.Error("True should return false")
160 | }
161 |
162 | }
163 |
164 | func TestFalse(t *testing.T) {
165 |
166 | mockT := new(testing.T)
167 |
168 | if !False(mockT, false) {
169 | t.Error("False should return true")
170 | }
171 | if False(mockT, true) {
172 | t.Error("False should return false")
173 | }
174 |
175 | }
176 |
177 | func TestExactly(t *testing.T) {
178 |
179 | mockT := new(testing.T)
180 |
181 | a := float32(1)
182 | b := float64(1)
183 | c := float32(1)
184 | d := float32(2)
185 |
186 | if Exactly(mockT, a, b) {
187 | t.Error("Exactly should return false")
188 | }
189 | if Exactly(mockT, a, d) {
190 | t.Error("Exactly should return false")
191 | }
192 | if !Exactly(mockT, a, c) {
193 | t.Error("Exactly should return true")
194 | }
195 |
196 | if Exactly(mockT, nil, a) {
197 | t.Error("Exactly should return false")
198 | }
199 | if Exactly(mockT, a, nil) {
200 | t.Error("Exactly should return false")
201 | }
202 |
203 | }
204 |
205 | func TestNotEqual(t *testing.T) {
206 |
207 | mockT := new(testing.T)
208 |
209 | if !NotEqual(mockT, "Hello World", "Hello World!") {
210 | t.Error("NotEqual should return true")
211 | }
212 | if !NotEqual(mockT, 123, 1234) {
213 | t.Error("NotEqual should return true")
214 | }
215 | if !NotEqual(mockT, 123.5, 123.55) {
216 | t.Error("NotEqual should return true")
217 | }
218 | if !NotEqual(mockT, []byte("Hello World"), []byte("Hello World!")) {
219 | t.Error("NotEqual should return true")
220 | }
221 | if !NotEqual(mockT, nil, new(AssertionTesterConformingObject)) {
222 | t.Error("NotEqual should return true")
223 | }
224 | funcA := func() int { return 23 }
225 | funcB := func() int { return 42 }
226 | if !NotEqual(mockT, funcA, funcB) {
227 | t.Error("NotEqual should return true")
228 | }
229 |
230 | if NotEqual(mockT, "Hello World", "Hello World") {
231 | t.Error("NotEqual should return false")
232 | }
233 | if NotEqual(mockT, 123, 123) {
234 | t.Error("NotEqual should return false")
235 | }
236 | if NotEqual(mockT, 123.5, 123.5) {
237 | t.Error("NotEqual should return false")
238 | }
239 | if NotEqual(mockT, []byte("Hello World"), []byte("Hello World")) {
240 | t.Error("NotEqual should return false")
241 | }
242 | if NotEqual(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
243 | t.Error("NotEqual should return false")
244 | }
245 | }
246 |
247 | type A struct {
248 | Name, Value string
249 | }
250 |
251 | func TestContains(t *testing.T) {
252 |
253 | mockT := new(testing.T)
254 | list := []string{"Foo", "Bar"}
255 | complexList := []*A{
256 | {"b", "c"},
257 | {"d", "e"},
258 | {"g", "h"},
259 | {"j", "k"},
260 | }
261 |
262 | if !Contains(mockT, "Hello World", "Hello") {
263 | t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
264 | }
265 | if Contains(mockT, "Hello World", "Salut") {
266 | t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
267 | }
268 |
269 | if !Contains(mockT, list, "Bar") {
270 | t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Bar\"")
271 | }
272 | if Contains(mockT, list, "Salut") {
273 | t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
274 | }
275 | if !Contains(mockT, complexList, &A{"g", "h"}) {
276 | t.Error("Contains should return true: complexList contains {\"g\", \"h\"}")
277 | }
278 | if Contains(mockT, complexList, &A{"g", "e"}) {
279 | t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
280 | }
281 | }
282 |
283 | func TestNotContains(t *testing.T) {
284 |
285 | mockT := new(testing.T)
286 | list := []string{"Foo", "Bar"}
287 |
288 | if !NotContains(mockT, "Hello World", "Hello!") {
289 | t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
290 | }
291 | if NotContains(mockT, "Hello World", "Hello") {
292 | t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
293 | }
294 |
295 | if !NotContains(mockT, list, "Foo!") {
296 | t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
297 | }
298 | if NotContains(mockT, list, "Foo") {
299 | t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
300 | }
301 |
302 | }
303 |
304 | func Test_includeElement(t *testing.T) {
305 |
306 | list1 := []string{"Foo", "Bar"}
307 | list2 := []int{1, 2}
308 |
309 | ok, found := includeElement("Hello World", "World")
310 | True(t, ok)
311 | True(t, found)
312 |
313 | ok, found = includeElement(list1, "Foo")
314 | True(t, ok)
315 | True(t, found)
316 |
317 | ok, found = includeElement(list1, "Bar")
318 | True(t, ok)
319 | True(t, found)
320 |
321 | ok, found = includeElement(list2, 1)
322 | True(t, ok)
323 | True(t, found)
324 |
325 | ok, found = includeElement(list2, 2)
326 | True(t, ok)
327 | True(t, found)
328 |
329 | ok, found = includeElement(list1, "Foo!")
330 | True(t, ok)
331 | False(t, found)
332 |
333 | ok, found = includeElement(list2, 3)
334 | True(t, ok)
335 | False(t, found)
336 |
337 | ok, found = includeElement(list2, "1")
338 | True(t, ok)
339 | False(t, found)
340 |
341 | ok, found = includeElement(1433, "1")
342 | False(t, ok)
343 | False(t, found)
344 |
345 | }
346 |
347 | func TestCondition(t *testing.T) {
348 | mockT := new(testing.T)
349 |
350 | if !Condition(mockT, func() bool { return true }, "Truth") {
351 | t.Error("Condition should return true")
352 | }
353 |
354 | if Condition(mockT, func() bool { return false }, "Lie") {
355 | t.Error("Condition should return false")
356 | }
357 |
358 | }
359 |
360 | func TestDidPanic(t *testing.T) {
361 |
362 | if funcDidPanic, _ := didPanic(func() {
363 | panic("Panic!")
364 | }); !funcDidPanic {
365 | t.Error("didPanic should return true")
366 | }
367 |
368 | if funcDidPanic, _ := didPanic(func() {
369 | }); funcDidPanic {
370 | t.Error("didPanic should return false")
371 | }
372 |
373 | }
374 |
375 | func TestPanics(t *testing.T) {
376 |
377 | mockT := new(testing.T)
378 |
379 | if !Panics(mockT, func() {
380 | panic("Panic!")
381 | }) {
382 | t.Error("Panics should return true")
383 | }
384 |
385 | if Panics(mockT, func() {
386 | }) {
387 | t.Error("Panics should return false")
388 | }
389 |
390 | }
391 |
392 | func TestNotPanics(t *testing.T) {
393 |
394 | mockT := new(testing.T)
395 |
396 | if !NotPanics(mockT, func() {
397 | }) {
398 | t.Error("NotPanics should return true")
399 | }
400 |
401 | if NotPanics(mockT, func() {
402 | panic("Panic!")
403 | }) {
404 | t.Error("NotPanics should return false")
405 | }
406 |
407 | }
408 |
409 | func TestEqual_Funcs(t *testing.T) {
410 |
411 | type f func() int
412 | f1 := func() int { return 1 }
413 | f2 := func() int { return 2 }
414 |
415 | f1Copy := f1
416 |
417 | Equal(t, f1Copy, f1, "Funcs are the same and should be considered equal")
418 | NotEqual(t, f1, f2, "f1 and f2 are different")
419 |
420 | }
421 |
422 | func TestNoError(t *testing.T) {
423 |
424 | mockT := new(testing.T)
425 |
426 | // start with a nil error
427 | var err error
428 |
429 | True(t, NoError(mockT, err), "NoError should return True for nil arg")
430 |
431 | // now set an error
432 | err = errors.New("some error")
433 |
434 | False(t, NoError(mockT, err), "NoError with error should return False")
435 |
436 | }
437 |
438 | func TestError(t *testing.T) {
439 |
440 | mockT := new(testing.T)
441 |
442 | // start with a nil error
443 | var err error
444 |
445 | False(t, Error(mockT, err), "Error should return False for nil arg")
446 |
447 | // now set an error
448 | err = errors.New("some error")
449 |
450 | True(t, Error(mockT, err), "Error with error should return True")
451 |
452 | }
453 |
454 | func TestEqualError(t *testing.T) {
455 | mockT := new(testing.T)
456 |
457 | // start with a nil error
458 | var err error
459 | False(t, EqualError(mockT, err, ""),
460 | "EqualError should return false for nil arg")
461 |
462 | // now set an error
463 | err = errors.New("some error")
464 | False(t, EqualError(mockT, err, "Not some error"),
465 | "EqualError should return false for different error string")
466 | True(t, EqualError(mockT, err, "some error"),
467 | "EqualError should return true")
468 | }
469 |
470 | func Test_isEmpty(t *testing.T) {
471 |
472 | chWithValue := make(chan struct{}, 1)
473 | chWithValue <- struct{}{}
474 |
475 | True(t, isEmpty(""))
476 | True(t, isEmpty(nil))
477 | True(t, isEmpty([]string{}))
478 | True(t, isEmpty(0))
479 | True(t, isEmpty(int32(0)))
480 | True(t, isEmpty(int64(0)))
481 | True(t, isEmpty(false))
482 | True(t, isEmpty(map[string]string{}))
483 | True(t, isEmpty(new(time.Time)))
484 | True(t, isEmpty(make(chan struct{})))
485 | False(t, isEmpty("something"))
486 | False(t, isEmpty(errors.New("something")))
487 | False(t, isEmpty([]string{"something"}))
488 | False(t, isEmpty(1))
489 | False(t, isEmpty(true))
490 | False(t, isEmpty(map[string]string{"Hello": "World"}))
491 | False(t, isEmpty(chWithValue))
492 |
493 | }
494 |
495 | func TestEmpty(t *testing.T) {
496 |
497 | mockT := new(testing.T)
498 | chWithValue := make(chan struct{}, 1)
499 | chWithValue <- struct{}{}
500 |
501 | True(t, Empty(mockT, ""), "Empty string is empty")
502 | True(t, Empty(mockT, nil), "Nil is empty")
503 | True(t, Empty(mockT, []string{}), "Empty string array is empty")
504 | True(t, Empty(mockT, 0), "Zero int value is empty")
505 | True(t, Empty(mockT, false), "False value is empty")
506 | True(t, Empty(mockT, make(chan struct{})), "Channel without values is empty")
507 |
508 | False(t, Empty(mockT, "something"), "Non Empty string is not empty")
509 | False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty")
510 | False(t, Empty(mockT, []string{"something"}), "Non empty string array is not empty")
511 | False(t, Empty(mockT, 1), "Non-zero int value is not empty")
512 | False(t, Empty(mockT, true), "True value is not empty")
513 | False(t, Empty(mockT, chWithValue), "Channel with values is not empty")
514 | }
515 |
516 | func TestNotEmpty(t *testing.T) {
517 |
518 | mockT := new(testing.T)
519 | chWithValue := make(chan struct{}, 1)
520 | chWithValue <- struct{}{}
521 |
522 | False(t, NotEmpty(mockT, ""), "Empty string is empty")
523 | False(t, NotEmpty(mockT, nil), "Nil is empty")
524 | False(t, NotEmpty(mockT, []string{}), "Empty string array is empty")
525 | False(t, NotEmpty(mockT, 0), "Zero int value is empty")
526 | False(t, NotEmpty(mockT, false), "False value is empty")
527 | False(t, NotEmpty(mockT, make(chan struct{})), "Channel without values is empty")
528 |
529 | True(t, NotEmpty(mockT, "something"), "Non Empty string is not empty")
530 | True(t, NotEmpty(mockT, errors.New("something")), "Non nil object is not empty")
531 | True(t, NotEmpty(mockT, []string{"something"}), "Non empty string array is not empty")
532 | True(t, NotEmpty(mockT, 1), "Non-zero int value is not empty")
533 | True(t, NotEmpty(mockT, true), "True value is not empty")
534 | True(t, NotEmpty(mockT, chWithValue), "Channel with values is not empty")
535 | }
536 |
537 | func Test_getLen(t *testing.T) {
538 | falseCases := []interface{}{
539 | nil,
540 | 0,
541 | true,
542 | false,
543 | 'A',
544 | struct{}{},
545 | }
546 | for _, v := range falseCases {
547 | ok, l := getLen(v)
548 | False(t, ok, "Expected getLen fail to get length of %#v", v)
549 | Equal(t, 0, l, "getLen should return 0 for %#v", v)
550 | }
551 |
552 | ch := make(chan int, 5)
553 | ch <- 1
554 | ch <- 2
555 | ch <- 3
556 | trueCases := []struct {
557 | v interface{}
558 | l int
559 | }{
560 | {[]int{1, 2, 3}, 3},
561 | {[...]int{1, 2, 3}, 3},
562 | {"ABC", 3},
563 | {map[int]int{1: 2, 2: 4, 3: 6}, 3},
564 | {ch, 3},
565 |
566 | {[]int{}, 0},
567 | {map[int]int{}, 0},
568 | {make(chan int), 0},
569 |
570 | {[]int(nil), 0},
571 | {map[int]int(nil), 0},
572 | {(chan int)(nil), 0},
573 | }
574 |
575 | for _, c := range trueCases {
576 | ok, l := getLen(c.v)
577 | True(t, ok, "Expected getLen success to get length of %#v", c.v)
578 | Equal(t, c.l, l)
579 | }
580 | }
581 |
582 | func TestLen(t *testing.T) {
583 | mockT := new(testing.T)
584 |
585 | False(t, Len(mockT, nil, 0), "nil does not have length")
586 | False(t, Len(mockT, 0, 0), "int does not have length")
587 | False(t, Len(mockT, true, 0), "true does not have length")
588 | False(t, Len(mockT, false, 0), "false does not have length")
589 | False(t, Len(mockT, 'A', 0), "Rune does not have length")
590 | False(t, Len(mockT, struct{}{}, 0), "Struct does not have length")
591 |
592 | ch := make(chan int, 5)
593 | ch <- 1
594 | ch <- 2
595 | ch <- 3
596 |
597 | cases := []struct {
598 | v interface{}
599 | l int
600 | }{
601 | {[]int{1, 2, 3}, 3},
602 | {[...]int{1, 2, 3}, 3},
603 | {"ABC", 3},
604 | {map[int]int{1: 2, 2: 4, 3: 6}, 3},
605 | {ch, 3},
606 |
607 | {[]int{}, 0},
608 | {map[int]int{}, 0},
609 | {make(chan int), 0},
610 |
611 | {[]int(nil), 0},
612 | {map[int]int(nil), 0},
613 | {(chan int)(nil), 0},
614 | }
615 |
616 | for _, c := range cases {
617 | True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
618 | }
619 |
620 | cases = []struct {
621 | v interface{}
622 | l int
623 | }{
624 | {[]int{1, 2, 3}, 4},
625 | {[...]int{1, 2, 3}, 2},
626 | {"ABC", 2},
627 | {map[int]int{1: 2, 2: 4, 3: 6}, 4},
628 | {ch, 2},
629 |
630 | {[]int{}, 1},
631 | {map[int]int{}, 1},
632 | {make(chan int), 1},
633 |
634 | {[]int(nil), 1},
635 | {map[int]int(nil), 1},
636 | {(chan int)(nil), 1},
637 | }
638 |
639 | for _, c := range cases {
640 | False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
641 | }
642 | }
643 |
644 | func TestWithinDuration(t *testing.T) {
645 |
646 | mockT := new(testing.T)
647 | a := time.Now()
648 | b := a.Add(10 * time.Second)
649 |
650 | True(t, WithinDuration(mockT, a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
651 | True(t, WithinDuration(mockT, b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
652 |
653 | False(t, WithinDuration(mockT, a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
654 | False(t, WithinDuration(mockT, b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
655 |
656 | False(t, WithinDuration(mockT, a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
657 | False(t, WithinDuration(mockT, b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
658 |
659 | False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
660 | False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
661 | }
662 |
663 | func TestInDelta(t *testing.T) {
664 | mockT := new(testing.T)
665 |
666 | True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
667 | True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
668 | True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1")
669 | False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
670 | False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
671 | False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
672 |
673 | cases := []struct {
674 | a, b interface{}
675 | delta float64
676 | }{
677 | {uint8(2), uint8(1), 1},
678 | {uint16(2), uint16(1), 1},
679 | {uint32(2), uint32(1), 1},
680 | {uint64(2), uint64(1), 1},
681 |
682 | {int(2), int(1), 1},
683 | {int8(2), int8(1), 1},
684 | {int16(2), int16(1), 1},
685 | {int32(2), int32(1), 1},
686 | {int64(2), int64(1), 1},
687 |
688 | {float32(2), float32(1), 1},
689 | {float64(2), float64(1), 1},
690 | }
691 |
692 | for _, tc := range cases {
693 | True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
694 | }
695 | }
696 |
697 | func TestInEpsilon(t *testing.T) {
698 | mockT := new(testing.T)
699 |
700 | cases := []struct {
701 | a, b interface{}
702 | epsilon float64
703 | }{
704 | {uint8(2), uint16(2), .001},
705 | {2.1, 2.2, 0.1},
706 | {2.2, 2.1, 0.1},
707 | {-2.1, -2.2, 0.1},
708 | {-2.2, -2.1, 0.1},
709 | {uint64(100), uint8(101), 0.01},
710 | {0.1, -0.1, 2},
711 | }
712 |
713 | for _, tc := range cases {
714 | True(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
715 | }
716 |
717 | cases = []struct {
718 | a, b interface{}
719 | epsilon float64
720 | }{
721 | {uint8(2), int16(-2), .001},
722 | {uint64(100), uint8(102), 0.01},
723 | {2.1, 2.2, 0.001},
724 | {2.2, 2.1, 0.001},
725 | {2.1, -2.2, 1},
726 | {2.1, "bla-bla", 0},
727 | {0.1, -0.1, 1.99},
728 | }
729 |
730 | for _, tc := range cases {
731 | False(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
732 | }
733 |
734 | }
735 |
736 | func TestRegexp(t *testing.T) {
737 | mockT := new(testing.T)
738 |
739 | cases := []struct {
740 | rx, str string
741 | }{
742 | {"^start", "start of the line"},
743 | {"end$", "in the end"},
744 | {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
745 | }
746 |
747 | for _, tc := range cases {
748 | True(t, Regexp(mockT, tc.rx, tc.str))
749 | True(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
750 | False(t, NotRegexp(mockT, tc.rx, tc.str))
751 | False(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
752 | }
753 |
754 | cases = []struct {
755 | rx, str string
756 | }{
757 | {"^asdfastart", "Not the start of the line"},
758 | {"end$", "in the end."},
759 | {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
760 | }
761 |
762 | for _, tc := range cases {
763 | False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
764 | False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
765 | True(t, NotRegexp(mockT, tc.rx, tc.str))
766 | True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
767 | }
768 | }
769 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go:
--------------------------------------------------------------------------------
1 | // A set of comprehensive testing tools for use with the normal Go testing system.
2 | //
3 | // Example Usage
4 | //
5 | // The following is a complete example using assert in a standard test function:
6 | // import (
7 | // "testing"
8 | // "github.com/stretchr/testify/assert"
9 | // )
10 | //
11 | // func TestSomething(t *testing.T) {
12 | //
13 | // var a string = "Hello"
14 | // var b string = "Hello"
15 | //
16 | // assert.Equal(t, a, b, "The two words should be the same.")
17 | //
18 | // }
19 | //
20 | // if you assert many times, use the below:
21 | //
22 | // import (
23 | // "testing"
24 | // "github.com/stretchr/testify/assert"
25 | // )
26 | //
27 | // func TestSomething(t *testing.T) {
28 | // assert := assert.New(t)
29 | //
30 | // var a string = "Hello"
31 | // var b string = "Hello"
32 | //
33 | // assert.Equal(a, b, "The two words should be the same.")
34 | // }
35 | //
36 | // Assertions
37 | //
38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package.
39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the
40 | // testing framework. This allows the assertion funcs to write the failings and other details to
41 | // the correct place.
42 | //
43 | // Every assertion function also takes an optional string message as the final argument,
44 | // allowing custom error messages to be appended to the message the assertion method outputs.
45 | //
46 | // Here is an overview of the assert functions:
47 | //
48 | // assert.Equal(t, expected, actual [, message [, format-args])
49 | //
50 | // assert.NotEqual(t, notExpected, actual [, message [, format-args]])
51 | //
52 | // assert.True(t, actualBool [, message [, format-args]])
53 | //
54 | // assert.False(t, actualBool [, message [, format-args]])
55 | //
56 | // assert.Nil(t, actualObject [, message [, format-args]])
57 | //
58 | // assert.NotNil(t, actualObject [, message [, format-args]])
59 | //
60 | // assert.Empty(t, actualObject [, message [, format-args]])
61 | //
62 | // assert.NotEmpty(t, actualObject [, message [, format-args]])
63 | //
64 | // assert.Len(t, actualObject, expectedLength, [, message [, format-args]])
65 | //
66 | // assert.Error(t, errorObject [, message [, format-args]])
67 | //
68 | // assert.NoError(t, errorObject [, message [, format-args]])
69 | //
70 | // assert.EqualError(t, theError, errString [, message [, format-args]])
71 | //
72 | // assert.Implements(t, (*MyInterface)(nil), new(MyObject) [,message [, format-args]])
73 | //
74 | // assert.IsType(t, expectedObject, actualObject [, message [, format-args]])
75 | //
76 | // assert.Contains(t, stringOrSlice, substringOrElement [, message [, format-args]])
77 | //
78 | // assert.NotContains(t, stringOrSlice, substringOrElement [, message [, format-args]])
79 | //
80 | // assert.Panics(t, func(){
81 | //
82 | // // call code that should panic
83 | //
84 | // } [, message [, format-args]])
85 | //
86 | // assert.NotPanics(t, func(){
87 | //
88 | // // call code that should not panic
89 | //
90 | // } [, message [, format-args]])
91 | //
92 | // assert.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]])
93 | //
94 | // assert.InDelta(t, numA, numB, delta, [, message [, format-args]])
95 | //
96 | // assert.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]])
97 | //
98 | // assert package contains Assertions object. it has assertion methods.
99 | //
100 | // Here is an overview of the assert functions:
101 | // assert.Equal(expected, actual [, message [, format-args])
102 | //
103 | // assert.NotEqual(notExpected, actual [, message [, format-args]])
104 | //
105 | // assert.True(actualBool [, message [, format-args]])
106 | //
107 | // assert.False(actualBool [, message [, format-args]])
108 | //
109 | // assert.Nil(actualObject [, message [, format-args]])
110 | //
111 | // assert.NotNil(actualObject [, message [, format-args]])
112 | //
113 | // assert.Empty(actualObject [, message [, format-args]])
114 | //
115 | // assert.NotEmpty(actualObject [, message [, format-args]])
116 | //
117 | // assert.Len(actualObject, expectedLength, [, message [, format-args]])
118 | //
119 | // assert.Error(errorObject [, message [, format-args]])
120 | //
121 | // assert.NoError(errorObject [, message [, format-args]])
122 | //
123 | // assert.EqualError(theError, errString [, message [, format-args]])
124 | //
125 | // assert.Implements((*MyInterface)(nil), new(MyObject) [,message [, format-args]])
126 | //
127 | // assert.IsType(expectedObject, actualObject [, message [, format-args]])
128 | //
129 | // assert.Contains(stringOrSlice, substringOrElement [, message [, format-args]])
130 | //
131 | // assert.NotContains(stringOrSlice, substringOrElement [, message [, format-args]])
132 | //
133 | // assert.Panics(func(){
134 | //
135 | // // call code that should panic
136 | //
137 | // } [, message [, format-args]])
138 | //
139 | // assert.NotPanics(func(){
140 | //
141 | // // call code that should not panic
142 | //
143 | // } [, message [, format-args]])
144 | //
145 | // assert.WithinDuration(timeA, timeB, deltaTime, [, message [, format-args]])
146 | //
147 | // assert.InDelta(numA, numB, delta, [, message [, format-args]])
148 | //
149 | // assert.InEpsilon(numA, numB, epsilon, [, message [, format-args]])
150 | package assert
151 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/errors.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | // AnError is an error instance useful for testing. If the code does not care
8 | // about error specifics, and only needs to return the error for example, this
9 | // error should be used to make the test code more readable.
10 | var AnError = errors.New("assert.AnError general error for testing")
11 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import "time"
4 |
5 | type Assertions struct {
6 | t TestingT
7 | }
8 |
9 | func New(t TestingT) *Assertions {
10 | return &Assertions{
11 | t: t,
12 | }
13 | }
14 |
15 | // Fail reports a failure through
16 | func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
17 | return Fail(a.t, failureMessage, msgAndArgs...)
18 | }
19 |
20 | // Implements asserts that an object is implemented by the specified interface.
21 | //
22 | // assert.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
23 | func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
24 | return Implements(a.t, interfaceObject, object, msgAndArgs...)
25 | }
26 |
27 | // IsType asserts that the specified objects are of the same type.
28 | func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
29 | return IsType(a.t, expectedType, object, msgAndArgs...)
30 | }
31 |
32 | // Equal asserts that two objects are equal.
33 | //
34 | // assert.Equal(123, 123, "123 and 123 should be equal")
35 | //
36 | // Returns whether the assertion was successful (true) or not (false).
37 | func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) bool {
38 | return Equal(a.t, expected, actual, msgAndArgs...)
39 | }
40 |
41 | // EqualValues asserts that two objects are equal or convertable to the same types
42 | // and equal.
43 | //
44 | // assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
45 | //
46 | // Returns whether the assertion was successful (true) or not (false).
47 | func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) bool {
48 | return EqualValues(a.t, expected, actual, msgAndArgs...)
49 | }
50 |
51 | // Exactly asserts that two objects are equal is value and type.
52 | //
53 | // assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
54 | //
55 | // Returns whether the assertion was successful (true) or not (false).
56 | func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) bool {
57 | return Exactly(a.t, expected, actual, msgAndArgs...)
58 | }
59 |
60 | // NotNil asserts that the specified object is not nil.
61 | //
62 | // assert.NotNil(err, "err should be something")
63 | //
64 | // Returns whether the assertion was successful (true) or not (false).
65 | func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
66 | return NotNil(a.t, object, msgAndArgs...)
67 | }
68 |
69 | // Nil asserts that the specified object is nil.
70 | //
71 | // assert.Nil(err, "err should be nothing")
72 | //
73 | // Returns whether the assertion was successful (true) or not (false).
74 | func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
75 | return Nil(a.t, object, msgAndArgs...)
76 | }
77 |
78 | // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
79 | // slice with len == 0.
80 | //
81 | // assert.Empty(obj)
82 | //
83 | // Returns whether the assertion was successful (true) or not (false).
84 | func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
85 | return Empty(a.t, object, msgAndArgs...)
86 | }
87 |
88 | // Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
89 | // slice with len == 0.
90 | //
91 | // if assert.NotEmpty(obj) {
92 | // assert.Equal("two", obj[1])
93 | // }
94 | //
95 | // Returns whether the assertion was successful (true) or not (false).
96 | func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
97 | return NotEmpty(a.t, object, msgAndArgs...)
98 | }
99 |
100 | // Len asserts that the specified object has specific length.
101 | // Len also fails if the object has a type that len() not accept.
102 | //
103 | // assert.Len(mySlice, 3, "The size of slice is not 3")
104 | //
105 | // Returns whether the assertion was successful (true) or not (false).
106 | func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
107 | return Len(a.t, object, length, msgAndArgs...)
108 | }
109 |
110 | // True asserts that the specified value is true.
111 | //
112 | // assert.True(myBool, "myBool should be true")
113 | //
114 | // Returns whether the assertion was successful (true) or not (false).
115 | func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
116 | return True(a.t, value, msgAndArgs...)
117 | }
118 |
119 | // False asserts that the specified value is true.
120 | //
121 | // assert.False(myBool, "myBool should be false")
122 | //
123 | // Returns whether the assertion was successful (true) or not (false).
124 | func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
125 | return False(a.t, value, msgAndArgs...)
126 | }
127 |
128 | // NotEqual asserts that the specified values are NOT equal.
129 | //
130 | // assert.NotEqual(obj1, obj2, "two objects shouldn't be equal")
131 | //
132 | // Returns whether the assertion was successful (true) or not (false).
133 | func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) bool {
134 | return NotEqual(a.t, expected, actual, msgAndArgs...)
135 | }
136 |
137 | // Contains asserts that the specified string contains the specified substring.
138 | //
139 | // assert.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
140 | //
141 | // Returns whether the assertion was successful (true) or not (false).
142 | func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) bool {
143 | return Contains(a.t, s, contains, msgAndArgs...)
144 | }
145 |
146 | // NotContains asserts that the specified string does NOT contain the specified substring.
147 | //
148 | // assert.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
149 | //
150 | // Returns whether the assertion was successful (true) or not (false).
151 | func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) bool {
152 | return NotContains(a.t, s, contains, msgAndArgs...)
153 | }
154 |
155 | // Uses a Comparison to assert a complex condition.
156 | func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
157 | return Condition(a.t, comp, msgAndArgs...)
158 | }
159 |
160 | // Panics asserts that the code inside the specified PanicTestFunc panics.
161 | //
162 | // assert.Panics(func(){
163 | // GoCrazy()
164 | // }, "Calling GoCrazy() should panic")
165 | //
166 | // Returns whether the assertion was successful (true) or not (false).
167 | func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
168 | return Panics(a.t, f, msgAndArgs...)
169 | }
170 |
171 | // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
172 | //
173 | // assert.NotPanics(func(){
174 | // RemainCalm()
175 | // }, "Calling RemainCalm() should NOT panic")
176 | //
177 | // Returns whether the assertion was successful (true) or not (false).
178 | func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
179 | return NotPanics(a.t, f, msgAndArgs...)
180 | }
181 |
182 | // WithinDuration asserts that the two times are within duration delta of each other.
183 | //
184 | // assert.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
185 | //
186 | // Returns whether the assertion was successful (true) or not (false).
187 | func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
188 | return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
189 | }
190 |
191 | // InDelta asserts that the two numerals are within delta of each other.
192 | //
193 | // assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
194 | //
195 | // Returns whether the assertion was successful (true) or not (false).
196 | func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
197 | return InDelta(a.t, expected, actual, delta, msgAndArgs...)
198 | }
199 |
200 | // InEpsilon asserts that expected and actual have a relative error less than epsilon
201 | //
202 | // Returns whether the assertion was successful (true) or not (false).
203 | func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
204 | return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
205 | }
206 |
207 | // NoError asserts that a function returned no error (i.e. `nil`).
208 | //
209 | // actualObj, err := SomeFunction()
210 | // if assert.NoError(err) {
211 | // assert.Equal(actualObj, expectedObj)
212 | // }
213 | //
214 | // Returns whether the assertion was successful (true) or not (false).
215 | func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) bool {
216 | return NoError(a.t, theError, msgAndArgs...)
217 | }
218 |
219 | // Error asserts that a function returned an error (i.e. not `nil`).
220 | //
221 | // actualObj, err := SomeFunction()
222 | // if assert.Error(err, "An error was expected") {
223 | // assert.Equal(err, expectedError)
224 | // }
225 | //
226 | // Returns whether the assertion was successful (true) or not (false).
227 | func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) bool {
228 | return Error(a.t, theError, msgAndArgs...)
229 | }
230 |
231 | // EqualError asserts that a function returned an error (i.e. not `nil`)
232 | // and that it is equal to the provided error.
233 | //
234 | // actualObj, err := SomeFunction()
235 | // if assert.Error(err, "An error was expected") {
236 | // assert.Equal(err, expectedError)
237 | // }
238 | //
239 | // Returns whether the assertion was successful (true) or not (false).
240 | func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
241 | return EqualError(a.t, theError, errString, msgAndArgs...)
242 | }
243 |
244 | // Regexp asserts that a specified regexp matches a string.
245 | //
246 | // assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
247 | // assert.Regexp(t, "start...$", "it's not starting")
248 | //
249 | // Returns whether the assertion was successful (true) or not (false).
250 | func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
251 | return Regexp(a.t, rx, str, msgAndArgs...)
252 | }
253 |
254 | // NotRegexp asserts that a specified regexp does not match a string.
255 | //
256 | // assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
257 | // assert.NotRegexp(t, "^start", "it's not starting")
258 | //
259 | // Returns whether the assertion was successful (true) or not (false).
260 | func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
261 | return NotRegexp(a.t, rx, str, msgAndArgs...)
262 | }
263 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "errors"
5 | "regexp"
6 | "testing"
7 | "time"
8 | )
9 |
10 | func TestImplementsWrapper(t *testing.T) {
11 | assert := New(new(testing.T))
12 |
13 | if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
14 | t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface")
15 | }
16 | if assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
17 | t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
18 | }
19 | }
20 |
21 | func TestIsTypeWrapper(t *testing.T) {
22 | assert := New(new(testing.T))
23 |
24 | if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
25 | t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
26 | }
27 | if assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
28 | t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
29 | }
30 |
31 | }
32 |
33 | func TestEqualWrapper(t *testing.T) {
34 | assert := New(new(testing.T))
35 |
36 | if !assert.Equal("Hello World", "Hello World") {
37 | t.Error("Equal should return true")
38 | }
39 | if !assert.Equal(123, 123) {
40 | t.Error("Equal should return true")
41 | }
42 | if !assert.Equal(123.5, 123.5) {
43 | t.Error("Equal should return true")
44 | }
45 | if !assert.Equal([]byte("Hello World"), []byte("Hello World")) {
46 | t.Error("Equal should return true")
47 | }
48 | if !assert.Equal(nil, nil) {
49 | t.Error("Equal should return true")
50 | }
51 | }
52 |
53 | func TestEqualValuesWrapper(t *testing.T) {
54 | assert := New(new(testing.T))
55 |
56 | if !assert.EqualValues(uint32(10), int32(10)) {
57 | t.Error("EqualValues should return true")
58 | }
59 | }
60 |
61 | func TestNotNilWrapper(t *testing.T) {
62 | assert := New(new(testing.T))
63 |
64 | if !assert.NotNil(new(AssertionTesterConformingObject)) {
65 | t.Error("NotNil should return true: object is not nil")
66 | }
67 | if assert.NotNil(nil) {
68 | t.Error("NotNil should return false: object is nil")
69 | }
70 |
71 | }
72 |
73 | func TestNilWrapper(t *testing.T) {
74 | assert := New(new(testing.T))
75 |
76 | if !assert.Nil(nil) {
77 | t.Error("Nil should return true: object is nil")
78 | }
79 | if assert.Nil(new(AssertionTesterConformingObject)) {
80 | t.Error("Nil should return false: object is not nil")
81 | }
82 |
83 | }
84 |
85 | func TestTrueWrapper(t *testing.T) {
86 | assert := New(new(testing.T))
87 |
88 | if !assert.True(true) {
89 | t.Error("True should return true")
90 | }
91 | if assert.True(false) {
92 | t.Error("True should return false")
93 | }
94 |
95 | }
96 |
97 | func TestFalseWrapper(t *testing.T) {
98 | assert := New(new(testing.T))
99 |
100 | if !assert.False(false) {
101 | t.Error("False should return true")
102 | }
103 | if assert.False(true) {
104 | t.Error("False should return false")
105 | }
106 |
107 | }
108 |
109 | func TestExactlyWrapper(t *testing.T) {
110 | assert := New(new(testing.T))
111 |
112 | a := float32(1)
113 | b := float64(1)
114 | c := float32(1)
115 | d := float32(2)
116 |
117 | if assert.Exactly(a, b) {
118 | t.Error("Exactly should return false")
119 | }
120 | if assert.Exactly(a, d) {
121 | t.Error("Exactly should return false")
122 | }
123 | if !assert.Exactly(a, c) {
124 | t.Error("Exactly should return true")
125 | }
126 |
127 | if assert.Exactly(nil, a) {
128 | t.Error("Exactly should return false")
129 | }
130 | if assert.Exactly(a, nil) {
131 | t.Error("Exactly should return false")
132 | }
133 |
134 | }
135 |
136 | func TestNotEqualWrapper(t *testing.T) {
137 |
138 | assert := New(new(testing.T))
139 |
140 | if !assert.NotEqual("Hello World", "Hello World!") {
141 | t.Error("NotEqual should return true")
142 | }
143 | if !assert.NotEqual(123, 1234) {
144 | t.Error("NotEqual should return true")
145 | }
146 | if !assert.NotEqual(123.5, 123.55) {
147 | t.Error("NotEqual should return true")
148 | }
149 | if !assert.NotEqual([]byte("Hello World"), []byte("Hello World!")) {
150 | t.Error("NotEqual should return true")
151 | }
152 | if !assert.NotEqual(nil, new(AssertionTesterConformingObject)) {
153 | t.Error("NotEqual should return true")
154 | }
155 | }
156 |
157 | func TestContainsWrapper(t *testing.T) {
158 |
159 | assert := New(new(testing.T))
160 | list := []string{"Foo", "Bar"}
161 |
162 | if !assert.Contains("Hello World", "Hello") {
163 | t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
164 | }
165 | if assert.Contains("Hello World", "Salut") {
166 | t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
167 | }
168 |
169 | if !assert.Contains(list, "Foo") {
170 | t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
171 | }
172 | if assert.Contains(list, "Salut") {
173 | t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
174 | }
175 |
176 | }
177 |
178 | func TestNotContainsWrapper(t *testing.T) {
179 |
180 | assert := New(new(testing.T))
181 | list := []string{"Foo", "Bar"}
182 |
183 | if !assert.NotContains("Hello World", "Hello!") {
184 | t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
185 | }
186 | if assert.NotContains("Hello World", "Hello") {
187 | t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
188 | }
189 |
190 | if !assert.NotContains(list, "Foo!") {
191 | t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
192 | }
193 | if assert.NotContains(list, "Foo") {
194 | t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
195 | }
196 |
197 | }
198 |
199 | func TestConditionWrapper(t *testing.T) {
200 |
201 | assert := New(new(testing.T))
202 |
203 | if !assert.Condition(func() bool { return true }, "Truth") {
204 | t.Error("Condition should return true")
205 | }
206 |
207 | if assert.Condition(func() bool { return false }, "Lie") {
208 | t.Error("Condition should return false")
209 | }
210 |
211 | }
212 |
213 | func TestDidPanicWrapper(t *testing.T) {
214 |
215 | if funcDidPanic, _ := didPanic(func() {
216 | panic("Panic!")
217 | }); !funcDidPanic {
218 | t.Error("didPanic should return true")
219 | }
220 |
221 | if funcDidPanic, _ := didPanic(func() {
222 | }); funcDidPanic {
223 | t.Error("didPanic should return false")
224 | }
225 |
226 | }
227 |
228 | func TestPanicsWrapper(t *testing.T) {
229 |
230 | assert := New(new(testing.T))
231 |
232 | if !assert.Panics(func() {
233 | panic("Panic!")
234 | }) {
235 | t.Error("Panics should return true")
236 | }
237 |
238 | if assert.Panics(func() {
239 | }) {
240 | t.Error("Panics should return false")
241 | }
242 |
243 | }
244 |
245 | func TestNotPanicsWrapper(t *testing.T) {
246 |
247 | assert := New(new(testing.T))
248 |
249 | if !assert.NotPanics(func() {
250 | }) {
251 | t.Error("NotPanics should return true")
252 | }
253 |
254 | if assert.NotPanics(func() {
255 | panic("Panic!")
256 | }) {
257 | t.Error("NotPanics should return false")
258 | }
259 |
260 | }
261 |
262 | func TestEqualWrapper_Funcs(t *testing.T) {
263 |
264 | assert := New(t)
265 |
266 | type f func() int
267 | var f1 f = func() int { return 1 }
268 | var f2 f = func() int { return 2 }
269 |
270 | var f1_copy f = f1
271 |
272 | assert.Equal(f1_copy, f1, "Funcs are the same and should be considered equal")
273 | assert.NotEqual(f1, f2, "f1 and f2 are different")
274 |
275 | }
276 |
277 | func TestNoErrorWrapper(t *testing.T) {
278 | assert := New(t)
279 | mockAssert := New(new(testing.T))
280 |
281 | // start with a nil error
282 | var err error = nil
283 |
284 | assert.True(mockAssert.NoError(err), "NoError should return True for nil arg")
285 |
286 | // now set an error
287 | err = errors.New("Some error")
288 |
289 | assert.False(mockAssert.NoError(err), "NoError with error should return False")
290 |
291 | }
292 |
293 | func TestErrorWrapper(t *testing.T) {
294 | assert := New(t)
295 | mockAssert := New(new(testing.T))
296 |
297 | // start with a nil error
298 | var err error = nil
299 |
300 | assert.False(mockAssert.Error(err), "Error should return False for nil arg")
301 |
302 | // now set an error
303 | err = errors.New("Some error")
304 |
305 | assert.True(mockAssert.Error(err), "Error with error should return True")
306 |
307 | }
308 |
309 | func TestEqualErrorWrapper(t *testing.T) {
310 | assert := New(t)
311 | mockAssert := New(new(testing.T))
312 |
313 | // start with a nil error
314 | var err error
315 | assert.False(mockAssert.EqualError(err, ""),
316 | "EqualError should return false for nil arg")
317 |
318 | // now set an error
319 | err = errors.New("some error")
320 | assert.False(mockAssert.EqualError(err, "Not some error"),
321 | "EqualError should return false for different error string")
322 | assert.True(mockAssert.EqualError(err, "some error"),
323 | "EqualError should return true")
324 | }
325 |
326 | func TestEmptyWrapper(t *testing.T) {
327 | assert := New(t)
328 | mockAssert := New(new(testing.T))
329 |
330 | assert.True(mockAssert.Empty(""), "Empty string is empty")
331 | assert.True(mockAssert.Empty(nil), "Nil is empty")
332 | assert.True(mockAssert.Empty([]string{}), "Empty string array is empty")
333 | assert.True(mockAssert.Empty(0), "Zero int value is empty")
334 | assert.True(mockAssert.Empty(false), "False value is empty")
335 |
336 | assert.False(mockAssert.Empty("something"), "Non Empty string is not empty")
337 | assert.False(mockAssert.Empty(errors.New("something")), "Non nil object is not empty")
338 | assert.False(mockAssert.Empty([]string{"something"}), "Non empty string array is not empty")
339 | assert.False(mockAssert.Empty(1), "Non-zero int value is not empty")
340 | assert.False(mockAssert.Empty(true), "True value is not empty")
341 |
342 | }
343 |
344 | func TestNotEmptyWrapper(t *testing.T) {
345 | assert := New(t)
346 | mockAssert := New(new(testing.T))
347 |
348 | assert.False(mockAssert.NotEmpty(""), "Empty string is empty")
349 | assert.False(mockAssert.NotEmpty(nil), "Nil is empty")
350 | assert.False(mockAssert.NotEmpty([]string{}), "Empty string array is empty")
351 | assert.False(mockAssert.NotEmpty(0), "Zero int value is empty")
352 | assert.False(mockAssert.NotEmpty(false), "False value is empty")
353 |
354 | assert.True(mockAssert.NotEmpty("something"), "Non Empty string is not empty")
355 | assert.True(mockAssert.NotEmpty(errors.New("something")), "Non nil object is not empty")
356 | assert.True(mockAssert.NotEmpty([]string{"something"}), "Non empty string array is not empty")
357 | assert.True(mockAssert.NotEmpty(1), "Non-zero int value is not empty")
358 | assert.True(mockAssert.NotEmpty(true), "True value is not empty")
359 |
360 | }
361 |
362 | func TestLenWrapper(t *testing.T) {
363 | assert := New(t)
364 | mockAssert := New(new(testing.T))
365 |
366 | assert.False(mockAssert.Len(nil, 0), "nil does not have length")
367 | assert.False(mockAssert.Len(0, 0), "int does not have length")
368 | assert.False(mockAssert.Len(true, 0), "true does not have length")
369 | assert.False(mockAssert.Len(false, 0), "false does not have length")
370 | assert.False(mockAssert.Len('A', 0), "Rune does not have length")
371 | assert.False(mockAssert.Len(struct{}{}, 0), "Struct does not have length")
372 |
373 | ch := make(chan int, 5)
374 | ch <- 1
375 | ch <- 2
376 | ch <- 3
377 |
378 | cases := []struct {
379 | v interface{}
380 | l int
381 | }{
382 | {[]int{1, 2, 3}, 3},
383 | {[...]int{1, 2, 3}, 3},
384 | {"ABC", 3},
385 | {map[int]int{1: 2, 2: 4, 3: 6}, 3},
386 | {ch, 3},
387 |
388 | {[]int{}, 0},
389 | {map[int]int{}, 0},
390 | {make(chan int), 0},
391 |
392 | {[]int(nil), 0},
393 | {map[int]int(nil), 0},
394 | {(chan int)(nil), 0},
395 | }
396 |
397 | for _, c := range cases {
398 | assert.True(mockAssert.Len(c.v, c.l), "%#v have %d items", c.v, c.l)
399 | }
400 | }
401 |
402 | func TestWithinDurationWrapper(t *testing.T) {
403 | assert := New(t)
404 | mockAssert := New(new(testing.T))
405 | a := time.Now()
406 | b := a.Add(10 * time.Second)
407 |
408 | assert.True(mockAssert.WithinDuration(a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
409 | assert.True(mockAssert.WithinDuration(b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
410 |
411 | assert.False(mockAssert.WithinDuration(a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
412 | assert.False(mockAssert.WithinDuration(b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
413 |
414 | assert.False(mockAssert.WithinDuration(a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
415 | assert.False(mockAssert.WithinDuration(b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
416 |
417 | assert.False(mockAssert.WithinDuration(a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
418 | assert.False(mockAssert.WithinDuration(b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
419 | }
420 |
421 | func TestInDeltaWrapper(t *testing.T) {
422 | assert := New(new(testing.T))
423 |
424 | True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
425 | True(t, assert.InDelta(1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
426 | True(t, assert.InDelta(1, 2, 1), "|1 - 2| <= 1")
427 | False(t, assert.InDelta(1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
428 | False(t, assert.InDelta(2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
429 | False(t, assert.InDelta("", nil, 1), "Expected non numerals to fail")
430 |
431 | cases := []struct {
432 | a, b interface{}
433 | delta float64
434 | }{
435 | {uint8(2), uint8(1), 1},
436 | {uint16(2), uint16(1), 1},
437 | {uint32(2), uint32(1), 1},
438 | {uint64(2), uint64(1), 1},
439 |
440 | {int(2), int(1), 1},
441 | {int8(2), int8(1), 1},
442 | {int16(2), int16(1), 1},
443 | {int32(2), int32(1), 1},
444 | {int64(2), int64(1), 1},
445 |
446 | {float32(2), float32(1), 1},
447 | {float64(2), float64(1), 1},
448 | }
449 |
450 | for _, tc := range cases {
451 | True(t, assert.InDelta(tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
452 | }
453 | }
454 |
455 | func TestInEpsilonWrapper(t *testing.T) {
456 | assert := New(new(testing.T))
457 |
458 | cases := []struct {
459 | a, b interface{}
460 | epsilon float64
461 | }{
462 | {uint8(2), uint16(2), .001},
463 | {2.1, 2.2, 0.1},
464 | {2.2, 2.1, 0.1},
465 | {-2.1, -2.2, 0.1},
466 | {-2.2, -2.1, 0.1},
467 | {uint64(100), uint8(101), 0.01},
468 | {0.1, -0.1, 2},
469 | }
470 |
471 | for _, tc := range cases {
472 | True(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
473 | }
474 |
475 | cases = []struct {
476 | a, b interface{}
477 | epsilon float64
478 | }{
479 | {uint8(2), int16(-2), .001},
480 | {uint64(100), uint8(102), 0.01},
481 | {2.1, 2.2, 0.001},
482 | {2.2, 2.1, 0.001},
483 | {2.1, -2.2, 1},
484 | {2.1, "bla-bla", 0},
485 | {0.1, -0.1, 1.99},
486 | }
487 |
488 | for _, tc := range cases {
489 | False(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
490 | }
491 | }
492 |
493 | func TestRegexpWrapper(t *testing.T) {
494 |
495 | assert := New(new(testing.T))
496 |
497 | cases := []struct {
498 | rx, str string
499 | }{
500 | {"^start", "start of the line"},
501 | {"end$", "in the end"},
502 | {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
503 | }
504 |
505 | for _, tc := range cases {
506 | True(t, assert.Regexp(tc.rx, tc.str))
507 | True(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
508 | False(t, assert.NotRegexp(tc.rx, tc.str))
509 | False(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
510 | }
511 |
512 | cases = []struct {
513 | rx, str string
514 | }{
515 | {"^asdfastart", "Not the start of the line"},
516 | {"end$", "in the end."},
517 | {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
518 | }
519 |
520 | for _, tc := range cases {
521 | False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
522 | False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
523 | True(t, assert.NotRegexp(tc.rx, tc.str))
524 | True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
525 | }
526 | }
527 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "net/http/httptest"
7 | "net/url"
8 | "strings"
9 | )
10 |
11 | // httpCode is a helper that returns HTTP code of the response. It returns -1
12 | // if building a new request fails.
13 | func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int {
14 | w := httptest.NewRecorder()
15 | req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
16 | if err != nil {
17 | return -1
18 | }
19 | handler(w, req)
20 | return w.Code
21 | }
22 |
23 | // HTTPSuccess asserts that a specified handler returns a success status code.
24 | //
25 | // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
26 | //
27 | // Returns whether the assertion was successful (true) or not (false).
28 | func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
29 | code := httpCode(handler, mode, url, values)
30 | if code == -1 {
31 | return false
32 | }
33 | return code >= http.StatusOK && code <= http.StatusPartialContent
34 | }
35 |
36 | // HTTPRedirect asserts that a specified handler returns a redirect status code.
37 | //
38 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
39 | //
40 | // Returns whether the assertion was successful (true) or not (false).
41 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
42 | code := httpCode(handler, mode, url, values)
43 | if code == -1 {
44 | return false
45 | }
46 | return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
47 | }
48 |
49 | // HTTPError asserts that a specified handler returns an error status code.
50 | //
51 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
52 | //
53 | // Returns whether the assertion was successful (true) or not (false).
54 | func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
55 | code := httpCode(handler, mode, url, values)
56 | if code == -1 {
57 | return false
58 | }
59 | return code >= http.StatusBadRequest
60 | }
61 |
62 | // HttpBody is a helper that returns HTTP body of the response. It returns
63 | // empty string if building a new request fails.
64 | func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) string {
65 | w := httptest.NewRecorder()
66 | req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
67 | if err != nil {
68 | return ""
69 | }
70 | handler(w, req)
71 | return w.Body.String()
72 | }
73 |
74 | // HTTPBodyContains asserts that a specified handler returns a
75 | // body that contains a string.
76 | //
77 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
78 | //
79 | // Returns whether the assertion was successful (true) or not (false).
80 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
81 | body := HttpBody(handler, mode, url, values)
82 |
83 | contains := strings.Contains(body, fmt.Sprint(str))
84 | if !contains {
85 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
86 | }
87 |
88 | return contains
89 | }
90 |
91 | // HTTPBodyNotContains asserts that a specified handler returns a
92 | // body that does not contain a string.
93 | //
94 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
95 | //
96 | // Returns whether the assertion was successful (true) or not (false).
97 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
98 | body := HttpBody(handler, mode, url, values)
99 |
100 | contains := strings.Contains(body, fmt.Sprint(str))
101 | if contains {
102 | Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)
103 | }
104 |
105 | return !contains
106 | }
107 |
108 | //
109 | // Assertions Wrappers
110 | //
111 |
112 | // HTTPSuccess asserts that a specified handler returns a success status code.
113 | //
114 | // assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
115 | //
116 | // Returns whether the assertion was successful (true) or not (false).
117 | func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool {
118 | return HTTPSuccess(a.t, handler, mode, url, values)
119 | }
120 |
121 | // HTTPRedirect asserts that a specified handler returns a redirect status code.
122 | //
123 | // assert.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
124 | //
125 | // Returns whether the assertion was successful (true) or not (false).
126 | func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, mode, url string, values url.Values) bool {
127 | return HTTPRedirect(a.t, handler, mode, url, values)
128 | }
129 |
130 | // HTTPError asserts that a specified handler returns an error status code.
131 | //
132 | // assert.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
133 | //
134 | // Returns whether the assertion was successful (true) or not (false).
135 | func (a *Assertions) HTTPError(handler http.HandlerFunc, mode, url string, values url.Values) bool {
136 | return HTTPError(a.t, handler, mode, url, values)
137 | }
138 |
139 | // HTTPBodyContains asserts that a specified handler returns a
140 | // body that contains a string.
141 | //
142 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
143 | //
144 | // Returns whether the assertion was successful (true) or not (false).
145 | func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
146 | return HTTPBodyContains(a.t, handler, mode, url, values, str)
147 | }
148 |
149 | // HTTPBodyNotContains asserts that a specified handler returns a
150 | // body that does not contain a string.
151 | //
152 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
153 | //
154 | // Returns whether the assertion was successful (true) or not (false).
155 | func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
156 | return HTTPBodyNotContains(a.t, handler, mode, url, values, str)
157 | }
158 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions_test.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "net/url"
7 | "testing"
8 | )
9 |
10 | func httpOK(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(http.StatusOK)
12 | }
13 |
14 | func httpRedirect(w http.ResponseWriter, r *http.Request) {
15 | w.WriteHeader(http.StatusTemporaryRedirect)
16 | }
17 |
18 | func httpError(w http.ResponseWriter, r *http.Request) {
19 | w.WriteHeader(http.StatusInternalServerError)
20 | }
21 |
22 | func TestHTTPStatuses(t *testing.T) {
23 | assert := New(t)
24 | mockT := new(testing.T)
25 |
26 | assert.Equal(HTTPSuccess(mockT, httpOK, "GET", "/", nil), true)
27 | assert.Equal(HTTPSuccess(mockT, httpRedirect, "GET", "/", nil), false)
28 | assert.Equal(HTTPSuccess(mockT, httpError, "GET", "/", nil), false)
29 |
30 | assert.Equal(HTTPRedirect(mockT, httpOK, "GET", "/", nil), false)
31 | assert.Equal(HTTPRedirect(mockT, httpRedirect, "GET", "/", nil), true)
32 | assert.Equal(HTTPRedirect(mockT, httpError, "GET", "/", nil), false)
33 |
34 | assert.Equal(HTTPError(mockT, httpOK, "GET", "/", nil), false)
35 | assert.Equal(HTTPError(mockT, httpRedirect, "GET", "/", nil), false)
36 | assert.Equal(HTTPError(mockT, httpError, "GET", "/", nil), true)
37 | }
38 |
39 | func TestHTTPStatusesWrapper(t *testing.T) {
40 | assert := New(t)
41 | mockAssert := New(new(testing.T))
42 |
43 | assert.Equal(mockAssert.HTTPSuccess(httpOK, "GET", "/", nil), true)
44 | assert.Equal(mockAssert.HTTPSuccess(httpRedirect, "GET", "/", nil), false)
45 | assert.Equal(mockAssert.HTTPSuccess(httpError, "GET", "/", nil), false)
46 |
47 | assert.Equal(mockAssert.HTTPRedirect(httpOK, "GET", "/", nil), false)
48 | assert.Equal(mockAssert.HTTPRedirect(httpRedirect, "GET", "/", nil), true)
49 | assert.Equal(mockAssert.HTTPRedirect(httpError, "GET", "/", nil), false)
50 |
51 | assert.Equal(mockAssert.HTTPError(httpOK, "GET", "/", nil), false)
52 | assert.Equal(mockAssert.HTTPError(httpRedirect, "GET", "/", nil), false)
53 | assert.Equal(mockAssert.HTTPError(httpError, "GET", "/", nil), true)
54 | }
55 |
56 | func httpHelloName(w http.ResponseWriter, r *http.Request) {
57 | name := r.FormValue("name")
58 | w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
59 | }
60 |
61 | func TestHttpBody(t *testing.T) {
62 | assert := New(t)
63 | mockT := new(testing.T)
64 |
65 | assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
66 | assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
67 | assert.False(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
68 |
69 | assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
70 | assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
71 | assert.True(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
72 | }
73 |
74 | func TestHttpBodyWrappers(t *testing.T) {
75 | assert := New(t)
76 | mockAssert := New(new(testing.T))
77 |
78 | assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
79 | assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
80 | assert.False(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
81 |
82 | assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
83 | assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
84 | assert.True(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/require/doc.go:
--------------------------------------------------------------------------------
1 | // Alternative testing tools which stop test execution if test failed.
2 | //
3 | // Example Usage
4 | //
5 | // The following is a complete example using require in a standard test function:
6 | // import (
7 | // "testing"
8 | // "github.com/stretchr/testify/require"
9 | // )
10 | //
11 | // func TestSomething(t *testing.T) {
12 | //
13 | // var a string = "Hello"
14 | // var b string = "Hello"
15 | //
16 | // require.Equal(t, a, b, "The two words should be the same.")
17 | //
18 | // }
19 | //
20 | // Assertions
21 | //
22 | // The `require` package have same global functions as in the `assert` package,
23 | // but instead of returning a boolean result they call `t.FailNow()`.
24 | //
25 | // Every assertion function also takes an optional string message as the final argument,
26 | // allowing custom error messages to be appended to the message the assertion method outputs.
27 | //
28 | // Here is an overview of the assert functions:
29 | //
30 | // require.Equal(t, expected, actual [, message [, format-args])
31 | //
32 | // require.NotEqual(t, notExpected, actual [, message [, format-args]])
33 | //
34 | // require.True(t, actualBool [, message [, format-args]])
35 | //
36 | // require.False(t, actualBool [, message [, format-args]])
37 | //
38 | // require.Nil(t, actualObject [, message [, format-args]])
39 | //
40 | // require.NotNil(t, actualObject [, message [, format-args]])
41 | //
42 | // require.Empty(t, actualObject [, message [, format-args]])
43 | //
44 | // require.NotEmpty(t, actualObject [, message [, format-args]])
45 | //
46 | // require.Error(t, errorObject [, message [, format-args]])
47 | //
48 | // require.NoError(t, errorObject [, message [, format-args]])
49 | //
50 | // require.EqualError(t, theError, errString [, message [, format-args]])
51 | //
52 | // require.Implements(t, (*MyInterface)(nil), new(MyObject) [,message [, format-args]])
53 | //
54 | // require.IsType(t, expectedObject, actualObject [, message [, format-args]])
55 | //
56 | // require.Contains(t, string, substring [, message [, format-args]])
57 | //
58 | // require.NotContains(t, string, substring [, message [, format-args]])
59 | //
60 | // require.Panics(t, func(){
61 | //
62 | // // call code that should panic
63 | //
64 | // } [, message [, format-args]])
65 | //
66 | // require.NotPanics(t, func(){
67 | //
68 | // // call code that should not panic
69 | //
70 | // } [, message [, format-args]])
71 | //
72 | // require.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]])
73 | //
74 | // require.InDelta(t, numA, numB, delta, [, message [, format-args]])
75 | //
76 | // require.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]])
77 | package require
78 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/github.com/stretchr/testify/assert"
7 | )
8 |
9 | type Assertions struct {
10 | t TestingT
11 | }
12 |
13 | func New(t TestingT) *Assertions {
14 | return &Assertions{
15 | t: t,
16 | }
17 | }
18 |
19 | // Fail reports a failure through
20 | func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
21 | FailNow(a.t, failureMessage, msgAndArgs...)
22 | }
23 |
24 | // Implements asserts that an object is implemented by the specified interface.
25 |
26 | func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
27 | Implements(a.t, interfaceObject, object, msgAndArgs...)
28 | }
29 |
30 | // IsType asserts that the specified objects are of the same type.
31 | func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
32 | IsType(a.t, expectedType, object, msgAndArgs...)
33 | }
34 |
35 | // Equal asserts that two objects are equal.
36 | //
37 | // require.Equal(123, 123, "123 and 123 should be equal")
38 | func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) {
39 | Equal(a.t, expected, actual, msgAndArgs...)
40 | }
41 |
42 | // Exactly asserts that two objects are equal is value and type.
43 | //
44 | // require.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
45 | func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) {
46 | Exactly(a.t, expected, actual, msgAndArgs...)
47 | }
48 |
49 | // NotNil asserts that the specified object is not nil.
50 | //
51 | // require.NotNil(err, "err should be something")
52 | func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
53 | NotNil(a.t, object, msgAndArgs...)
54 | }
55 |
56 | // Nil asserts that the specified object is nil.
57 | //
58 | // require.Nil(err, "err should be nothing")
59 | func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
60 | Nil(a.t, object, msgAndArgs...)
61 | }
62 |
63 | // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
64 | // slice with len == 0.
65 | //
66 | // require.Empty(obj)
67 | func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
68 | Empty(a.t, object, msgAndArgs...)
69 | }
70 |
71 | // Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
72 | // slice with len == 0.
73 | //
74 | // if require.NotEmpty(obj) {
75 | // require.Equal("two", obj[1])
76 | // }
77 | func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
78 | NotEmpty(a.t, object, msgAndArgs...)
79 | }
80 |
81 | // Len asserts that the specified object has specific length.
82 | // Len also fails if the object has a type that len() not accept.
83 | //
84 | // require.Len(mySlice, 3, "The size of slice is not 3")
85 | func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
86 | Len(a.t, object, length, msgAndArgs...)
87 | }
88 |
89 | // True asserts that the specified value is true.
90 | //
91 | // require.True(myBool, "myBool should be true")
92 | func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
93 | True(a.t, value, msgAndArgs...)
94 | }
95 |
96 | // False asserts that the specified value is true.
97 | //
98 | // require.False(myBool, "myBool should be false")
99 | func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
100 | False(a.t, value, msgAndArgs...)
101 | }
102 |
103 | // NotEqual asserts that the specified values are NOT equal.
104 | //
105 | // require.NotEqual(obj1, obj2, "two objects shouldn't be equal")
106 | func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) {
107 | NotEqual(a.t, expected, actual, msgAndArgs...)
108 | }
109 |
110 | // Contains asserts that the specified string contains the specified substring.
111 | //
112 | // require.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
113 | func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) {
114 | Contains(a.t, s, contains, msgAndArgs...)
115 | }
116 |
117 | // NotContains asserts that the specified string does NOT contain the specified substring.
118 | //
119 | // require.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
120 | func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) {
121 | NotContains(a.t, s, contains, msgAndArgs...)
122 | }
123 |
124 | // Uses a Comparison to assert a complex condition.
125 | func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {
126 | Condition(a.t, comp, msgAndArgs...)
127 | }
128 |
129 | // Panics asserts that the code inside the specified PanicTestFunc panics.
130 | //
131 | // require.Panics(func(){
132 | // GoCrazy()
133 | // }, "Calling GoCrazy() should panic")
134 | func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
135 | Panics(a.t, f, msgAndArgs...)
136 | }
137 |
138 | // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
139 | //
140 | // require.NotPanics(func(){
141 | // RemainCalm()
142 | // }, "Calling RemainCalm() should NOT panic")
143 | func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
144 | NotPanics(a.t, f, msgAndArgs...)
145 | }
146 |
147 | // WithinDuration asserts that the two times are within duration delta of each other.
148 | //
149 | // require.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
150 | func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
151 | WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
152 | }
153 |
154 | // InDelta asserts that the two numerals are within delta of each other.
155 | //
156 | // require.InDelta(t, math.Pi, (22 / 7.0), 0.01)
157 | func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
158 | InDelta(a.t, expected, actual, delta, msgAndArgs...)
159 | }
160 |
161 | // InEpsilon asserts that expected and actual have a relative error less than epsilon
162 | func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
163 | InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
164 | }
165 |
166 | // NoError asserts that a function returned no error (i.e. `nil`).
167 | //
168 | // actualObj, err := SomeFunction()
169 | // if require.NoError(err) {
170 | // require.Equal(actualObj, expectedObj)
171 | // }
172 | func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) {
173 | NoError(a.t, theError, msgAndArgs...)
174 | }
175 |
176 | // Error asserts that a function returned an error (i.e. not `nil`).
177 | //
178 | // actualObj, err := SomeFunction()
179 | // if require.Error(err, "An error was expected") {
180 | // require.Equal(err, expectedError)
181 | // }
182 | func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) {
183 | Error(a.t, theError, msgAndArgs...)
184 | }
185 |
186 | // EqualError asserts that a function returned an error (i.e. not `nil`)
187 | // and that it is equal to the provided error.
188 | //
189 | // actualObj, err := SomeFunction()
190 | // if require.Error(err, "An error was expected") {
191 | // require.Equal(err, expectedError)
192 | // }
193 | func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
194 | EqualError(a.t, theError, errString, msgAndArgs...)
195 | }
196 |
197 | // Regexp asserts that a specified regexp matches a string.
198 | //
199 | // require.Regexp(t, regexp.MustCompile("start"), "it's starting")
200 | // require.Regexp(t, "start...$", "it's not starting")
201 | func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
202 | Regexp(a.t, rx, str, msgAndArgs...)
203 | }
204 |
205 | // NotRegexp asserts that a specified regexp does not match a string.
206 | //
207 | // require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
208 | // require.NotRegexp(t, "^start", "it's not starting")
209 | func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
210 | NotRegexp(a.t, rx, str, msgAndArgs...)
211 | }
212 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements_test.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | import (
4 | "errors"
5 | "testing"
6 | "time"
7 | )
8 |
9 | func TestImplementsWrapper(t *testing.T) {
10 | require := New(t)
11 |
12 | require.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
13 |
14 | mockT := new(MockT)
15 | mockRequire := New(mockT)
16 | mockRequire.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject))
17 | if !mockT.Failed {
18 | t.Error("Check should fail")
19 | }
20 | }
21 |
22 | func TestIsTypeWrapper(t *testing.T) {
23 | require := New(t)
24 | require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
25 |
26 | mockT := new(MockT)
27 | mockRequire := New(mockT)
28 | mockRequire.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject))
29 | if !mockT.Failed {
30 | t.Error("Check should fail")
31 | }
32 | }
33 |
34 | func TestEqualWrapper(t *testing.T) {
35 | require := New(t)
36 | require.Equal(1, 1)
37 |
38 | mockT := new(MockT)
39 | mockRequire := New(mockT)
40 | mockRequire.Equal(1, 2)
41 | if !mockT.Failed {
42 | t.Error("Check should fail")
43 | }
44 | }
45 |
46 | func TestNotEqualWrapper(t *testing.T) {
47 | require := New(t)
48 | require.NotEqual(1, 2)
49 |
50 | mockT := new(MockT)
51 | mockRequire := New(mockT)
52 | mockRequire.NotEqual(2, 2)
53 | if !mockT.Failed {
54 | t.Error("Check should fail")
55 | }
56 | }
57 |
58 | func TestExactlyWrapper(t *testing.T) {
59 | require := New(t)
60 |
61 | a := float32(1)
62 | b := float32(1)
63 | c := float64(1)
64 |
65 | require.Exactly(a, b)
66 |
67 | mockT := new(MockT)
68 | mockRequire := New(mockT)
69 | mockRequire.Exactly(a, c)
70 | if !mockT.Failed {
71 | t.Error("Check should fail")
72 | }
73 | }
74 |
75 | func TestNotNilWrapper(t *testing.T) {
76 | require := New(t)
77 | require.NotNil(t, new(AssertionTesterConformingObject))
78 |
79 | mockT := new(MockT)
80 | mockRequire := New(mockT)
81 | mockRequire.NotNil(nil)
82 | if !mockT.Failed {
83 | t.Error("Check should fail")
84 | }
85 | }
86 |
87 | func TestNilWrapper(t *testing.T) {
88 | require := New(t)
89 | require.Nil(nil)
90 |
91 | mockT := new(MockT)
92 | mockRequire := New(mockT)
93 | mockRequire.Nil(new(AssertionTesterConformingObject))
94 | if !mockT.Failed {
95 | t.Error("Check should fail")
96 | }
97 | }
98 |
99 | func TestTrueWrapper(t *testing.T) {
100 | require := New(t)
101 | require.True(true)
102 |
103 | mockT := new(MockT)
104 | mockRequire := New(mockT)
105 | mockRequire.True(false)
106 | if !mockT.Failed {
107 | t.Error("Check should fail")
108 | }
109 | }
110 |
111 | func TestFalseWrapper(t *testing.T) {
112 | require := New(t)
113 | require.False(false)
114 |
115 | mockT := new(MockT)
116 | mockRequire := New(mockT)
117 | mockRequire.False(true)
118 | if !mockT.Failed {
119 | t.Error("Check should fail")
120 | }
121 | }
122 |
123 | func TestContainsWrapper(t *testing.T) {
124 | require := New(t)
125 | require.Contains("Hello World", "Hello")
126 |
127 | mockT := new(MockT)
128 | mockRequire := New(mockT)
129 | mockRequire.Contains("Hello World", "Salut")
130 | if !mockT.Failed {
131 | t.Error("Check should fail")
132 | }
133 | }
134 |
135 | func TestNotContainsWrapper(t *testing.T) {
136 | require := New(t)
137 | require.NotContains("Hello World", "Hello!")
138 |
139 | mockT := new(MockT)
140 | mockRequire := New(mockT)
141 | mockRequire.NotContains("Hello World", "Hello")
142 | if !mockT.Failed {
143 | t.Error("Check should fail")
144 | }
145 | }
146 |
147 | func TestPanicsWrapper(t *testing.T) {
148 | require := New(t)
149 | require.Panics(func() {
150 | panic("Panic!")
151 | })
152 |
153 | mockT := new(MockT)
154 | mockRequire := New(mockT)
155 | mockRequire.Panics(func() {})
156 | if !mockT.Failed {
157 | t.Error("Check should fail")
158 | }
159 | }
160 |
161 | func TestNotPanicsWrapper(t *testing.T) {
162 | require := New(t)
163 | require.NotPanics(func() {})
164 |
165 | mockT := new(MockT)
166 | mockRequire := New(mockT)
167 | mockRequire.NotPanics(func() {
168 | panic("Panic!")
169 | })
170 | if !mockT.Failed {
171 | t.Error("Check should fail")
172 | }
173 | }
174 |
175 | func TestNoErrorWrapper(t *testing.T) {
176 | require := New(t)
177 | require.NoError(nil)
178 |
179 | mockT := new(MockT)
180 | mockRequire := New(mockT)
181 | mockRequire.NoError(errors.New("some error"))
182 | if !mockT.Failed {
183 | t.Error("Check should fail")
184 | }
185 | }
186 |
187 | func TestErrorWrapper(t *testing.T) {
188 | require := New(t)
189 | require.Error(errors.New("some error"))
190 |
191 | mockT := new(MockT)
192 | mockRequire := New(mockT)
193 | mockRequire.Error(nil)
194 | if !mockT.Failed {
195 | t.Error("Check should fail")
196 | }
197 | }
198 |
199 | func TestEqualErrorWrapper(t *testing.T) {
200 | require := New(t)
201 | require.EqualError(errors.New("some error"), "some error")
202 |
203 | mockT := new(MockT)
204 | mockRequire := New(mockT)
205 | mockRequire.EqualError(errors.New("some error"), "Not some error")
206 | if !mockT.Failed {
207 | t.Error("Check should fail")
208 | }
209 | }
210 |
211 | func TestEmptyWrapper(t *testing.T) {
212 | require := New(t)
213 | require.Empty("")
214 |
215 | mockT := new(MockT)
216 | mockRequire := New(mockT)
217 | mockRequire.Empty("x")
218 | if !mockT.Failed {
219 | t.Error("Check should fail")
220 | }
221 | }
222 |
223 | func TestNotEmptyWrapper(t *testing.T) {
224 | require := New(t)
225 | require.NotEmpty("x")
226 |
227 | mockT := new(MockT)
228 | mockRequire := New(mockT)
229 | mockRequire.NotEmpty("")
230 | if !mockT.Failed {
231 | t.Error("Check should fail")
232 | }
233 | }
234 |
235 | func TestWithinDurationWrapper(t *testing.T) {
236 | require := New(t)
237 | a := time.Now()
238 | b := a.Add(10 * time.Second)
239 |
240 | require.WithinDuration(a, b, 15*time.Second)
241 |
242 | mockT := new(MockT)
243 | mockRequire := New(mockT)
244 | mockRequire.WithinDuration(a, b, 5*time.Second)
245 | if !mockT.Failed {
246 | t.Error("Check should fail")
247 | }
248 | }
249 |
250 | func TestInDeltaWrapper(t *testing.T) {
251 | require := New(t)
252 | require.InDelta(1.001, 1, 0.01)
253 |
254 | mockT := new(MockT)
255 | mockRequire := New(mockT)
256 | mockRequire.InDelta(1, 2, 0.5)
257 | if !mockT.Failed {
258 | t.Error("Check should fail")
259 | }
260 | }
261 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/github.com/stretchr/testify/assert"
7 | )
8 |
9 | type TestingT interface {
10 | Errorf(format string, args ...interface{})
11 | FailNow()
12 | }
13 |
14 | // Fail reports a failure through
15 | func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
16 | assert.Fail(t, failureMessage, msgAndArgs...)
17 | t.FailNow()
18 | }
19 |
20 | // Implements asserts that an object is implemented by the specified interface.
21 | //
22 | // require.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
23 | func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
24 | if !assert.Implements(t, interfaceObject, object, msgAndArgs...) {
25 | t.FailNow()
26 | }
27 | }
28 |
29 | // IsType asserts that the specified objects are of the same type.
30 | func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
31 | if !assert.IsType(t, expectedType, object, msgAndArgs...) {
32 | t.FailNow()
33 | }
34 | }
35 |
36 | // Equal asserts that two objects are equal.
37 | //
38 | // require.Equal(t, 123, 123, "123 and 123 should be equal")
39 | func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
40 | if !assert.Equal(t, expected, actual, msgAndArgs...) {
41 | t.FailNow()
42 | }
43 | }
44 |
45 | // EqualValues asserts that two objects are equal or convertable to each other.
46 | //
47 | // require.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
48 | func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
49 | if !assert.EqualValues(t, expected, actual, msgAndArgs...) {
50 | t.FailNow()
51 | }
52 | }
53 |
54 | // Exactly asserts that two objects are equal is value and type.
55 | //
56 | // require.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
57 | func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
58 | if !assert.Exactly(t, expected, actual, msgAndArgs...) {
59 | t.FailNow()
60 | }
61 | }
62 |
63 | // NotNil asserts that the specified object is not nil.
64 | //
65 | // require.NotNil(t, err, "err should be something")
66 | func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
67 | if !assert.NotNil(t, object, msgAndArgs...) {
68 | t.FailNow()
69 | }
70 | }
71 |
72 | // Nil asserts that the specified object is nil.
73 | //
74 | // require.Nil(t, err, "err should be nothing")
75 | func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
76 | if !assert.Nil(t, object, msgAndArgs...) {
77 | t.FailNow()
78 | }
79 | }
80 |
81 | // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
82 | // a slice or a channel with len == 0.
83 | //
84 | // require.Empty(t, obj)
85 | func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
86 | if !assert.Empty(t, object, msgAndArgs...) {
87 | t.FailNow()
88 | }
89 | }
90 |
91 | // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
92 | // a slice or a channel with len == 0.
93 | //
94 | // require.NotEmpty(t, obj)
95 | // require.Equal(t, "one", obj[0])
96 | func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
97 | if !assert.NotEmpty(t, object, msgAndArgs...) {
98 | t.FailNow()
99 | }
100 | }
101 |
102 | // Len asserts that the specified object has specific length.
103 | // Len also fails if the object has a type that len() not accept.
104 | //
105 | // require.Len(t, mySlice, 3, "The size of slice is not 3")
106 | func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
107 | if !assert.Len(t, object, length, msgAndArgs...) {
108 | t.FailNow()
109 | }
110 | }
111 |
112 | // True asserts that the specified value is true.
113 | //
114 | // require.True(t, myBool, "myBool should be true")
115 | func True(t TestingT, value bool, msgAndArgs ...interface{}) {
116 | if !assert.True(t, value, msgAndArgs...) {
117 | t.FailNow()
118 | }
119 | }
120 |
121 | // False asserts that the specified value is true.
122 | //
123 | // require.False(t, myBool, "myBool should be false")
124 | func False(t TestingT, value bool, msgAndArgs ...interface{}) {
125 | if !assert.False(t, value, msgAndArgs...) {
126 | t.FailNow()
127 | }
128 | }
129 |
130 | // NotEqual asserts that the specified values are NOT equal.
131 | //
132 | // require.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
133 | func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
134 | if !assert.NotEqual(t, expected, actual, msgAndArgs...) {
135 | t.FailNow()
136 | }
137 | }
138 |
139 | // Contains asserts that the specified string contains the specified substring.
140 | //
141 | // require.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
142 | func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) {
143 | if !assert.Contains(t, s, contains, msgAndArgs...) {
144 | t.FailNow()
145 | }
146 | }
147 |
148 | // NotContains asserts that the specified string does NOT contain the specified substring.
149 | //
150 | // require.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
151 | func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) {
152 | if !assert.NotContains(t, s, contains, msgAndArgs...) {
153 | t.FailNow()
154 | }
155 | }
156 |
157 | // Condition uses a Comparison to assert a complex condition.
158 | func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {
159 | if !assert.Condition(t, comp, msgAndArgs...) {
160 | t.FailNow()
161 | }
162 | }
163 |
164 | // Panics asserts that the code inside the specified PanicTestFunc panics.
165 | //
166 | // require.Panics(t, func(){
167 | // GoCrazy()
168 | // }, "Calling GoCrazy() should panic")
169 | func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
170 | if !assert.Panics(t, f, msgAndArgs...) {
171 | t.FailNow()
172 | }
173 | }
174 |
175 | // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
176 | //
177 | // require.NotPanics(t, func(){
178 | // RemainCalm()
179 | // }, "Calling RemainCalm() should NOT panic")
180 | func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
181 | if !assert.NotPanics(t, f, msgAndArgs...) {
182 | t.FailNow()
183 | }
184 | }
185 |
186 | // WithinDuration asserts that the two times are within duration delta of each other.
187 | //
188 | // require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
189 | func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
190 | if !assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
191 | t.FailNow()
192 | }
193 | }
194 |
195 | // InDelta asserts that the two numerals are within delta of each other.
196 | //
197 | // require.InDelta(t, math.Pi, (22 / 7.0), 0.01)
198 | func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
199 | if !assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
200 | t.FailNow()
201 | }
202 | }
203 |
204 | // InEpsilon asserts that expected and actual have a relative error less than epsilon
205 | func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
206 | if !assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
207 | t.FailNow()
208 | }
209 | }
210 |
211 | // Regexp asserts that a specified regexp matches a string.
212 | //
213 | // require.Regexp(t, regexp.MustCompile("start"), "it's starting")
214 | // require.Regexp(t, "start...$", "it's not starting")
215 | func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
216 | if !assert.Regexp(t, rx, str, msgAndArgs...) {
217 | t.FailNow()
218 | }
219 | }
220 |
221 | // NotRegexp asserts that a specified regexp does not match a string.
222 | //
223 | // require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
224 | // require.NotRegexp(t, "^start", "it's not starting")
225 | func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
226 | if !assert.NotRegexp(t, rx, str, msgAndArgs...) {
227 | t.FailNow()
228 | }
229 | }
230 |
231 | /*
232 | Errors
233 | */
234 |
235 | // NoError asserts that a function returned no error (i.e. `nil`).
236 | //
237 | // actualObj, err := SomeFunction()
238 | // require.NoError(t, err)
239 | // require.Equal(t, actualObj, expectedObj)
240 | //
241 | // Returns whether the assertion was successful (true) or not (false).
242 | func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
243 | if !assert.NoError(t, err, msgAndArgs...) {
244 | t.FailNow()
245 | }
246 | }
247 |
248 | // Error asserts that a function returned an error (i.e. not `nil`).
249 | //
250 | // actualObj, err := SomeFunction()
251 | // require.Error(t, err, "An error was expected")
252 | // require.Equal(t, err, expectedError)
253 | // }
254 | func Error(t TestingT, err error, msgAndArgs ...interface{}) {
255 | if !assert.Error(t, err, msgAndArgs...) {
256 | t.FailNow()
257 | }
258 | }
259 |
260 | // EqualError asserts that a function returned an error (i.e. not `nil`)
261 | // and that it is equal to the provided error.
262 | //
263 | // actualObj, err := SomeFunction()
264 | // require.Error(t, err, "An error was expected")
265 | // require.Equal(t, err, expectedError)
266 | // }
267 | func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
268 | if !assert.EqualError(t, theError, errString, msgAndArgs...) {
269 | t.FailNow()
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements_test.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | import (
4 | "errors"
5 | "testing"
6 | "time"
7 | )
8 |
9 | // AssertionTesterInterface defines an interface to be used for testing assertion methods
10 | type AssertionTesterInterface interface {
11 | TestMethod()
12 | }
13 |
14 | // AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface
15 | type AssertionTesterConformingObject struct {
16 | }
17 |
18 | func (a *AssertionTesterConformingObject) TestMethod() {
19 | }
20 |
21 | // AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface
22 | type AssertionTesterNonConformingObject struct {
23 | }
24 |
25 | type MockT struct {
26 | Failed bool
27 | }
28 |
29 | func (t *MockT) FailNow() {
30 | t.Failed = true
31 | }
32 |
33 | func (t *MockT) Errorf(format string, args ...interface{}) {
34 | _, _ = format, args
35 | }
36 |
37 | func TestImplements(t *testing.T) {
38 |
39 | Implements(t, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
40 |
41 | mockT := new(MockT)
42 | Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject))
43 | if !mockT.Failed {
44 | t.Error("Check should fail")
45 | }
46 | }
47 |
48 | func TestIsType(t *testing.T) {
49 |
50 | IsType(t, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
51 |
52 | mockT := new(MockT)
53 | IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject))
54 | if !mockT.Failed {
55 | t.Error("Check should fail")
56 | }
57 | }
58 |
59 | func TestEqual(t *testing.T) {
60 |
61 | Equal(t, 1, 1)
62 |
63 | mockT := new(MockT)
64 | Equal(mockT, 1, 2)
65 | if !mockT.Failed {
66 | t.Error("Check should fail")
67 | }
68 |
69 | }
70 |
71 | func TestNotEqual(t *testing.T) {
72 |
73 | NotEqual(t, 1, 2)
74 | mockT := new(MockT)
75 | NotEqual(mockT, 2, 2)
76 | if !mockT.Failed {
77 | t.Error("Check should fail")
78 | }
79 | }
80 |
81 | func TestExactly(t *testing.T) {
82 |
83 | a := float32(1)
84 | b := float32(1)
85 | c := float64(1)
86 |
87 | Exactly(t, a, b)
88 |
89 | mockT := new(MockT)
90 | Exactly(mockT, a, c)
91 | if !mockT.Failed {
92 | t.Error("Check should fail")
93 | }
94 | }
95 |
96 | func TestNotNil(t *testing.T) {
97 |
98 | NotNil(t, new(AssertionTesterConformingObject))
99 |
100 | mockT := new(MockT)
101 | NotNil(mockT, nil)
102 | if !mockT.Failed {
103 | t.Error("Check should fail")
104 | }
105 | }
106 |
107 | func TestNil(t *testing.T) {
108 |
109 | Nil(t, nil)
110 |
111 | mockT := new(MockT)
112 | Nil(mockT, new(AssertionTesterConformingObject))
113 | if !mockT.Failed {
114 | t.Error("Check should fail")
115 | }
116 | }
117 |
118 | func TestTrue(t *testing.T) {
119 |
120 | True(t, true)
121 |
122 | mockT := new(MockT)
123 | True(mockT, false)
124 | if !mockT.Failed {
125 | t.Error("Check should fail")
126 | }
127 | }
128 |
129 | func TestFalse(t *testing.T) {
130 |
131 | False(t, false)
132 |
133 | mockT := new(MockT)
134 | False(mockT, true)
135 | if !mockT.Failed {
136 | t.Error("Check should fail")
137 | }
138 | }
139 |
140 | func TestContains(t *testing.T) {
141 |
142 | Contains(t, "Hello World", "Hello")
143 |
144 | mockT := new(MockT)
145 | Contains(mockT, "Hello World", "Salut")
146 | if !mockT.Failed {
147 | t.Error("Check should fail")
148 | }
149 | }
150 |
151 | func TestNotContains(t *testing.T) {
152 |
153 | NotContains(t, "Hello World", "Hello!")
154 |
155 | mockT := new(MockT)
156 | NotContains(mockT, "Hello World", "Hello")
157 | if !mockT.Failed {
158 | t.Error("Check should fail")
159 | }
160 | }
161 |
162 | func TestPanics(t *testing.T) {
163 |
164 | Panics(t, func() {
165 | panic("Panic!")
166 | })
167 |
168 | mockT := new(MockT)
169 | Panics(mockT, func() {})
170 | if !mockT.Failed {
171 | t.Error("Check should fail")
172 | }
173 | }
174 |
175 | func TestNotPanics(t *testing.T) {
176 |
177 | NotPanics(t, func() {})
178 |
179 | mockT := new(MockT)
180 | NotPanics(mockT, func() {
181 | panic("Panic!")
182 | })
183 | if !mockT.Failed {
184 | t.Error("Check should fail")
185 | }
186 | }
187 |
188 | func TestNoError(t *testing.T) {
189 |
190 | NoError(t, nil)
191 |
192 | mockT := new(MockT)
193 | NoError(mockT, errors.New("some error"))
194 | if !mockT.Failed {
195 | t.Error("Check should fail")
196 | }
197 | }
198 |
199 | func TestError(t *testing.T) {
200 |
201 | Error(t, errors.New("some error"))
202 |
203 | mockT := new(MockT)
204 | Error(mockT, nil)
205 | if !mockT.Failed {
206 | t.Error("Check should fail")
207 | }
208 | }
209 |
210 | func TestEqualError(t *testing.T) {
211 |
212 | EqualError(t, errors.New("some error"), "some error")
213 |
214 | mockT := new(MockT)
215 | EqualError(mockT, errors.New("some error"), "Not some error")
216 | if !mockT.Failed {
217 | t.Error("Check should fail")
218 | }
219 | }
220 |
221 | func TestEmpty(t *testing.T) {
222 |
223 | Empty(t, "")
224 |
225 | mockT := new(MockT)
226 | Empty(mockT, "x")
227 | if !mockT.Failed {
228 | t.Error("Check should fail")
229 | }
230 | }
231 |
232 | func TestNotEmpty(t *testing.T) {
233 |
234 | NotEmpty(t, "x")
235 |
236 | mockT := new(MockT)
237 | NotEmpty(mockT, "")
238 | if !mockT.Failed {
239 | t.Error("Check should fail")
240 | }
241 | }
242 |
243 | func TestWithinDuration(t *testing.T) {
244 |
245 | a := time.Now()
246 | b := a.Add(10 * time.Second)
247 |
248 | WithinDuration(t, a, b, 15*time.Second)
249 |
250 | mockT := new(MockT)
251 | WithinDuration(mockT, a, b, 5*time.Second)
252 | if !mockT.Failed {
253 | t.Error("Check should fail")
254 | }
255 | }
256 |
257 | func TestInDelta(t *testing.T) {
258 |
259 | InDelta(t, 1.001, 1, 0.01)
260 |
261 | mockT := new(MockT)
262 | InDelta(mockT, 1, 2, 0.5)
263 | if !mockT.Failed {
264 | t.Error("Check should fail")
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) 2011-2014 - Canonical Inc.
3 |
4 | This software is licensed under the LGPLv3, included below.
5 |
6 | As a special exception to the GNU Lesser General Public License version 3
7 | ("LGPL3"), the copyright holders of this Library give you permission to
8 | convey to a third party a Combined Work that links statically or dynamically
9 | to this Library without providing any Minimal Corresponding Source or
10 | Minimal Application Code as set out in 4d or providing the installation
11 | information set out in section 4e, provided that you comply with the other
12 | provisions of LGPL3 and provided that you meet, for the Application the
13 | terms and conditions of the license(s) which apply to the Application.
14 |
15 | Except as stated in this special exception, the provisions of LGPL3 will
16 | continue to comply in full to this Library. If you modify this Library, you
17 | may apply this exception to your version of this Library, but you are not
18 | obliged to do so. If you do not wish to do so, delete this exception
19 | statement from your version. This exception does not (and cannot) modify any
20 | license terms which apply to the Application, with which you must still
21 | comply.
22 |
23 |
24 | GNU LESSER GENERAL PUBLIC LICENSE
25 | Version 3, 29 June 2007
26 |
27 | Copyright (C) 2007 Free Software Foundation, Inc.
28 | Everyone is permitted to copy and distribute verbatim copies
29 | of this license document, but changing it is not allowed.
30 |
31 |
32 | This version of the GNU Lesser General Public License incorporates
33 | the terms and conditions of version 3 of the GNU General Public
34 | License, supplemented by the additional permissions listed below.
35 |
36 | 0. Additional Definitions.
37 |
38 | As used herein, "this License" refers to version 3 of the GNU Lesser
39 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
40 | General Public License.
41 |
42 | "The Library" refers to a covered work governed by this License,
43 | other than an Application or a Combined Work as defined below.
44 |
45 | An "Application" is any work that makes use of an interface provided
46 | by the Library, but which is not otherwise based on the Library.
47 | Defining a subclass of a class defined by the Library is deemed a mode
48 | of using an interface provided by the Library.
49 |
50 | A "Combined Work" is a work produced by combining or linking an
51 | Application with the Library. The particular version of the Library
52 | with which the Combined Work was made is also called the "Linked
53 | Version".
54 |
55 | The "Minimal Corresponding Source" for a Combined Work means the
56 | Corresponding Source for the Combined Work, excluding any source code
57 | for portions of the Combined Work that, considered in isolation, are
58 | based on the Application, and not on the Linked Version.
59 |
60 | The "Corresponding Application Code" for a Combined Work means the
61 | object code and/or source code for the Application, including any data
62 | and utility programs needed for reproducing the Combined Work from the
63 | Application, but excluding the System Libraries of the Combined Work.
64 |
65 | 1. Exception to Section 3 of the GNU GPL.
66 |
67 | You may convey a covered work under sections 3 and 4 of this License
68 | without being bound by section 3 of the GNU GPL.
69 |
70 | 2. Conveying Modified Versions.
71 |
72 | If you modify a copy of the Library, and, in your modifications, a
73 | facility refers to a function or data to be supplied by an Application
74 | that uses the facility (other than as an argument passed when the
75 | facility is invoked), then you may convey a copy of the modified
76 | version:
77 |
78 | a) under this License, provided that you make a good faith effort to
79 | ensure that, in the event an Application does not supply the
80 | function or data, the facility still operates, and performs
81 | whatever part of its purpose remains meaningful, or
82 |
83 | b) under the GNU GPL, with none of the additional permissions of
84 | this License applicable to that copy.
85 |
86 | 3. Object Code Incorporating Material from Library Header Files.
87 |
88 | The object code form of an Application may incorporate material from
89 | a header file that is part of the Library. You may convey such object
90 | code under terms of your choice, provided that, if the incorporated
91 | material is not limited to numerical parameters, data structure
92 | layouts and accessors, or small macros, inline functions and templates
93 | (ten or fewer lines in length), you do both of the following:
94 |
95 | a) Give prominent notice with each copy of the object code that the
96 | Library is used in it and that the Library and its use are
97 | covered by this License.
98 |
99 | b) Accompany the object code with a copy of the GNU GPL and this license
100 | document.
101 |
102 | 4. Combined Works.
103 |
104 | You may convey a Combined Work under terms of your choice that,
105 | taken together, effectively do not restrict modification of the
106 | portions of the Library contained in the Combined Work and reverse
107 | engineering for debugging such modifications, if you also do each of
108 | the following:
109 |
110 | a) Give prominent notice with each copy of the Combined Work that
111 | the Library is used in it and that the Library and its use are
112 | covered by this License.
113 |
114 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
115 | document.
116 |
117 | c) For a Combined Work that displays copyright notices during
118 | execution, include the copyright notice for the Library among
119 | these notices, as well as a reference directing the user to the
120 | copies of the GNU GPL and this license document.
121 |
122 | d) Do one of the following:
123 |
124 | 0) Convey the Minimal Corresponding Source under the terms of this
125 | License, and the Corresponding Application Code in a form
126 | suitable for, and under terms that permit, the user to
127 | recombine or relink the Application with a modified version of
128 | the Linked Version to produce a modified Combined Work, in the
129 | manner specified by section 6 of the GNU GPL for conveying
130 | Corresponding Source.
131 |
132 | 1) Use a suitable shared library mechanism for linking with the
133 | Library. A suitable mechanism is one that (a) uses at run time
134 | a copy of the Library already present on the user's computer
135 | system, and (b) will operate properly with a modified version
136 | of the Library that is interface-compatible with the Linked
137 | Version.
138 |
139 | e) Provide Installation Information, but only if you would otherwise
140 | be required to provide such information under section 6 of the
141 | GNU GPL, and only to the extent that such information is
142 | necessary to install and execute a modified version of the
143 | Combined Work produced by recombining or relinking the
144 | Application with a modified version of the Linked Version. (If
145 | you use option 4d0, the Installation Information must accompany
146 | the Minimal Corresponding Source and Corresponding Application
147 | Code. If you use option 4d1, you must provide the Installation
148 | Information in the manner specified by section 6 of the GNU GPL
149 | for conveying Corresponding Source.)
150 |
151 | 5. Combined Libraries.
152 |
153 | You may place library facilities that are a work based on the
154 | Library side by side in a single library together with other library
155 | facilities that are not Applications and are not covered by this
156 | License, and convey such a combined library under terms of your
157 | choice, if you do both of the following:
158 |
159 | a) Accompany the combined library with a copy of the same work based
160 | on the Library, uncombined with any other library facilities,
161 | conveyed under the terms of this License.
162 |
163 | b) Give prominent notice with the combined library that part of it
164 | is a work based on the Library, and explaining where to find the
165 | accompanying uncombined form of the same work.
166 |
167 | 6. Revised Versions of the GNU Lesser General Public License.
168 |
169 | The Free Software Foundation may publish revised and/or new versions
170 | of the GNU Lesser General Public License from time to time. Such new
171 | versions will be similar in spirit to the present version, but may
172 | differ in detail to address new problems or concerns.
173 |
174 | Each version is given a distinguishing version number. If the
175 | Library as you received it specifies that a certain numbered version
176 | of the GNU Lesser General Public License "or any later version"
177 | applies to it, you have the option of following the terms and
178 | conditions either of that published version or of any later version
179 | published by the Free Software Foundation. If the Library as you
180 | received it does not specify a version number of the GNU Lesser
181 | General Public License, you may choose any version of the GNU Lesser
182 | General Public License ever published by the Free Software Foundation.
183 |
184 | If the Library as you received it specifies that a proxy can decide
185 | whether future versions of the GNU Lesser General Public License shall
186 | apply, that proxy's public statement of acceptance of any version is
187 | permanent authorization for you to choose that version for the
188 | Library.
189 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml:
--------------------------------------------------------------------------------
1 | The following files were ported to Go from C files of libyaml, and thus
2 | are still covered by their original copyright and license:
3 |
4 | apic.go
5 | emitterc.go
6 | parserc.go
7 | readerc.go
8 | scannerc.go
9 | writerc.go
10 | yamlh.go
11 | yamlprivateh.go
12 |
13 | Copyright (c) 2006 Kirill Simonov
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy of
16 | this software and associated documentation files (the "Software"), to deal in
17 | the Software without restriction, including without limitation the rights to
18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
19 | of the Software, and to permit persons to whom the Software is furnished to do
20 | so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/README.md:
--------------------------------------------------------------------------------
1 | # YAML support for the Go language
2 |
3 | Introduction
4 | ------------
5 |
6 | The yaml package enables Go programs to comfortably encode and decode YAML
7 | values. It was developed within [Canonical](https://www.canonical.com) as
8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a
9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
10 | C library to parse and generate YAML data quickly and reliably.
11 |
12 | Compatibility
13 | -------------
14 |
15 | The yaml package supports most of YAML 1.1 and 1.2, including support for
16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
17 | implemented, and base-60 floats from YAML 1.1 are purposefully not
18 | supported since they're a poor design and are gone in YAML 1.2.
19 |
20 | Installation and usage
21 | ----------------------
22 |
23 | The import path for the package is *gopkg.in/yaml.v2*.
24 |
25 | To install it, run:
26 |
27 | go get gopkg.in/yaml.v2
28 |
29 | API documentation
30 | -----------------
31 |
32 | If opened in a browser, the import path itself leads to the API documentation:
33 |
34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
35 |
36 | API stability
37 | -------------
38 |
39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
40 |
41 |
42 | License
43 | -------
44 |
45 | The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
46 |
47 |
48 | Example
49 | -------
50 |
51 | ```Go
52 | package main
53 |
54 | import (
55 | "fmt"
56 | "log"
57 |
58 | "gopkg.in/yaml.v2"
59 | )
60 |
61 | var data = `
62 | a: Easy!
63 | b:
64 | c: 2
65 | d: [3, 4]
66 | `
67 |
68 | type T struct {
69 | A string
70 | B struct{C int; D []int ",flow"}
71 | }
72 |
73 | func main() {
74 | t := T{}
75 |
76 | err := yaml.Unmarshal([]byte(data), &t)
77 | if err != nil {
78 | log.Fatalf("error: %v", err)
79 | }
80 | fmt.Printf("--- t:\n%v\n\n", t)
81 |
82 | d, err := yaml.Marshal(&t)
83 | if err != nil {
84 | log.Fatalf("error: %v", err)
85 | }
86 | fmt.Printf("--- t dump:\n%s\n\n", string(d))
87 |
88 | m := make(map[interface{}]interface{})
89 |
90 | err = yaml.Unmarshal([]byte(data), &m)
91 | if err != nil {
92 | log.Fatalf("error: %v", err)
93 | }
94 | fmt.Printf("--- m:\n%v\n\n", m)
95 |
96 | d, err = yaml.Marshal(&m)
97 | if err != nil {
98 | log.Fatalf("error: %v", err)
99 | }
100 | fmt.Printf("--- m dump:\n%s\n\n", string(d))
101 | }
102 | ```
103 |
104 | This example will generate the following output:
105 |
106 | ```
107 | --- t:
108 | {Easy! {2 [3 4]}}
109 |
110 | --- t dump:
111 | a: Easy!
112 | b:
113 | c: 2
114 | d: [3, 4]
115 |
116 |
117 | --- m:
118 | map[a:Easy! b:map[c:2 d:[3 4]]]
119 |
120 | --- m dump:
121 | a: Easy!
122 | b:
123 | c: 2
124 | d:
125 | - 3
126 | - 4
127 | ```
128 |
129 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding"
5 | "encoding/base64"
6 | "fmt"
7 | "math"
8 | "reflect"
9 | "strconv"
10 | "time"
11 | )
12 |
13 | const (
14 | documentNode = 1 << iota
15 | mappingNode
16 | sequenceNode
17 | scalarNode
18 | aliasNode
19 | )
20 |
21 | type node struct {
22 | kind int
23 | line, column int
24 | tag string
25 | value string
26 | implicit bool
27 | children []*node
28 | anchors map[string]*node
29 | }
30 |
31 | // ----------------------------------------------------------------------------
32 | // Parser, produces a node tree out of a libyaml event stream.
33 |
34 | type parser struct {
35 | parser yaml_parser_t
36 | event yaml_event_t
37 | doc *node
38 | }
39 |
40 | func newParser(b []byte) *parser {
41 | p := parser{}
42 | if !yaml_parser_initialize(&p.parser) {
43 | panic("failed to initialize YAML emitter")
44 | }
45 |
46 | if len(b) == 0 {
47 | b = []byte{'\n'}
48 | }
49 |
50 | yaml_parser_set_input_string(&p.parser, b)
51 |
52 | p.skip()
53 | if p.event.typ != yaml_STREAM_START_EVENT {
54 | panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
55 | }
56 | p.skip()
57 | return &p
58 | }
59 |
60 | func (p *parser) destroy() {
61 | if p.event.typ != yaml_NO_EVENT {
62 | yaml_event_delete(&p.event)
63 | }
64 | yaml_parser_delete(&p.parser)
65 | }
66 |
67 | func (p *parser) skip() {
68 | if p.event.typ != yaml_NO_EVENT {
69 | if p.event.typ == yaml_STREAM_END_EVENT {
70 | failf("attempted to go past the end of stream; corrupted value?")
71 | }
72 | yaml_event_delete(&p.event)
73 | }
74 | if !yaml_parser_parse(&p.parser, &p.event) {
75 | p.fail()
76 | }
77 | }
78 |
79 | func (p *parser) fail() {
80 | var where string
81 | var line int
82 | if p.parser.problem_mark.line != 0 {
83 | line = p.parser.problem_mark.line
84 | } else if p.parser.context_mark.line != 0 {
85 | line = p.parser.context_mark.line
86 | }
87 | if line != 0 {
88 | where = "line " + strconv.Itoa(line) + ": "
89 | }
90 | var msg string
91 | if len(p.parser.problem) > 0 {
92 | msg = p.parser.problem
93 | } else {
94 | msg = "unknown problem parsing YAML content"
95 | }
96 | failf("%s%s", where, msg)
97 | }
98 |
99 | func (p *parser) anchor(n *node, anchor []byte) {
100 | if anchor != nil {
101 | p.doc.anchors[string(anchor)] = n
102 | }
103 | }
104 |
105 | func (p *parser) parse() *node {
106 | switch p.event.typ {
107 | case yaml_SCALAR_EVENT:
108 | return p.scalar()
109 | case yaml_ALIAS_EVENT:
110 | return p.alias()
111 | case yaml_MAPPING_START_EVENT:
112 | return p.mapping()
113 | case yaml_SEQUENCE_START_EVENT:
114 | return p.sequence()
115 | case yaml_DOCUMENT_START_EVENT:
116 | return p.document()
117 | case yaml_STREAM_END_EVENT:
118 | // Happens when attempting to decode an empty buffer.
119 | return nil
120 | default:
121 | panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
122 | }
123 | panic("unreachable")
124 | }
125 |
126 | func (p *parser) node(kind int) *node {
127 | return &node{
128 | kind: kind,
129 | line: p.event.start_mark.line,
130 | column: p.event.start_mark.column,
131 | }
132 | }
133 |
134 | func (p *parser) document() *node {
135 | n := p.node(documentNode)
136 | n.anchors = make(map[string]*node)
137 | p.doc = n
138 | p.skip()
139 | n.children = append(n.children, p.parse())
140 | if p.event.typ != yaml_DOCUMENT_END_EVENT {
141 | panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
142 | }
143 | p.skip()
144 | return n
145 | }
146 |
147 | func (p *parser) alias() *node {
148 | n := p.node(aliasNode)
149 | n.value = string(p.event.anchor)
150 | p.skip()
151 | return n
152 | }
153 |
154 | func (p *parser) scalar() *node {
155 | n := p.node(scalarNode)
156 | n.value = string(p.event.value)
157 | n.tag = string(p.event.tag)
158 | n.implicit = p.event.implicit
159 | p.anchor(n, p.event.anchor)
160 | p.skip()
161 | return n
162 | }
163 |
164 | func (p *parser) sequence() *node {
165 | n := p.node(sequenceNode)
166 | p.anchor(n, p.event.anchor)
167 | p.skip()
168 | for p.event.typ != yaml_SEQUENCE_END_EVENT {
169 | n.children = append(n.children, p.parse())
170 | }
171 | p.skip()
172 | return n
173 | }
174 |
175 | func (p *parser) mapping() *node {
176 | n := p.node(mappingNode)
177 | p.anchor(n, p.event.anchor)
178 | p.skip()
179 | for p.event.typ != yaml_MAPPING_END_EVENT {
180 | n.children = append(n.children, p.parse(), p.parse())
181 | }
182 | p.skip()
183 | return n
184 | }
185 |
186 | // ----------------------------------------------------------------------------
187 | // Decoder, unmarshals a node into a provided value.
188 |
189 | type decoder struct {
190 | doc *node
191 | aliases map[string]bool
192 | mapType reflect.Type
193 | terrors []string
194 | }
195 |
196 | var (
197 | mapItemType = reflect.TypeOf(MapItem{})
198 | durationType = reflect.TypeOf(time.Duration(0))
199 | defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
200 | ifaceType = defaultMapType.Elem()
201 | )
202 |
203 | func newDecoder() *decoder {
204 | d := &decoder{mapType: defaultMapType}
205 | d.aliases = make(map[string]bool)
206 | return d
207 | }
208 |
209 | func (d *decoder) terror(n *node, tag string, out reflect.Value) {
210 | if n.tag != "" {
211 | tag = n.tag
212 | }
213 | value := n.value
214 | if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
215 | if len(value) > 10 {
216 | value = " `" + value[:7] + "...`"
217 | } else {
218 | value = " `" + value + "`"
219 | }
220 | }
221 | d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
222 | }
223 |
224 | func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
225 | terrlen := len(d.terrors)
226 | err := u.UnmarshalYAML(func(v interface{}) (err error) {
227 | defer handleErr(&err)
228 | d.unmarshal(n, reflect.ValueOf(v))
229 | if len(d.terrors) > terrlen {
230 | issues := d.terrors[terrlen:]
231 | d.terrors = d.terrors[:terrlen]
232 | return &TypeError{issues}
233 | }
234 | return nil
235 | })
236 | if e, ok := err.(*TypeError); ok {
237 | d.terrors = append(d.terrors, e.Errors...)
238 | return false
239 | }
240 | if err != nil {
241 | fail(err)
242 | }
243 | return true
244 | }
245 |
246 | // d.prepare initializes and dereferences pointers and calls UnmarshalYAML
247 | // if a value is found to implement it.
248 | // It returns the initialized and dereferenced out value, whether
249 | // unmarshalling was already done by UnmarshalYAML, and if so whether
250 | // its types unmarshalled appropriately.
251 | //
252 | // If n holds a null value, prepare returns before doing anything.
253 | func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
254 | if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
255 | return out, false, false
256 | }
257 | again := true
258 | for again {
259 | again = false
260 | if out.Kind() == reflect.Ptr {
261 | if out.IsNil() {
262 | out.Set(reflect.New(out.Type().Elem()))
263 | }
264 | out = out.Elem()
265 | again = true
266 | }
267 | if out.CanAddr() {
268 | if u, ok := out.Addr().Interface().(Unmarshaler); ok {
269 | good = d.callUnmarshaler(n, u)
270 | return out, true, good
271 | }
272 | }
273 | }
274 | return out, false, false
275 | }
276 |
277 | func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
278 | switch n.kind {
279 | case documentNode:
280 | return d.document(n, out)
281 | case aliasNode:
282 | return d.alias(n, out)
283 | }
284 | out, unmarshaled, good := d.prepare(n, out)
285 | if unmarshaled {
286 | return good
287 | }
288 | switch n.kind {
289 | case scalarNode:
290 | good = d.scalar(n, out)
291 | case mappingNode:
292 | good = d.mapping(n, out)
293 | case sequenceNode:
294 | good = d.sequence(n, out)
295 | default:
296 | panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
297 | }
298 | return good
299 | }
300 |
301 | func (d *decoder) document(n *node, out reflect.Value) (good bool) {
302 | if len(n.children) == 1 {
303 | d.doc = n
304 | d.unmarshal(n.children[0], out)
305 | return true
306 | }
307 | return false
308 | }
309 |
310 | func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
311 | an, ok := d.doc.anchors[n.value]
312 | if !ok {
313 | failf("unknown anchor '%s' referenced", n.value)
314 | }
315 | if d.aliases[n.value] {
316 | failf("anchor '%s' value contains itself", n.value)
317 | }
318 | d.aliases[n.value] = true
319 | good = d.unmarshal(an, out)
320 | delete(d.aliases, n.value)
321 | return good
322 | }
323 |
324 | var zeroValue reflect.Value
325 |
326 | func resetMap(out reflect.Value) {
327 | for _, k := range out.MapKeys() {
328 | out.SetMapIndex(k, zeroValue)
329 | }
330 | }
331 |
332 | func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
333 | var tag string
334 | var resolved interface{}
335 | if n.tag == "" && !n.implicit {
336 | tag = yaml_STR_TAG
337 | resolved = n.value
338 | } else {
339 | tag, resolved = resolve(n.tag, n.value)
340 | if tag == yaml_BINARY_TAG {
341 | data, err := base64.StdEncoding.DecodeString(resolved.(string))
342 | if err != nil {
343 | failf("!!binary value contains invalid base64 data")
344 | }
345 | resolved = string(data)
346 | }
347 | }
348 | if resolved == nil {
349 | if out.Kind() == reflect.Map && !out.CanAddr() {
350 | resetMap(out)
351 | } else {
352 | out.Set(reflect.Zero(out.Type()))
353 | }
354 | return true
355 | }
356 | if s, ok := resolved.(string); ok && out.CanAddr() {
357 | if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
358 | err := u.UnmarshalText([]byte(s))
359 | if err != nil {
360 | fail(err)
361 | }
362 | return true
363 | }
364 | }
365 | switch out.Kind() {
366 | case reflect.String:
367 | if tag == yaml_BINARY_TAG {
368 | out.SetString(resolved.(string))
369 | good = true
370 | } else if resolved != nil {
371 | out.SetString(n.value)
372 | good = true
373 | }
374 | case reflect.Interface:
375 | if resolved == nil {
376 | out.Set(reflect.Zero(out.Type()))
377 | } else {
378 | out.Set(reflect.ValueOf(resolved))
379 | }
380 | good = true
381 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
382 | switch resolved := resolved.(type) {
383 | case int:
384 | if !out.OverflowInt(int64(resolved)) {
385 | out.SetInt(int64(resolved))
386 | good = true
387 | }
388 | case int64:
389 | if !out.OverflowInt(resolved) {
390 | out.SetInt(resolved)
391 | good = true
392 | }
393 | case uint64:
394 | if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
395 | out.SetInt(int64(resolved))
396 | good = true
397 | }
398 | case float64:
399 | if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
400 | out.SetInt(int64(resolved))
401 | good = true
402 | }
403 | case string:
404 | if out.Type() == durationType {
405 | d, err := time.ParseDuration(resolved)
406 | if err == nil {
407 | out.SetInt(int64(d))
408 | good = true
409 | }
410 | }
411 | }
412 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
413 | switch resolved := resolved.(type) {
414 | case int:
415 | if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
416 | out.SetUint(uint64(resolved))
417 | good = true
418 | }
419 | case int64:
420 | if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
421 | out.SetUint(uint64(resolved))
422 | good = true
423 | }
424 | case uint64:
425 | if !out.OverflowUint(uint64(resolved)) {
426 | out.SetUint(uint64(resolved))
427 | good = true
428 | }
429 | case float64:
430 | if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
431 | out.SetUint(uint64(resolved))
432 | good = true
433 | }
434 | }
435 | case reflect.Bool:
436 | switch resolved := resolved.(type) {
437 | case bool:
438 | out.SetBool(resolved)
439 | good = true
440 | }
441 | case reflect.Float32, reflect.Float64:
442 | switch resolved := resolved.(type) {
443 | case int:
444 | out.SetFloat(float64(resolved))
445 | good = true
446 | case int64:
447 | out.SetFloat(float64(resolved))
448 | good = true
449 | case uint64:
450 | out.SetFloat(float64(resolved))
451 | good = true
452 | case float64:
453 | out.SetFloat(resolved)
454 | good = true
455 | }
456 | case reflect.Ptr:
457 | if out.Type().Elem() == reflect.TypeOf(resolved) {
458 | // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
459 | elem := reflect.New(out.Type().Elem())
460 | elem.Elem().Set(reflect.ValueOf(resolved))
461 | out.Set(elem)
462 | good = true
463 | }
464 | }
465 | if !good {
466 | d.terror(n, tag, out)
467 | }
468 | return good
469 | }
470 |
471 | func settableValueOf(i interface{}) reflect.Value {
472 | v := reflect.ValueOf(i)
473 | sv := reflect.New(v.Type()).Elem()
474 | sv.Set(v)
475 | return sv
476 | }
477 |
478 | func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
479 | l := len(n.children)
480 |
481 | var iface reflect.Value
482 | switch out.Kind() {
483 | case reflect.Slice:
484 | out.Set(reflect.MakeSlice(out.Type(), l, l))
485 | case reflect.Interface:
486 | // No type hints. Will have to use a generic sequence.
487 | iface = out
488 | out = settableValueOf(make([]interface{}, l))
489 | default:
490 | d.terror(n, yaml_SEQ_TAG, out)
491 | return false
492 | }
493 | et := out.Type().Elem()
494 |
495 | j := 0
496 | for i := 0; i < l; i++ {
497 | e := reflect.New(et).Elem()
498 | if ok := d.unmarshal(n.children[i], e); ok {
499 | out.Index(j).Set(e)
500 | j++
501 | }
502 | }
503 | out.Set(out.Slice(0, j))
504 | if iface.IsValid() {
505 | iface.Set(out)
506 | }
507 | return true
508 | }
509 |
510 | func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
511 | switch out.Kind() {
512 | case reflect.Struct:
513 | return d.mappingStruct(n, out)
514 | case reflect.Slice:
515 | return d.mappingSlice(n, out)
516 | case reflect.Map:
517 | // okay
518 | case reflect.Interface:
519 | if d.mapType.Kind() == reflect.Map {
520 | iface := out
521 | out = reflect.MakeMap(d.mapType)
522 | iface.Set(out)
523 | } else {
524 | slicev := reflect.New(d.mapType).Elem()
525 | if !d.mappingSlice(n, slicev) {
526 | return false
527 | }
528 | out.Set(slicev)
529 | return true
530 | }
531 | default:
532 | d.terror(n, yaml_MAP_TAG, out)
533 | return false
534 | }
535 | outt := out.Type()
536 | kt := outt.Key()
537 | et := outt.Elem()
538 |
539 | mapType := d.mapType
540 | if outt.Key() == ifaceType && outt.Elem() == ifaceType {
541 | d.mapType = outt
542 | }
543 |
544 | if out.IsNil() {
545 | out.Set(reflect.MakeMap(outt))
546 | }
547 | l := len(n.children)
548 | for i := 0; i < l; i += 2 {
549 | if isMerge(n.children[i]) {
550 | d.merge(n.children[i+1], out)
551 | continue
552 | }
553 | k := reflect.New(kt).Elem()
554 | if d.unmarshal(n.children[i], k) {
555 | kkind := k.Kind()
556 | if kkind == reflect.Interface {
557 | kkind = k.Elem().Kind()
558 | }
559 | if kkind == reflect.Map || kkind == reflect.Slice {
560 | failf("invalid map key: %#v", k.Interface())
561 | }
562 | e := reflect.New(et).Elem()
563 | if d.unmarshal(n.children[i+1], e) {
564 | out.SetMapIndex(k, e)
565 | }
566 | }
567 | }
568 | d.mapType = mapType
569 | return true
570 | }
571 |
572 | func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
573 | outt := out.Type()
574 | if outt.Elem() != mapItemType {
575 | d.terror(n, yaml_MAP_TAG, out)
576 | return false
577 | }
578 |
579 | mapType := d.mapType
580 | d.mapType = outt
581 |
582 | var slice []MapItem
583 | var l = len(n.children)
584 | for i := 0; i < l; i += 2 {
585 | if isMerge(n.children[i]) {
586 | d.merge(n.children[i+1], out)
587 | continue
588 | }
589 | item := MapItem{}
590 | k := reflect.ValueOf(&item.Key).Elem()
591 | if d.unmarshal(n.children[i], k) {
592 | v := reflect.ValueOf(&item.Value).Elem()
593 | if d.unmarshal(n.children[i+1], v) {
594 | slice = append(slice, item)
595 | }
596 | }
597 | }
598 | out.Set(reflect.ValueOf(slice))
599 | d.mapType = mapType
600 | return true
601 | }
602 |
603 | func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
604 | sinfo, err := getStructInfo(out.Type())
605 | if err != nil {
606 | panic(err)
607 | }
608 | name := settableValueOf("")
609 | l := len(n.children)
610 |
611 | var inlineMap reflect.Value
612 | var elemType reflect.Type
613 | if sinfo.InlineMap != -1 {
614 | inlineMap = out.Field(sinfo.InlineMap)
615 | inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
616 | elemType = inlineMap.Type().Elem()
617 | }
618 |
619 | for i := 0; i < l; i += 2 {
620 | ni := n.children[i]
621 | if isMerge(ni) {
622 | d.merge(n.children[i+1], out)
623 | continue
624 | }
625 | if !d.unmarshal(ni, name) {
626 | continue
627 | }
628 | if info, ok := sinfo.FieldsMap[name.String()]; ok {
629 | var field reflect.Value
630 | if info.Inline == nil {
631 | field = out.Field(info.Num)
632 | } else {
633 | field = out.FieldByIndex(info.Inline)
634 | }
635 | d.unmarshal(n.children[i+1], field)
636 | } else if sinfo.InlineMap != -1 {
637 | if inlineMap.IsNil() {
638 | inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
639 | }
640 | value := reflect.New(elemType).Elem()
641 | d.unmarshal(n.children[i+1], value)
642 | inlineMap.SetMapIndex(name, value)
643 | }
644 | }
645 | return true
646 | }
647 |
648 | func failWantMap() {
649 | failf("map merge requires map or sequence of maps as the value")
650 | }
651 |
652 | func (d *decoder) merge(n *node, out reflect.Value) {
653 | switch n.kind {
654 | case mappingNode:
655 | d.unmarshal(n, out)
656 | case aliasNode:
657 | an, ok := d.doc.anchors[n.value]
658 | if ok && an.kind != mappingNode {
659 | failWantMap()
660 | }
661 | d.unmarshal(n, out)
662 | case sequenceNode:
663 | // Step backwards as earlier nodes take precedence.
664 | for i := len(n.children) - 1; i >= 0; i-- {
665 | ni := n.children[i]
666 | if ni.kind == aliasNode {
667 | an, ok := d.doc.anchors[ni.value]
668 | if ok && an.kind != mappingNode {
669 | failWantMap()
670 | }
671 | } else if ni.kind != mappingNode {
672 | failWantMap()
673 | }
674 | d.unmarshal(ni, out)
675 | }
676 | default:
677 | failWantMap()
678 | }
679 | }
680 |
681 | func isMerge(n *node) bool {
682 | return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
683 | }
684 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/encode.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding"
5 | "fmt"
6 | "reflect"
7 | "regexp"
8 | "sort"
9 | "strconv"
10 | "strings"
11 | "time"
12 | )
13 |
14 | type encoder struct {
15 | emitter yaml_emitter_t
16 | event yaml_event_t
17 | out []byte
18 | flow bool
19 | }
20 |
21 | func newEncoder() (e *encoder) {
22 | e = &encoder{}
23 | e.must(yaml_emitter_initialize(&e.emitter))
24 | yaml_emitter_set_output_string(&e.emitter, &e.out)
25 | yaml_emitter_set_unicode(&e.emitter, true)
26 | e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
27 | e.emit()
28 | e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
29 | e.emit()
30 | return e
31 | }
32 |
33 | func (e *encoder) finish() {
34 | e.must(yaml_document_end_event_initialize(&e.event, true))
35 | e.emit()
36 | e.emitter.open_ended = false
37 | e.must(yaml_stream_end_event_initialize(&e.event))
38 | e.emit()
39 | }
40 |
41 | func (e *encoder) destroy() {
42 | yaml_emitter_delete(&e.emitter)
43 | }
44 |
45 | func (e *encoder) emit() {
46 | // This will internally delete the e.event value.
47 | if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
48 | e.must(false)
49 | }
50 | }
51 |
52 | func (e *encoder) must(ok bool) {
53 | if !ok {
54 | msg := e.emitter.problem
55 | if msg == "" {
56 | msg = "unknown problem generating YAML content"
57 | }
58 | failf("%s", msg)
59 | }
60 | }
61 |
62 | func (e *encoder) marshal(tag string, in reflect.Value) {
63 | if !in.IsValid() {
64 | e.nilv()
65 | return
66 | }
67 | iface := in.Interface()
68 | if m, ok := iface.(Marshaler); ok {
69 | v, err := m.MarshalYAML()
70 | if err != nil {
71 | fail(err)
72 | }
73 | if v == nil {
74 | e.nilv()
75 | return
76 | }
77 | in = reflect.ValueOf(v)
78 | } else if m, ok := iface.(encoding.TextMarshaler); ok {
79 | text, err := m.MarshalText()
80 | if err != nil {
81 | fail(err)
82 | }
83 | in = reflect.ValueOf(string(text))
84 | }
85 | switch in.Kind() {
86 | case reflect.Interface:
87 | if in.IsNil() {
88 | e.nilv()
89 | } else {
90 | e.marshal(tag, in.Elem())
91 | }
92 | case reflect.Map:
93 | e.mapv(tag, in)
94 | case reflect.Ptr:
95 | if in.IsNil() {
96 | e.nilv()
97 | } else {
98 | e.marshal(tag, in.Elem())
99 | }
100 | case reflect.Struct:
101 | e.structv(tag, in)
102 | case reflect.Slice:
103 | if in.Type().Elem() == mapItemType {
104 | e.itemsv(tag, in)
105 | } else {
106 | e.slicev(tag, in)
107 | }
108 | case reflect.String:
109 | e.stringv(tag, in)
110 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
111 | if in.Type() == durationType {
112 | e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
113 | } else {
114 | e.intv(tag, in)
115 | }
116 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
117 | e.uintv(tag, in)
118 | case reflect.Float32, reflect.Float64:
119 | e.floatv(tag, in)
120 | case reflect.Bool:
121 | e.boolv(tag, in)
122 | default:
123 | panic("cannot marshal type: " + in.Type().String())
124 | }
125 | }
126 |
127 | func (e *encoder) mapv(tag string, in reflect.Value) {
128 | e.mappingv(tag, func() {
129 | keys := keyList(in.MapKeys())
130 | sort.Sort(keys)
131 | for _, k := range keys {
132 | e.marshal("", k)
133 | e.marshal("", in.MapIndex(k))
134 | }
135 | })
136 | }
137 |
138 | func (e *encoder) itemsv(tag string, in reflect.Value) {
139 | e.mappingv(tag, func() {
140 | slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
141 | for _, item := range slice {
142 | e.marshal("", reflect.ValueOf(item.Key))
143 | e.marshal("", reflect.ValueOf(item.Value))
144 | }
145 | })
146 | }
147 |
148 | func (e *encoder) structv(tag string, in reflect.Value) {
149 | sinfo, err := getStructInfo(in.Type())
150 | if err != nil {
151 | panic(err)
152 | }
153 | e.mappingv(tag, func() {
154 | for _, info := range sinfo.FieldsList {
155 | var value reflect.Value
156 | if info.Inline == nil {
157 | value = in.Field(info.Num)
158 | } else {
159 | value = in.FieldByIndex(info.Inline)
160 | }
161 | if info.OmitEmpty && isZero(value) {
162 | continue
163 | }
164 | e.marshal("", reflect.ValueOf(info.Key))
165 | e.flow = info.Flow
166 | e.marshal("", value)
167 | }
168 | if sinfo.InlineMap >= 0 {
169 | m := in.Field(sinfo.InlineMap)
170 | if m.Len() > 0 {
171 | e.flow = false
172 | keys := keyList(m.MapKeys())
173 | sort.Sort(keys)
174 | for _, k := range keys {
175 | if _, found := sinfo.FieldsMap[k.String()]; found {
176 | panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
177 | }
178 | e.marshal("", k)
179 | e.flow = false
180 | e.marshal("", m.MapIndex(k))
181 | }
182 | }
183 | }
184 | })
185 | }
186 |
187 | func (e *encoder) mappingv(tag string, f func()) {
188 | implicit := tag == ""
189 | style := yaml_BLOCK_MAPPING_STYLE
190 | if e.flow {
191 | e.flow = false
192 | style = yaml_FLOW_MAPPING_STYLE
193 | }
194 | e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
195 | e.emit()
196 | f()
197 | e.must(yaml_mapping_end_event_initialize(&e.event))
198 | e.emit()
199 | }
200 |
201 | func (e *encoder) slicev(tag string, in reflect.Value) {
202 | implicit := tag == ""
203 | style := yaml_BLOCK_SEQUENCE_STYLE
204 | if e.flow {
205 | e.flow = false
206 | style = yaml_FLOW_SEQUENCE_STYLE
207 | }
208 | e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
209 | e.emit()
210 | n := in.Len()
211 | for i := 0; i < n; i++ {
212 | e.marshal("", in.Index(i))
213 | }
214 | e.must(yaml_sequence_end_event_initialize(&e.event))
215 | e.emit()
216 | }
217 |
218 | // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
219 | //
220 | // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
221 | // in YAML 1.2 and by this package, but these should be marshalled quoted for
222 | // the time being for compatibility with other parsers.
223 | func isBase60Float(s string) (result bool) {
224 | // Fast path.
225 | if s == "" {
226 | return false
227 | }
228 | c := s[0]
229 | if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
230 | return false
231 | }
232 | // Do the full match.
233 | return base60float.MatchString(s)
234 | }
235 |
236 | // From http://yaml.org/type/float.html, except the regular expression there
237 | // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
238 | var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
239 |
240 | func (e *encoder) stringv(tag string, in reflect.Value) {
241 | var style yaml_scalar_style_t
242 | s := in.String()
243 | rtag, rs := resolve("", s)
244 | if rtag == yaml_BINARY_TAG {
245 | if tag == "" || tag == yaml_STR_TAG {
246 | tag = rtag
247 | s = rs.(string)
248 | } else if tag == yaml_BINARY_TAG {
249 | failf("explicitly tagged !!binary data must be base64-encoded")
250 | } else {
251 | failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
252 | }
253 | }
254 | if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
255 | style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
256 | } else if strings.Contains(s, "\n") {
257 | style = yaml_LITERAL_SCALAR_STYLE
258 | } else {
259 | style = yaml_PLAIN_SCALAR_STYLE
260 | }
261 | e.emitScalar(s, "", tag, style)
262 | }
263 |
264 | func (e *encoder) boolv(tag string, in reflect.Value) {
265 | var s string
266 | if in.Bool() {
267 | s = "true"
268 | } else {
269 | s = "false"
270 | }
271 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
272 | }
273 |
274 | func (e *encoder) intv(tag string, in reflect.Value) {
275 | s := strconv.FormatInt(in.Int(), 10)
276 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
277 | }
278 |
279 | func (e *encoder) uintv(tag string, in reflect.Value) {
280 | s := strconv.FormatUint(in.Uint(), 10)
281 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
282 | }
283 |
284 | func (e *encoder) floatv(tag string, in reflect.Value) {
285 | // FIXME: Handle 64 bits here.
286 | s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
287 | switch s {
288 | case "+Inf":
289 | s = ".inf"
290 | case "-Inf":
291 | s = "-.inf"
292 | case "NaN":
293 | s = ".nan"
294 | }
295 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
296 | }
297 |
298 | func (e *encoder) nilv() {
299 | e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
300 | }
301 |
302 | func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
303 | implicit := tag == ""
304 | e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
305 | e.emit()
306 | }
307 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/encode_test.go:
--------------------------------------------------------------------------------
1 | package yaml_test
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | "strconv"
7 | "strings"
8 | "time"
9 |
10 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/gopkg.in/yaml.v2"
11 | . "gopkg.in/check.v1"
12 | "net"
13 | "os"
14 | )
15 |
16 | var marshalIntTest = 123
17 |
18 | var marshalTests = []struct {
19 | value interface{}
20 | data string
21 | }{
22 | {
23 | nil,
24 | "null\n",
25 | }, {
26 | &struct{}{},
27 | "{}\n",
28 | }, {
29 | map[string]string{"v": "hi"},
30 | "v: hi\n",
31 | }, {
32 | map[string]interface{}{"v": "hi"},
33 | "v: hi\n",
34 | }, {
35 | map[string]string{"v": "true"},
36 | "v: \"true\"\n",
37 | }, {
38 | map[string]string{"v": "false"},
39 | "v: \"false\"\n",
40 | }, {
41 | map[string]interface{}{"v": true},
42 | "v: true\n",
43 | }, {
44 | map[string]interface{}{"v": false},
45 | "v: false\n",
46 | }, {
47 | map[string]interface{}{"v": 10},
48 | "v: 10\n",
49 | }, {
50 | map[string]interface{}{"v": -10},
51 | "v: -10\n",
52 | }, {
53 | map[string]uint{"v": 42},
54 | "v: 42\n",
55 | }, {
56 | map[string]interface{}{"v": int64(4294967296)},
57 | "v: 4294967296\n",
58 | }, {
59 | map[string]int64{"v": int64(4294967296)},
60 | "v: 4294967296\n",
61 | }, {
62 | map[string]uint64{"v": 4294967296},
63 | "v: 4294967296\n",
64 | }, {
65 | map[string]interface{}{"v": "10"},
66 | "v: \"10\"\n",
67 | }, {
68 | map[string]interface{}{"v": 0.1},
69 | "v: 0.1\n",
70 | }, {
71 | map[string]interface{}{"v": float64(0.1)},
72 | "v: 0.1\n",
73 | }, {
74 | map[string]interface{}{"v": -0.1},
75 | "v: -0.1\n",
76 | }, {
77 | map[string]interface{}{"v": math.Inf(+1)},
78 | "v: .inf\n",
79 | }, {
80 | map[string]interface{}{"v": math.Inf(-1)},
81 | "v: -.inf\n",
82 | }, {
83 | map[string]interface{}{"v": math.NaN()},
84 | "v: .nan\n",
85 | }, {
86 | map[string]interface{}{"v": nil},
87 | "v: null\n",
88 | }, {
89 | map[string]interface{}{"v": ""},
90 | "v: \"\"\n",
91 | }, {
92 | map[string][]string{"v": []string{"A", "B"}},
93 | "v:\n- A\n- B\n",
94 | }, {
95 | map[string][]string{"v": []string{"A", "B\nC"}},
96 | "v:\n- A\n- |-\n B\n C\n",
97 | }, {
98 | map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
99 | "v:\n- A\n- 1\n- B:\n - 2\n - 3\n",
100 | }, {
101 | map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
102 | "a:\n b: c\n",
103 | }, {
104 | map[string]interface{}{"a": "-"},
105 | "a: '-'\n",
106 | },
107 |
108 | // Simple values.
109 | {
110 | &marshalIntTest,
111 | "123\n",
112 | },
113 |
114 | // Structures
115 | {
116 | &struct{ Hello string }{"world"},
117 | "hello: world\n",
118 | }, {
119 | &struct {
120 | A struct {
121 | B string
122 | }
123 | }{struct{ B string }{"c"}},
124 | "a:\n b: c\n",
125 | }, {
126 | &struct {
127 | A *struct {
128 | B string
129 | }
130 | }{&struct{ B string }{"c"}},
131 | "a:\n b: c\n",
132 | }, {
133 | &struct {
134 | A *struct {
135 | B string
136 | }
137 | }{},
138 | "a: null\n",
139 | }, {
140 | &struct{ A int }{1},
141 | "a: 1\n",
142 | }, {
143 | &struct{ A []int }{[]int{1, 2}},
144 | "a:\n- 1\n- 2\n",
145 | }, {
146 | &struct {
147 | B int "a"
148 | }{1},
149 | "a: 1\n",
150 | }, {
151 | &struct{ A bool }{true},
152 | "a: true\n",
153 | },
154 |
155 | // Conditional flag
156 | {
157 | &struct {
158 | A int "a,omitempty"
159 | B int "b,omitempty"
160 | }{1, 0},
161 | "a: 1\n",
162 | }, {
163 | &struct {
164 | A int "a,omitempty"
165 | B int "b,omitempty"
166 | }{0, 0},
167 | "{}\n",
168 | }, {
169 | &struct {
170 | A *struct{ X, y int } "a,omitempty,flow"
171 | }{&struct{ X, y int }{1, 2}},
172 | "a: {x: 1}\n",
173 | }, {
174 | &struct {
175 | A *struct{ X, y int } "a,omitempty,flow"
176 | }{nil},
177 | "{}\n",
178 | }, {
179 | &struct {
180 | A *struct{ X, y int } "a,omitempty,flow"
181 | }{&struct{ X, y int }{}},
182 | "a: {x: 0}\n",
183 | }, {
184 | &struct {
185 | A struct{ X, y int } "a,omitempty,flow"
186 | }{struct{ X, y int }{1, 2}},
187 | "a: {x: 1}\n",
188 | }, {
189 | &struct {
190 | A struct{ X, y int } "a,omitempty,flow"
191 | }{struct{ X, y int }{0, 1}},
192 | "{}\n",
193 | },
194 |
195 | // Flow flag
196 | {
197 | &struct {
198 | A []int "a,flow"
199 | }{[]int{1, 2}},
200 | "a: [1, 2]\n",
201 | }, {
202 | &struct {
203 | A map[string]string "a,flow"
204 | }{map[string]string{"b": "c", "d": "e"}},
205 | "a: {b: c, d: e}\n",
206 | }, {
207 | &struct {
208 | A struct {
209 | B, D string
210 | } "a,flow"
211 | }{struct{ B, D string }{"c", "e"}},
212 | "a: {b: c, d: e}\n",
213 | },
214 |
215 | // Unexported field
216 | {
217 | &struct {
218 | u int
219 | A int
220 | }{0, 1},
221 | "a: 1\n",
222 | },
223 |
224 | // Ignored field
225 | {
226 | &struct {
227 | A int
228 | B int "-"
229 | }{1, 2},
230 | "a: 1\n",
231 | },
232 |
233 | // Struct inlining
234 | {
235 | &struct {
236 | A int
237 | C inlineB `yaml:",inline"`
238 | }{1, inlineB{2, inlineC{3}}},
239 | "a: 1\nb: 2\nc: 3\n",
240 | },
241 |
242 | // Map inlining
243 | {
244 | &struct {
245 | A int
246 | C map[string]int `yaml:",inline"`
247 | }{1, map[string]int{"b": 2, "c": 3}},
248 | "a: 1\nb: 2\nc: 3\n",
249 | },
250 |
251 | // Duration
252 | {
253 | map[string]time.Duration{"a": 3 * time.Second},
254 | "a: 3s\n",
255 | },
256 |
257 | // Issue #24: bug in map merging logic.
258 | {
259 | map[string]string{"a": ""},
260 | "a: \n",
261 | },
262 |
263 | // Issue #34: marshal unsupported base 60 floats quoted for compatibility
264 | // with old YAML 1.1 parsers.
265 | {
266 | map[string]string{"a": "1:1"},
267 | "a: \"1:1\"\n",
268 | },
269 |
270 | // Binary data.
271 | {
272 | map[string]string{"a": "\x00"},
273 | "a: \"\\0\"\n",
274 | }, {
275 | map[string]string{"a": "\x80\x81\x82"},
276 | "a: !!binary gIGC\n",
277 | }, {
278 | map[string]string{"a": strings.Repeat("\x90", 54)},
279 | "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
280 | },
281 |
282 | // Ordered maps.
283 | {
284 | &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
285 | "b: 2\na: 1\nd: 4\nc: 3\nsub:\n e: 5\n",
286 | },
287 |
288 | // Encode unicode as utf-8 rather than in escaped form.
289 | {
290 | map[string]string{"a": "你好"},
291 | "a: 你好\n",
292 | },
293 |
294 | // Support encoding.TextMarshaler.
295 | {
296 | map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
297 | "a: 1.2.3.4\n",
298 | },
299 | {
300 | map[string]time.Time{"a": time.Unix(1424801979, 0)},
301 | "a: 2015-02-24T18:19:39Z\n",
302 | },
303 |
304 | // Ensure strings containing ": " are quoted (reported as PR #43, but not reproducible).
305 | {
306 | map[string]string{"a": "b: c"},
307 | "a: 'b: c'\n",
308 | },
309 | }
310 |
311 | func (s *S) TestMarshal(c *C) {
312 | defer os.Setenv("TZ", os.Getenv("TZ"))
313 | os.Setenv("TZ", "UTC")
314 | for _, item := range marshalTests {
315 | data, err := yaml.Marshal(item.value)
316 | c.Assert(err, IsNil)
317 | c.Assert(string(data), Equals, item.data)
318 | }
319 | }
320 |
321 | var marshalErrorTests = []struct {
322 | value interface{}
323 | error string
324 | panic string
325 | }{{
326 | value: &struct {
327 | B int
328 | inlineB ",inline"
329 | }{1, inlineB{2, inlineC{3}}},
330 | panic: `Duplicated key 'b' in struct struct \{ B int; .*`,
331 | }, {
332 | value: &struct {
333 | A int
334 | B map[string]int ",inline"
335 | }{1, map[string]int{"a": 2}},
336 | panic: `Can't have key "a" in inlined map; conflicts with struct field`,
337 | }}
338 |
339 | func (s *S) TestMarshalErrors(c *C) {
340 | for _, item := range marshalErrorTests {
341 | if item.panic != "" {
342 | c.Assert(func() { yaml.Marshal(item.value) }, PanicMatches, item.panic)
343 | } else {
344 | _, err := yaml.Marshal(item.value)
345 | c.Assert(err, ErrorMatches, item.error)
346 | }
347 | }
348 | }
349 |
350 | func (s *S) TestMarshalTypeCache(c *C) {
351 | var data []byte
352 | var err error
353 | func() {
354 | type T struct{ A int }
355 | data, err = yaml.Marshal(&T{})
356 | c.Assert(err, IsNil)
357 | }()
358 | func() {
359 | type T struct{ B int }
360 | data, err = yaml.Marshal(&T{})
361 | c.Assert(err, IsNil)
362 | }()
363 | c.Assert(string(data), Equals, "b: 0\n")
364 | }
365 |
366 | var marshalerTests = []struct {
367 | data string
368 | value interface{}
369 | }{
370 | {"_:\n hi: there\n", map[interface{}]interface{}{"hi": "there"}},
371 | {"_:\n- 1\n- A\n", []interface{}{1, "A"}},
372 | {"_: 10\n", 10},
373 | {"_: null\n", nil},
374 | {"_: BAR!\n", "BAR!"},
375 | }
376 |
377 | type marshalerType struct {
378 | value interface{}
379 | }
380 |
381 | func (o marshalerType) MarshalText() ([]byte, error) {
382 | panic("MarshalText called on type with MarshalYAML")
383 | }
384 |
385 | func (o marshalerType) MarshalYAML() (interface{}, error) {
386 | return o.value, nil
387 | }
388 |
389 | type marshalerValue struct {
390 | Field marshalerType "_"
391 | }
392 |
393 | func (s *S) TestMarshaler(c *C) {
394 | for _, item := range marshalerTests {
395 | obj := &marshalerValue{}
396 | obj.Field.value = item.value
397 | data, err := yaml.Marshal(obj)
398 | c.Assert(err, IsNil)
399 | c.Assert(string(data), Equals, string(item.data))
400 | }
401 | }
402 |
403 | func (s *S) TestMarshalerWholeDocument(c *C) {
404 | obj := &marshalerType{}
405 | obj.value = map[string]string{"hello": "world!"}
406 | data, err := yaml.Marshal(obj)
407 | c.Assert(err, IsNil)
408 | c.Assert(string(data), Equals, "hello: world!\n")
409 | }
410 |
411 | type failingMarshaler struct{}
412 |
413 | func (ft *failingMarshaler) MarshalYAML() (interface{}, error) {
414 | return nil, failingErr
415 | }
416 |
417 | func (s *S) TestMarshalerError(c *C) {
418 | _, err := yaml.Marshal(&failingMarshaler{})
419 | c.Assert(err, Equals, failingErr)
420 | }
421 |
422 | func (s *S) TestSortedOutput(c *C) {
423 | order := []interface{}{
424 | false,
425 | true,
426 | 1,
427 | uint(1),
428 | 1.0,
429 | 1.1,
430 | 1.2,
431 | 2,
432 | uint(2),
433 | 2.0,
434 | 2.1,
435 | "",
436 | ".1",
437 | ".2",
438 | ".a",
439 | "1",
440 | "2",
441 | "a!10",
442 | "a/2",
443 | "a/10",
444 | "a~10",
445 | "ab/1",
446 | "b/1",
447 | "b/01",
448 | "b/2",
449 | "b/02",
450 | "b/3",
451 | "b/03",
452 | "b1",
453 | "b01",
454 | "b3",
455 | "c2.10",
456 | "c10.2",
457 | "d1",
458 | "d12",
459 | "d12a",
460 | }
461 | m := make(map[interface{}]int)
462 | for _, k := range order {
463 | m[k] = 1
464 | }
465 | data, err := yaml.Marshal(m)
466 | c.Assert(err, IsNil)
467 | out := "\n" + string(data)
468 | last := 0
469 | for i, k := range order {
470 | repr := fmt.Sprint(k)
471 | if s, ok := k.(string); ok {
472 | if _, err = strconv.ParseFloat(repr, 32); s == "" || err == nil {
473 | repr = `"` + repr + `"`
474 | }
475 | }
476 | index := strings.Index(out, "\n"+repr+":")
477 | if index == -1 {
478 | c.Fatalf("%#v is not in the output: %#v", k, out)
479 | }
480 | if index < last {
481 | c.Fatalf("%#v was generated before %#v: %q", k, order[i-1], out)
482 | }
483 | last = index
484 | }
485 | }
486 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/readerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "io"
5 | )
6 |
7 | // Set the reader error and return 0.
8 | func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
9 | parser.error = yaml_READER_ERROR
10 | parser.problem = problem
11 | parser.problem_offset = offset
12 | parser.problem_value = value
13 | return false
14 | }
15 |
16 | // Byte order marks.
17 | const (
18 | bom_UTF8 = "\xef\xbb\xbf"
19 | bom_UTF16LE = "\xff\xfe"
20 | bom_UTF16BE = "\xfe\xff"
21 | )
22 |
23 | // Determine the input stream encoding by checking the BOM symbol. If no BOM is
24 | // found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
25 | func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
26 | // Ensure that we had enough bytes in the raw buffer.
27 | for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
28 | if !yaml_parser_update_raw_buffer(parser) {
29 | return false
30 | }
31 | }
32 |
33 | // Determine the encoding.
34 | buf := parser.raw_buffer
35 | pos := parser.raw_buffer_pos
36 | avail := len(buf) - pos
37 | if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
38 | parser.encoding = yaml_UTF16LE_ENCODING
39 | parser.raw_buffer_pos += 2
40 | parser.offset += 2
41 | } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
42 | parser.encoding = yaml_UTF16BE_ENCODING
43 | parser.raw_buffer_pos += 2
44 | parser.offset += 2
45 | } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
46 | parser.encoding = yaml_UTF8_ENCODING
47 | parser.raw_buffer_pos += 3
48 | parser.offset += 3
49 | } else {
50 | parser.encoding = yaml_UTF8_ENCODING
51 | }
52 | return true
53 | }
54 |
55 | // Update the raw buffer.
56 | func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
57 | size_read := 0
58 |
59 | // Return if the raw buffer is full.
60 | if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
61 | return true
62 | }
63 |
64 | // Return on EOF.
65 | if parser.eof {
66 | return true
67 | }
68 |
69 | // Move the remaining bytes in the raw buffer to the beginning.
70 | if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
71 | copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
72 | }
73 | parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
74 | parser.raw_buffer_pos = 0
75 |
76 | // Call the read handler to fill the buffer.
77 | size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
78 | parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
79 | if err == io.EOF {
80 | parser.eof = true
81 | } else if err != nil {
82 | return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
83 | }
84 | return true
85 | }
86 |
87 | // Ensure that the buffer contains at least `length` characters.
88 | // Return true on success, false on failure.
89 | //
90 | // The length is supposed to be significantly less that the buffer size.
91 | func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
92 | if parser.read_handler == nil {
93 | panic("read handler must be set")
94 | }
95 |
96 | // If the EOF flag is set and the raw buffer is empty, do nothing.
97 | if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
98 | return true
99 | }
100 |
101 | // Return if the buffer contains enough characters.
102 | if parser.unread >= length {
103 | return true
104 | }
105 |
106 | // Determine the input encoding if it is not known yet.
107 | if parser.encoding == yaml_ANY_ENCODING {
108 | if !yaml_parser_determine_encoding(parser) {
109 | return false
110 | }
111 | }
112 |
113 | // Move the unread characters to the beginning of the buffer.
114 | buffer_len := len(parser.buffer)
115 | if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
116 | copy(parser.buffer, parser.buffer[parser.buffer_pos:])
117 | buffer_len -= parser.buffer_pos
118 | parser.buffer_pos = 0
119 | } else if parser.buffer_pos == buffer_len {
120 | buffer_len = 0
121 | parser.buffer_pos = 0
122 | }
123 |
124 | // Open the whole buffer for writing, and cut it before returning.
125 | parser.buffer = parser.buffer[:cap(parser.buffer)]
126 |
127 | // Fill the buffer until it has enough characters.
128 | first := true
129 | for parser.unread < length {
130 |
131 | // Fill the raw buffer if necessary.
132 | if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
133 | if !yaml_parser_update_raw_buffer(parser) {
134 | parser.buffer = parser.buffer[:buffer_len]
135 | return false
136 | }
137 | }
138 | first = false
139 |
140 | // Decode the raw buffer.
141 | inner:
142 | for parser.raw_buffer_pos != len(parser.raw_buffer) {
143 | var value rune
144 | var width int
145 |
146 | raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
147 |
148 | // Decode the next character.
149 | switch parser.encoding {
150 | case yaml_UTF8_ENCODING:
151 | // Decode a UTF-8 character. Check RFC 3629
152 | // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
153 | //
154 | // The following table (taken from the RFC) is used for
155 | // decoding.
156 | //
157 | // Char. number range | UTF-8 octet sequence
158 | // (hexadecimal) | (binary)
159 | // --------------------+------------------------------------
160 | // 0000 0000-0000 007F | 0xxxxxxx
161 | // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
162 | // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
163 | // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
164 | //
165 | // Additionally, the characters in the range 0xD800-0xDFFF
166 | // are prohibited as they are reserved for use with UTF-16
167 | // surrogate pairs.
168 |
169 | // Determine the length of the UTF-8 sequence.
170 | octet := parser.raw_buffer[parser.raw_buffer_pos]
171 | switch {
172 | case octet&0x80 == 0x00:
173 | width = 1
174 | case octet&0xE0 == 0xC0:
175 | width = 2
176 | case octet&0xF0 == 0xE0:
177 | width = 3
178 | case octet&0xF8 == 0xF0:
179 | width = 4
180 | default:
181 | // The leading octet is invalid.
182 | return yaml_parser_set_reader_error(parser,
183 | "invalid leading UTF-8 octet",
184 | parser.offset, int(octet))
185 | }
186 |
187 | // Check if the raw buffer contains an incomplete character.
188 | if width > raw_unread {
189 | if parser.eof {
190 | return yaml_parser_set_reader_error(parser,
191 | "incomplete UTF-8 octet sequence",
192 | parser.offset, -1)
193 | }
194 | break inner
195 | }
196 |
197 | // Decode the leading octet.
198 | switch {
199 | case octet&0x80 == 0x00:
200 | value = rune(octet & 0x7F)
201 | case octet&0xE0 == 0xC0:
202 | value = rune(octet & 0x1F)
203 | case octet&0xF0 == 0xE0:
204 | value = rune(octet & 0x0F)
205 | case octet&0xF8 == 0xF0:
206 | value = rune(octet & 0x07)
207 | default:
208 | value = 0
209 | }
210 |
211 | // Check and decode the trailing octets.
212 | for k := 1; k < width; k++ {
213 | octet = parser.raw_buffer[parser.raw_buffer_pos+k]
214 |
215 | // Check if the octet is valid.
216 | if (octet & 0xC0) != 0x80 {
217 | return yaml_parser_set_reader_error(parser,
218 | "invalid trailing UTF-8 octet",
219 | parser.offset+k, int(octet))
220 | }
221 |
222 | // Decode the octet.
223 | value = (value << 6) + rune(octet&0x3F)
224 | }
225 |
226 | // Check the length of the sequence against the value.
227 | switch {
228 | case width == 1:
229 | case width == 2 && value >= 0x80:
230 | case width == 3 && value >= 0x800:
231 | case width == 4 && value >= 0x10000:
232 | default:
233 | return yaml_parser_set_reader_error(parser,
234 | "invalid length of a UTF-8 sequence",
235 | parser.offset, -1)
236 | }
237 |
238 | // Check the range of the value.
239 | if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
240 | return yaml_parser_set_reader_error(parser,
241 | "invalid Unicode character",
242 | parser.offset, int(value))
243 | }
244 |
245 | case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
246 | var low, high int
247 | if parser.encoding == yaml_UTF16LE_ENCODING {
248 | low, high = 0, 1
249 | } else {
250 | high, low = 1, 0
251 | }
252 |
253 | // The UTF-16 encoding is not as simple as one might
254 | // naively think. Check RFC 2781
255 | // (http://www.ietf.org/rfc/rfc2781.txt).
256 | //
257 | // Normally, two subsequent bytes describe a Unicode
258 | // character. However a special technique (called a
259 | // surrogate pair) is used for specifying character
260 | // values larger than 0xFFFF.
261 | //
262 | // A surrogate pair consists of two pseudo-characters:
263 | // high surrogate area (0xD800-0xDBFF)
264 | // low surrogate area (0xDC00-0xDFFF)
265 | //
266 | // The following formulas are used for decoding
267 | // and encoding characters using surrogate pairs:
268 | //
269 | // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
270 | // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
271 | // W1 = 110110yyyyyyyyyy
272 | // W2 = 110111xxxxxxxxxx
273 | //
274 | // where U is the character value, W1 is the high surrogate
275 | // area, W2 is the low surrogate area.
276 |
277 | // Check for incomplete UTF-16 character.
278 | if raw_unread < 2 {
279 | if parser.eof {
280 | return yaml_parser_set_reader_error(parser,
281 | "incomplete UTF-16 character",
282 | parser.offset, -1)
283 | }
284 | break inner
285 | }
286 |
287 | // Get the character.
288 | value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
289 | (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
290 |
291 | // Check for unexpected low surrogate area.
292 | if value&0xFC00 == 0xDC00 {
293 | return yaml_parser_set_reader_error(parser,
294 | "unexpected low surrogate area",
295 | parser.offset, int(value))
296 | }
297 |
298 | // Check for a high surrogate area.
299 | if value&0xFC00 == 0xD800 {
300 | width = 4
301 |
302 | // Check for incomplete surrogate pair.
303 | if raw_unread < 4 {
304 | if parser.eof {
305 | return yaml_parser_set_reader_error(parser,
306 | "incomplete UTF-16 surrogate pair",
307 | parser.offset, -1)
308 | }
309 | break inner
310 | }
311 |
312 | // Get the next character.
313 | value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
314 | (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
315 |
316 | // Check for a low surrogate area.
317 | if value2&0xFC00 != 0xDC00 {
318 | return yaml_parser_set_reader_error(parser,
319 | "expected low surrogate area",
320 | parser.offset+2, int(value2))
321 | }
322 |
323 | // Generate the value of the surrogate pair.
324 | value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
325 | } else {
326 | width = 2
327 | }
328 |
329 | default:
330 | panic("impossible")
331 | }
332 |
333 | // Check if the character is in the allowed range:
334 | // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
335 | // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
336 | // | [#x10000-#x10FFFF] (32 bit)
337 | switch {
338 | case value == 0x09:
339 | case value == 0x0A:
340 | case value == 0x0D:
341 | case value >= 0x20 && value <= 0x7E:
342 | case value == 0x85:
343 | case value >= 0xA0 && value <= 0xD7FF:
344 | case value >= 0xE000 && value <= 0xFFFD:
345 | case value >= 0x10000 && value <= 0x10FFFF:
346 | default:
347 | return yaml_parser_set_reader_error(parser,
348 | "control characters are not allowed",
349 | parser.offset, int(value))
350 | }
351 |
352 | // Move the raw pointers.
353 | parser.raw_buffer_pos += width
354 | parser.offset += width
355 |
356 | // Finally put the character into the buffer.
357 | if value <= 0x7F {
358 | // 0000 0000-0000 007F . 0xxxxxxx
359 | parser.buffer[buffer_len+0] = byte(value)
360 | } else if value <= 0x7FF {
361 | // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
362 | parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
363 | parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
364 | } else if value <= 0xFFFF {
365 | // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
366 | parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
367 | parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
368 | parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
369 | } else {
370 | // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
371 | parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
372 | parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
373 | parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
374 | parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
375 | }
376 | buffer_len += width
377 |
378 | parser.unread++
379 | }
380 |
381 | // On EOF, put NUL into the buffer and return.
382 | if parser.eof {
383 | parser.buffer[buffer_len] = 0
384 | buffer_len++
385 | parser.unread++
386 | break
387 | }
388 | }
389 | parser.buffer = parser.buffer[:buffer_len]
390 | return true
391 | }
392 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/resolve.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding/base64"
5 | "math"
6 | "strconv"
7 | "strings"
8 | "unicode/utf8"
9 | )
10 |
11 | type resolveMapItem struct {
12 | value interface{}
13 | tag string
14 | }
15 |
16 | var resolveTable = make([]byte, 256)
17 | var resolveMap = make(map[string]resolveMapItem)
18 |
19 | func init() {
20 | t := resolveTable
21 | t[int('+')] = 'S' // Sign
22 | t[int('-')] = 'S'
23 | for _, c := range "0123456789" {
24 | t[int(c)] = 'D' // Digit
25 | }
26 | for _, c := range "yYnNtTfFoO~" {
27 | t[int(c)] = 'M' // In map
28 | }
29 | t[int('.')] = '.' // Float (potentially in map)
30 |
31 | var resolveMapList = []struct {
32 | v interface{}
33 | tag string
34 | l []string
35 | }{
36 | {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
37 | {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
38 | {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
39 | {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
40 | {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
41 | {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
42 | {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
43 | {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
44 | {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
45 | {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
46 | {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
47 | {"<<", yaml_MERGE_TAG, []string{"<<"}},
48 | }
49 |
50 | m := resolveMap
51 | for _, item := range resolveMapList {
52 | for _, s := range item.l {
53 | m[s] = resolveMapItem{item.v, item.tag}
54 | }
55 | }
56 | }
57 |
58 | const longTagPrefix = "tag:yaml.org,2002:"
59 |
60 | func shortTag(tag string) string {
61 | // TODO This can easily be made faster and produce less garbage.
62 | if strings.HasPrefix(tag, longTagPrefix) {
63 | return "!!" + tag[len(longTagPrefix):]
64 | }
65 | return tag
66 | }
67 |
68 | func longTag(tag string) string {
69 | if strings.HasPrefix(tag, "!!") {
70 | return longTagPrefix + tag[2:]
71 | }
72 | return tag
73 | }
74 |
75 | func resolvableTag(tag string) bool {
76 | switch tag {
77 | case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
78 | return true
79 | }
80 | return false
81 | }
82 |
83 | func resolve(tag string, in string) (rtag string, out interface{}) {
84 | if !resolvableTag(tag) {
85 | return tag, in
86 | }
87 |
88 | defer func() {
89 | switch tag {
90 | case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
91 | return
92 | }
93 | failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
94 | }()
95 |
96 | // Any data is accepted as a !!str or !!binary.
97 | // Otherwise, the prefix is enough of a hint about what it might be.
98 | hint := byte('N')
99 | if in != "" {
100 | hint = resolveTable[in[0]]
101 | }
102 | if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
103 | // Handle things we can lookup in a map.
104 | if item, ok := resolveMap[in]; ok {
105 | return item.tag, item.value
106 | }
107 |
108 | // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
109 | // are purposefully unsupported here. They're still quoted on
110 | // the way out for compatibility with other parser, though.
111 |
112 | switch hint {
113 | case 'M':
114 | // We've already checked the map above.
115 |
116 | case '.':
117 | // Not in the map, so maybe a normal float.
118 | floatv, err := strconv.ParseFloat(in, 64)
119 | if err == nil {
120 | return yaml_FLOAT_TAG, floatv
121 | }
122 |
123 | case 'D', 'S':
124 | // Int, float, or timestamp.
125 | plain := strings.Replace(in, "_", "", -1)
126 | intv, err := strconv.ParseInt(plain, 0, 64)
127 | if err == nil {
128 | if intv == int64(int(intv)) {
129 | return yaml_INT_TAG, int(intv)
130 | } else {
131 | return yaml_INT_TAG, intv
132 | }
133 | }
134 | uintv, err := strconv.ParseUint(plain, 0, 64)
135 | if err == nil {
136 | return yaml_INT_TAG, uintv
137 | }
138 | floatv, err := strconv.ParseFloat(plain, 64)
139 | if err == nil {
140 | return yaml_FLOAT_TAG, floatv
141 | }
142 | if strings.HasPrefix(plain, "0b") {
143 | intv, err := strconv.ParseInt(plain[2:], 2, 64)
144 | if err == nil {
145 | if intv == int64(int(intv)) {
146 | return yaml_INT_TAG, int(intv)
147 | } else {
148 | return yaml_INT_TAG, intv
149 | }
150 | }
151 | uintv, err := strconv.ParseUint(plain[2:], 2, 64)
152 | if err == nil {
153 | return yaml_INT_TAG, uintv
154 | }
155 | } else if strings.HasPrefix(plain, "-0b") {
156 | intv, err := strconv.ParseInt(plain[3:], 2, 64)
157 | if err == nil {
158 | if intv == int64(int(intv)) {
159 | return yaml_INT_TAG, -int(intv)
160 | } else {
161 | return yaml_INT_TAG, -intv
162 | }
163 | }
164 | }
165 | // XXX Handle timestamps here.
166 |
167 | default:
168 | panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
169 | }
170 | }
171 | if tag == yaml_BINARY_TAG {
172 | return yaml_BINARY_TAG, in
173 | }
174 | if utf8.ValidString(in) {
175 | return yaml_STR_TAG, in
176 | }
177 | return yaml_BINARY_TAG, encodeBase64(in)
178 | }
179 |
180 | // encodeBase64 encodes s as base64 that is broken up into multiple lines
181 | // as appropriate for the resulting length.
182 | func encodeBase64(s string) string {
183 | const lineLen = 70
184 | encLen := base64.StdEncoding.EncodedLen(len(s))
185 | lines := encLen/lineLen + 1
186 | buf := make([]byte, encLen*2+lines)
187 | in := buf[0:encLen]
188 | out := buf[encLen:]
189 | base64.StdEncoding.Encode(in, []byte(s))
190 | k := 0
191 | for i := 0; i < len(in); i += lineLen {
192 | j := i + lineLen
193 | if j > len(in) {
194 | j = len(in)
195 | }
196 | k += copy(out[k:], in[i:j])
197 | if lines > 1 {
198 | out[k] = '\n'
199 | k++
200 | }
201 | }
202 | return string(out[:k])
203 | }
204 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/sorter.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "reflect"
5 | "unicode"
6 | )
7 |
8 | type keyList []reflect.Value
9 |
10 | func (l keyList) Len() int { return len(l) }
11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
12 | func (l keyList) Less(i, j int) bool {
13 | a := l[i]
14 | b := l[j]
15 | ak := a.Kind()
16 | bk := b.Kind()
17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
18 | a = a.Elem()
19 | ak = a.Kind()
20 | }
21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
22 | b = b.Elem()
23 | bk = b.Kind()
24 | }
25 | af, aok := keyFloat(a)
26 | bf, bok := keyFloat(b)
27 | if aok && bok {
28 | if af != bf {
29 | return af < bf
30 | }
31 | if ak != bk {
32 | return ak < bk
33 | }
34 | return numLess(a, b)
35 | }
36 | if ak != reflect.String || bk != reflect.String {
37 | return ak < bk
38 | }
39 | ar, br := []rune(a.String()), []rune(b.String())
40 | for i := 0; i < len(ar) && i < len(br); i++ {
41 | if ar[i] == br[i] {
42 | continue
43 | }
44 | al := unicode.IsLetter(ar[i])
45 | bl := unicode.IsLetter(br[i])
46 | if al && bl {
47 | return ar[i] < br[i]
48 | }
49 | if al || bl {
50 | return bl
51 | }
52 | var ai, bi int
53 | var an, bn int64
54 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
55 | an = an*10 + int64(ar[ai]-'0')
56 | }
57 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
58 | bn = bn*10 + int64(br[bi]-'0')
59 | }
60 | if an != bn {
61 | return an < bn
62 | }
63 | if ai != bi {
64 | return ai < bi
65 | }
66 | return ar[i] < br[i]
67 | }
68 | return len(ar) < len(br)
69 | }
70 |
71 | // keyFloat returns a float value for v if it is a number/bool
72 | // and whether it is a number/bool or not.
73 | func keyFloat(v reflect.Value) (f float64, ok bool) {
74 | switch v.Kind() {
75 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
76 | return float64(v.Int()), true
77 | case reflect.Float32, reflect.Float64:
78 | return v.Float(), true
79 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
80 | return float64(v.Uint()), true
81 | case reflect.Bool:
82 | if v.Bool() {
83 | return 1, true
84 | }
85 | return 0, true
86 | }
87 | return 0, false
88 | }
89 |
90 | // numLess returns whether a < b.
91 | // a and b must necessarily have the same kind.
92 | func numLess(a, b reflect.Value) bool {
93 | switch a.Kind() {
94 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
95 | return a.Int() < b.Int()
96 | case reflect.Float32, reflect.Float64:
97 | return a.Float() < b.Float()
98 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
99 | return a.Uint() < b.Uint()
100 | case reflect.Bool:
101 | return !a.Bool() && b.Bool()
102 | }
103 | panic("not a number")
104 | }
105 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/suite_test.go:
--------------------------------------------------------------------------------
1 | package yaml_test
2 |
3 | import (
4 | . "gopkg.in/check.v1"
5 | "testing"
6 | )
7 |
8 | func Test(t *testing.T) { TestingT(t) }
9 |
10 | type S struct{}
11 |
12 | var _ = Suite(&S{})
13 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/writerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | // Set the writer error and return false.
4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
5 | emitter.error = yaml_WRITER_ERROR
6 | emitter.problem = problem
7 | return false
8 | }
9 |
10 | // Flush the output buffer.
11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
12 | if emitter.write_handler == nil {
13 | panic("write handler not set")
14 | }
15 |
16 | // Check if the buffer is empty.
17 | if emitter.buffer_pos == 0 {
18 | return true
19 | }
20 |
21 | // If the output encoding is UTF-8, we don't need to recode the buffer.
22 | if emitter.encoding == yaml_UTF8_ENCODING {
23 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
24 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
25 | }
26 | emitter.buffer_pos = 0
27 | return true
28 | }
29 |
30 | // Recode the buffer into the raw buffer.
31 | var low, high int
32 | if emitter.encoding == yaml_UTF16LE_ENCODING {
33 | low, high = 0, 1
34 | } else {
35 | high, low = 1, 0
36 | }
37 |
38 | pos := 0
39 | for pos < emitter.buffer_pos {
40 | // See the "reader.c" code for more details on UTF-8 encoding. Note
41 | // that we assume that the buffer contains a valid UTF-8 sequence.
42 |
43 | // Read the next UTF-8 character.
44 | octet := emitter.buffer[pos]
45 |
46 | var w int
47 | var value rune
48 | switch {
49 | case octet&0x80 == 0x00:
50 | w, value = 1, rune(octet&0x7F)
51 | case octet&0xE0 == 0xC0:
52 | w, value = 2, rune(octet&0x1F)
53 | case octet&0xF0 == 0xE0:
54 | w, value = 3, rune(octet&0x0F)
55 | case octet&0xF8 == 0xF0:
56 | w, value = 4, rune(octet&0x07)
57 | }
58 | for k := 1; k < w; k++ {
59 | octet = emitter.buffer[pos+k]
60 | value = (value << 6) + (rune(octet) & 0x3F)
61 | }
62 | pos += w
63 |
64 | // Write the character.
65 | if value < 0x10000 {
66 | var b [2]byte
67 | b[high] = byte(value >> 8)
68 | b[low] = byte(value & 0xFF)
69 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
70 | } else {
71 | // Write the character using a surrogate pair (check "reader.c").
72 | var b [4]byte
73 | value -= 0x10000
74 | b[high] = byte(0xD8 + (value >> 18))
75 | b[low] = byte((value >> 10) & 0xFF)
76 | b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
77 | b[low+2] = byte(value & 0xFF)
78 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
79 | }
80 | }
81 |
82 | // Write the raw buffer.
83 | if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
84 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
85 | }
86 | emitter.buffer_pos = 0
87 | emitter.raw_buffer = emitter.raw_buffer[:0]
88 | return true
89 | }
90 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/yaml.go:
--------------------------------------------------------------------------------
1 | // Package yaml implements YAML support for the Go language.
2 | //
3 | // Source code and other details for the project are available at GitHub:
4 | //
5 | // https://github.com/go-yaml/yaml
6 | //
7 | package yaml
8 |
9 | import (
10 | "errors"
11 | "fmt"
12 | "reflect"
13 | "strings"
14 | "sync"
15 | )
16 |
17 | // MapSlice encodes and decodes as a YAML map.
18 | // The order of keys is preserved when encoding and decoding.
19 | type MapSlice []MapItem
20 |
21 | // MapItem is an item in a MapSlice.
22 | type MapItem struct {
23 | Key, Value interface{}
24 | }
25 |
26 | // The Unmarshaler interface may be implemented by types to customize their
27 | // behavior when being unmarshaled from a YAML document. The UnmarshalYAML
28 | // method receives a function that may be called to unmarshal the original
29 | // YAML value into a field or variable. It is safe to call the unmarshal
30 | // function parameter more than once if necessary.
31 | type Unmarshaler interface {
32 | UnmarshalYAML(unmarshal func(interface{}) error) error
33 | }
34 |
35 | // The Marshaler interface may be implemented by types to customize their
36 | // behavior when being marshaled into a YAML document. The returned value
37 | // is marshaled in place of the original value implementing Marshaler.
38 | //
39 | // If an error is returned by MarshalYAML, the marshaling procedure stops
40 | // and returns with the provided error.
41 | type Marshaler interface {
42 | MarshalYAML() (interface{}, error)
43 | }
44 |
45 | // Unmarshal decodes the first document found within the in byte slice
46 | // and assigns decoded values into the out value.
47 | //
48 | // Maps and pointers (to a struct, string, int, etc) are accepted as out
49 | // values. If an internal pointer within a struct is not initialized,
50 | // the yaml package will initialize it if necessary for unmarshalling
51 | // the provided data. The out parameter must not be nil.
52 | //
53 | // The type of the decoded values should be compatible with the respective
54 | // values in out. If one or more values cannot be decoded due to a type
55 | // mismatches, decoding continues partially until the end of the YAML
56 | // content, and a *yaml.TypeError is returned with details for all
57 | // missed values.
58 | //
59 | // Struct fields are only unmarshalled if they are exported (have an
60 | // upper case first letter), and are unmarshalled using the field name
61 | // lowercased as the default key. Custom keys may be defined via the
62 | // "yaml" name in the field tag: the content preceding the first comma
63 | // is used as the key, and the following comma-separated options are
64 | // used to tweak the marshalling process (see Marshal).
65 | // Conflicting names result in a runtime error.
66 | //
67 | // For example:
68 | //
69 | // type T struct {
70 | // F int `yaml:"a,omitempty"`
71 | // B int
72 | // }
73 | // var t T
74 | // yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
75 | //
76 | // See the documentation of Marshal for the format of tags and a list of
77 | // supported tag options.
78 | //
79 | func Unmarshal(in []byte, out interface{}) (err error) {
80 | defer handleErr(&err)
81 | d := newDecoder()
82 | p := newParser(in)
83 | defer p.destroy()
84 | node := p.parse()
85 | if node != nil {
86 | v := reflect.ValueOf(out)
87 | if v.Kind() == reflect.Ptr && !v.IsNil() {
88 | v = v.Elem()
89 | }
90 | d.unmarshal(node, v)
91 | }
92 | if len(d.terrors) > 0 {
93 | return &TypeError{d.terrors}
94 | }
95 | return nil
96 | }
97 |
98 | // Marshal serializes the value provided into a YAML document. The structure
99 | // of the generated document will reflect the structure of the value itself.
100 | // Maps and pointers (to struct, string, int, etc) are accepted as the in value.
101 | //
102 | // Struct fields are only unmarshalled if they are exported (have an upper case
103 | // first letter), and are unmarshalled using the field name lowercased as the
104 | // default key. Custom keys may be defined via the "yaml" name in the field
105 | // tag: the content preceding the first comma is used as the key, and the
106 | // following comma-separated options are used to tweak the marshalling process.
107 | // Conflicting names result in a runtime error.
108 | //
109 | // The field tag format accepted is:
110 | //
111 | // `(...) yaml:"[][,[,]]" (...)`
112 | //
113 | // The following flags are currently supported:
114 | //
115 | // omitempty Only include the field if it's not set to the zero
116 | // value for the type or to empty slices or maps.
117 | // Does not apply to zero valued structs.
118 | //
119 | // flow Marshal using a flow style (useful for structs,
120 | // sequences and maps).
121 | //
122 | // inline Inline the field, which must be a struct or a map,
123 | // causing all of its fields or keys to be processed as if
124 | // they were part of the outer struct. For maps, keys must
125 | // not conflict with the yaml keys of other struct fields.
126 | //
127 | // In addition, if the key is "-", the field is ignored.
128 | //
129 | // For example:
130 | //
131 | // type T struct {
132 | // F int "a,omitempty"
133 | // B int
134 | // }
135 | // yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
136 | // yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
137 | //
138 | func Marshal(in interface{}) (out []byte, err error) {
139 | defer handleErr(&err)
140 | e := newEncoder()
141 | defer e.destroy()
142 | e.marshal("", reflect.ValueOf(in))
143 | e.finish()
144 | out = e.out
145 | return
146 | }
147 |
148 | func handleErr(err *error) {
149 | if v := recover(); v != nil {
150 | if e, ok := v.(yamlError); ok {
151 | *err = e.err
152 | } else {
153 | panic(v)
154 | }
155 | }
156 | }
157 |
158 | type yamlError struct {
159 | err error
160 | }
161 |
162 | func fail(err error) {
163 | panic(yamlError{err})
164 | }
165 |
166 | func failf(format string, args ...interface{}) {
167 | panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
168 | }
169 |
170 | // A TypeError is returned by Unmarshal when one or more fields in
171 | // the YAML document cannot be properly decoded into the requested
172 | // types. When this error is returned, the value is still
173 | // unmarshaled partially.
174 | type TypeError struct {
175 | Errors []string
176 | }
177 |
178 | func (e *TypeError) Error() string {
179 | return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
180 | }
181 |
182 | // --------------------------------------------------------------------------
183 | // Maintain a mapping of keys to structure field indexes
184 |
185 | // The code in this section was copied from mgo/bson.
186 |
187 | // structInfo holds details for the serialization of fields of
188 | // a given struct.
189 | type structInfo struct {
190 | FieldsMap map[string]fieldInfo
191 | FieldsList []fieldInfo
192 |
193 | // InlineMap is the number of the field in the struct that
194 | // contains an ,inline map, or -1 if there's none.
195 | InlineMap int
196 | }
197 |
198 | type fieldInfo struct {
199 | Key string
200 | Num int
201 | OmitEmpty bool
202 | Flow bool
203 |
204 | // Inline holds the field index if the field is part of an inlined struct.
205 | Inline []int
206 | }
207 |
208 | var structMap = make(map[reflect.Type]*structInfo)
209 | var fieldMapMutex sync.RWMutex
210 |
211 | func getStructInfo(st reflect.Type) (*structInfo, error) {
212 | fieldMapMutex.RLock()
213 | sinfo, found := structMap[st]
214 | fieldMapMutex.RUnlock()
215 | if found {
216 | return sinfo, nil
217 | }
218 |
219 | n := st.NumField()
220 | fieldsMap := make(map[string]fieldInfo)
221 | fieldsList := make([]fieldInfo, 0, n)
222 | inlineMap := -1
223 | for i := 0; i != n; i++ {
224 | field := st.Field(i)
225 | if field.PkgPath != "" {
226 | continue // Private field
227 | }
228 |
229 | info := fieldInfo{Num: i}
230 |
231 | tag := field.Tag.Get("yaml")
232 | if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
233 | tag = string(field.Tag)
234 | }
235 | if tag == "-" {
236 | continue
237 | }
238 |
239 | inline := false
240 | fields := strings.Split(tag, ",")
241 | if len(fields) > 1 {
242 | for _, flag := range fields[1:] {
243 | switch flag {
244 | case "omitempty":
245 | info.OmitEmpty = true
246 | case "flow":
247 | info.Flow = true
248 | case "inline":
249 | inline = true
250 | default:
251 | return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
252 | }
253 | }
254 | tag = fields[0]
255 | }
256 |
257 | if inline {
258 | switch field.Type.Kind() {
259 | case reflect.Map:
260 | if inlineMap >= 0 {
261 | return nil, errors.New("Multiple ,inline maps in struct " + st.String())
262 | }
263 | if field.Type.Key() != reflect.TypeOf("") {
264 | return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
265 | }
266 | inlineMap = info.Num
267 | case reflect.Struct:
268 | sinfo, err := getStructInfo(field.Type)
269 | if err != nil {
270 | return nil, err
271 | }
272 | for _, finfo := range sinfo.FieldsList {
273 | if _, found := fieldsMap[finfo.Key]; found {
274 | msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
275 | return nil, errors.New(msg)
276 | }
277 | if finfo.Inline == nil {
278 | finfo.Inline = []int{i, finfo.Num}
279 | } else {
280 | finfo.Inline = append([]int{i}, finfo.Inline...)
281 | }
282 | fieldsMap[finfo.Key] = finfo
283 | fieldsList = append(fieldsList, finfo)
284 | }
285 | default:
286 | //return nil, errors.New("Option ,inline needs a struct value or map field")
287 | return nil, errors.New("Option ,inline needs a struct value field")
288 | }
289 | continue
290 | }
291 |
292 | if tag != "" {
293 | info.Key = tag
294 | } else {
295 | info.Key = strings.ToLower(field.Name)
296 | }
297 |
298 | if _, found = fieldsMap[info.Key]; found {
299 | msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
300 | return nil, errors.New(msg)
301 | }
302 |
303 | fieldsList = append(fieldsList, info)
304 | fieldsMap[info.Key] = info
305 | }
306 |
307 | sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
308 |
309 | fieldMapMutex.Lock()
310 | structMap[st] = sinfo
311 | fieldMapMutex.Unlock()
312 | return sinfo, nil
313 | }
314 |
315 | func isZero(v reflect.Value) bool {
316 | switch v.Kind() {
317 | case reflect.String:
318 | return len(v.String()) == 0
319 | case reflect.Interface, reflect.Ptr:
320 | return v.IsNil()
321 | case reflect.Slice:
322 | return v.Len() == 0
323 | case reflect.Map:
324 | return v.Len() == 0
325 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
326 | return v.Int() == 0
327 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
328 | return v.Uint() == 0
329 | case reflect.Bool:
330 | return !v.Bool()
331 | case reflect.Struct:
332 | vt := v.Type()
333 | for i := v.NumField()-1; i >= 0; i-- {
334 | if vt.Field(i).PkgPath != "" {
335 | continue // Private field
336 | }
337 | if !isZero(v.Field(i)) {
338 | return false
339 | }
340 | }
341 | return true
342 | }
343 | return false
344 | }
345 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/gopkg.in/yaml.v2/yamlprivateh.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | const (
4 | // The size of the input raw buffer.
5 | input_raw_buffer_size = 512
6 |
7 | // The size of the input buffer.
8 | // It should be possible to decode the whole raw buffer.
9 | input_buffer_size = input_raw_buffer_size * 3
10 |
11 | // The size of the output buffer.
12 | output_buffer_size = 128
13 |
14 | // The size of the output raw buffer.
15 | // It should be possible to encode the whole output buffer.
16 | output_raw_buffer_size = (output_buffer_size*2 + 2)
17 |
18 | // The size of other stacks and queues.
19 | initial_stack_size = 16
20 | initial_queue_size = 16
21 | initial_string_size = 16
22 | )
23 |
24 | // Check if the character at the specified position is an alphabetical
25 | // character, a digit, '_', or '-'.
26 | func is_alpha(b []byte, i int) bool {
27 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
28 | }
29 |
30 | // Check if the character at the specified position is a digit.
31 | func is_digit(b []byte, i int) bool {
32 | return b[i] >= '0' && b[i] <= '9'
33 | }
34 |
35 | // Get the value of a digit.
36 | func as_digit(b []byte, i int) int {
37 | return int(b[i]) - '0'
38 | }
39 |
40 | // Check if the character at the specified position is a hex-digit.
41 | func is_hex(b []byte, i int) bool {
42 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
43 | }
44 |
45 | // Get the value of a hex-digit.
46 | func as_hex(b []byte, i int) int {
47 | bi := b[i]
48 | if bi >= 'A' && bi <= 'F' {
49 | return int(bi) - 'A' + 10
50 | }
51 | if bi >= 'a' && bi <= 'f' {
52 | return int(bi) - 'a' + 10
53 | }
54 | return int(bi) - '0'
55 | }
56 |
57 | // Check if the character is ASCII.
58 | func is_ascii(b []byte, i int) bool {
59 | return b[i] <= 0x7F
60 | }
61 |
62 | // Check if the character at the start of the buffer can be printed unescaped.
63 | func is_printable(b []byte, i int) bool {
64 | return ((b[i] == 0x0A) || // . == #x0A
65 | (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
66 | (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
67 | (b[i] > 0xC2 && b[i] < 0xED) ||
68 | (b[i] == 0xED && b[i+1] < 0xA0) ||
69 | (b[i] == 0xEE) ||
70 | (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
71 | !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
72 | !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
73 | }
74 |
75 | // Check if the character at the specified position is NUL.
76 | func is_z(b []byte, i int) bool {
77 | return b[i] == 0x00
78 | }
79 |
80 | // Check if the beginning of the buffer is a BOM.
81 | func is_bom(b []byte, i int) bool {
82 | return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
83 | }
84 |
85 | // Check if the character at the specified position is space.
86 | func is_space(b []byte, i int) bool {
87 | return b[i] == ' '
88 | }
89 |
90 | // Check if the character at the specified position is tab.
91 | func is_tab(b []byte, i int) bool {
92 | return b[i] == '\t'
93 | }
94 |
95 | // Check if the character at the specified position is blank (space or tab).
96 | func is_blank(b []byte, i int) bool {
97 | //return is_space(b, i) || is_tab(b, i)
98 | return b[i] == ' ' || b[i] == '\t'
99 | }
100 |
101 | // Check if the character at the specified position is a line break.
102 | func is_break(b []byte, i int) bool {
103 | return (b[i] == '\r' || // CR (#xD)
104 | b[i] == '\n' || // LF (#xA)
105 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
106 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
107 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
108 | }
109 |
110 | func is_crlf(b []byte, i int) bool {
111 | return b[i] == '\r' && b[i+1] == '\n'
112 | }
113 |
114 | // Check if the character is a line break or NUL.
115 | func is_breakz(b []byte, i int) bool {
116 | //return is_break(b, i) || is_z(b, i)
117 | return ( // is_break:
118 | b[i] == '\r' || // CR (#xD)
119 | b[i] == '\n' || // LF (#xA)
120 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
121 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
122 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
123 | // is_z:
124 | b[i] == 0)
125 | }
126 |
127 | // Check if the character is a line break, space, or NUL.
128 | func is_spacez(b []byte, i int) bool {
129 | //return is_space(b, i) || is_breakz(b, i)
130 | return ( // is_space:
131 | b[i] == ' ' ||
132 | // is_breakz:
133 | b[i] == '\r' || // CR (#xD)
134 | b[i] == '\n' || // LF (#xA)
135 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
136 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
137 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
138 | b[i] == 0)
139 | }
140 |
141 | // Check if the character is a line break, space, tab, or NUL.
142 | func is_blankz(b []byte, i int) bool {
143 | //return is_blank(b, i) || is_breakz(b, i)
144 | return ( // is_blank:
145 | b[i] == ' ' || b[i] == '\t' ||
146 | // is_breakz:
147 | b[i] == '\r' || // CR (#xD)
148 | b[i] == '\n' || // LF (#xA)
149 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
150 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
151 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
152 | b[i] == 0)
153 | }
154 |
155 | // Determine the width of the character.
156 | func width(b byte) int {
157 | // Don't replace these by a switch without first
158 | // confirming that it is being inlined.
159 | if b&0x80 == 0x00 {
160 | return 1
161 | }
162 | if b&0xE0 == 0xC0 {
163 | return 2
164 | }
165 | if b&0xF0 == 0xE0 {
166 | return 3
167 | }
168 | if b&0xF8 == 0xF0 {
169 | return 4
170 | }
171 | return 0
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2015-2018 – Baptiste Fontaine
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SRCS=main.go $(wildcard httpdoc/*.go)
2 |
3 | bin/httpdoc: $(SRCS)
4 | go build -o $@ .
5 |
6 | check:
7 | go vet ./...
8 | go test -v ./...
9 |
10 | lint:
11 | golint ./...
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # httpdoc
2 |
3 | **httpdoc** gives you direct access to HTTP documentation straight from
4 | your terminal.
5 |
6 | [](https://godoc.org/github.com/bfontaine/httpdoc)
7 | [](https://travis-ci.org/bfontaine/httpdoc)
8 |
9 | ## Usage
10 |
11 | httpdoc
12 |
13 | ### Examples
14 |
15 | $ httpdoc 200 # => Doc about the status code
16 | $ httpdoc content-type # => Doc about the header field
17 |
18 | ## Install
19 |
20 | go get github.com/bfontaine/httpdoc
21 |
22 | `httpdoc` requires Go 1.2+.
23 |
24 | ### Using Homebrew
25 |
26 | If you use [Homebrew](http://brew.sh) or [Linuxbrew](http://linuxbrew.sh/) you
27 | can install `httpdoc` with one command:
28 |
29 | ```
30 | brew install bfontaine/utils/httpdoc
31 | ```
32 |
33 | ## Go API
34 |
35 | ```go
36 | import (
37 | "fmt"
38 | "github.com/bfontaine/httpdoc/httpdoc"
39 | )
40 |
41 | doc := httpdoc.DefaultDoc
42 | code, _ := doc.GetStatusCode("200")
43 | fmt.Println(code.PrettyString())
44 | ```
45 |
46 | ## Support
47 |
48 | | Resources | Support |
49 | |------------------------------|:-------:|
50 | | Standard status codes | ✔ |
51 | | Standard header fields | ✔ |
52 | | Standard methods | ✔ |
53 |
54 | ## See Also
55 |
56 | * [`rfc`][rfc-cli]: read RFCs in your terminal
57 |
58 | [rfc-cli]: https://github.com/bfontaine/rfc#rfc
59 |
--------------------------------------------------------------------------------
/_docs/methods.yml:
--------------------------------------------------------------------------------
1 | # main sources:
2 | # - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
3 | "OPTIONS":
4 | desc: |
5 | The OPTIONS method represents a request for information about the
6 | communication options available on the request/response chain identified by
7 | the URI. This method allows the client to determine the options and/or
8 | requirements associated with a resource, or the capabilities of a server,
9 | without implying a resource action or initiating a resource retrieval.
10 | refs:
11 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2
12 | "GET":
13 | desc: |
14 | The GET method means retrieve whatever information (in the form of an
15 | entity) is identified by the URI. If the URI refers to a data-producing
16 | process, it is the produced data which shall be returned as the entity in
17 | the response and not the source text of the process, unless that text
18 | happens to be the output of the process.
19 | refs:
20 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
21 | "HEAD":
22 | desc: |
23 | The HEAD method is identical to GET except that the server must not return
24 | a body in the response. The metainformation contained in the HTTP headers
25 | in response to a HEAD request should be identical to the information sent
26 | in response to a GET request. This method can be used for obtaining
27 | metainformation about the entity implied by the request without
28 | transferring the entity-body itself. This method is often used for testing
29 | hypertext links for validity, accessibility, and recent modification.
30 | refs:
31 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
32 | "POST":
33 | desc: |
34 | The POST method is used to request that the server accept the entity
35 | enclosed in the request as a new subordinate of the resource identified by
36 | the URI in the Request-Line. POST is designed to allow a uniform method to
37 | cover the following functions:
38 |
39 | - Annotation of existing resources;
40 | - Posting a message to a bulletin board, newsgroup, mailing list,
41 | or similar group of articles;
42 | - Providing a block of data, such as the result of submitting a
43 | form, to a data-handling process;
44 | - Extending a database through an append operation.
45 |
46 | The actual function performed by the POST method is determined by the
47 | server and is usually dependent on the Request-URI. The posted entity is
48 | subordinate to that URI in the same way that a file is subordinate to a
49 | directory containing it, a news article is subordinate to a newsgroup to
50 | which it is posted, or a record is subordinate to a database.
51 |
52 | The action performed by the POST method might not result in a resource that
53 | can be identified by a URI. In this case, either 200 (OK) or 204 (No
54 | Content) is the appropriate response status, depending on whether or not
55 | the response includes an entity that describes the result.
56 |
57 | If a resource has been created on the origin server, the response SHOULD be
58 | 201 (Created) and contain an entity which describes the status of the
59 | request and refers to the new resource, and a Location header (see section
60 | 14.30).
61 | refs:
62 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5
63 | "PUT":
64 | desc: |
65 | The PUT method requests that the enclosed entity be stored under the
66 | supplied URI. If the URI refers to an already existing resource, the
67 | enclosed entity should be considered as a modified version of the one
68 | residing on the server.
69 | refs:
70 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
71 | "DELETE":
72 | desc: |
73 | The DELETE method requests that the server delete the resource identified
74 | by the URI. This method may be overridden by human intervention (or other
75 | means) on the server. The client cannot be guaranteed that the operation
76 | has been carried out, even if the status code returned from the origin
77 | server indicates that the action has been completed successfully. However,
78 | the server should not indicate success unless, at the time the response is
79 | given, it intends to delete the resource or move it to an inaccessible
80 | location.
81 |
82 | A successful response SHOULD be 200 (OK) if the response includes an entity
83 | describing the status, 202 (Accepted) if the action has not yet been
84 | enacted, or 204 (No Content) if the action has been enacted but the
85 | response does not include an entity.
86 | refs:
87 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7
88 | "TRACE":
89 | desc: |
90 | The TRACE method is used to invoke a remote, application-layer loop-back
91 | of the request message. The final recipient of the request SHOULD reflect
92 | the message received back to the client as the entity-body of a 200 (OK)
93 | response. The final recipient is either the server or the first proxy or
94 | gateway to receive a Max-Forwards value of zero (0) in the request. A TRACE
95 | request must not include an entity.
96 |
97 | TRACE allows the client to see what is being received at the other end of
98 | the request chain and use that data for testing or diagnostic information.
99 | The value of the Via header field is of particular interest, since it acts
100 | as a trace of the request chain. Use of the Max-Forwards header field
101 | allows the client to limit the length of the request chain, which is useful
102 | for testing a chain of proxies forwarding messages in an infinite loop.
103 |
104 | If the request is valid, the response should contain the entire request
105 | message in the body, with a Content-Type of "message/http".
106 | refs:
107 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8
108 | "CONNECT":
109 | desc: |
110 | This specification reserves the method name CONNECT for use with a proxy
111 | that can dynamically switch to being a tunnel (e.g. SSL tunneling).
112 | refs:
113 | - http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.9
114 | "PATCH":
115 | desc: |
116 | The PATCH method requests that a set of changes described in the request
117 | entity be applied to the resource identified by the URI. The set of changes
118 | is represented in a format called a "patch document" identified by a media
119 | type. If the URI does not point to an existing resource, the server may
120 | create a new resource, depending on the patch document type, permissions,
121 | etc.
122 | The difference between the PUT and PATCH methods is reflected in the way
123 | the server processes the enclosed entity to modify the resource identified
124 | by the URI. In a PUT request, the enclosed entity is considered to be a
125 | modified version of the resource stored on the server, and the client is
126 | requesting that the stored version be replaced. With PATCH, however, the
127 | enclosed entity contains a set of instructions describing how a resource on
128 | the server should be modified to produce a new version. The PATCH method
129 | affects the resource identified by the URI, and it also may have side
130 | effects on other resources; i.e., new resources may be created, or existing
131 | ones modified, by the application of a PATCH.
132 | refs:
133 | - http://tools.ietf.org/html/rfc5789#section-2
134 |
--------------------------------------------------------------------------------
/httpdoc/codes.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | // A StatusCode is an HTTP status code
9 | type StatusCode struct {
10 | // Code is its actual code (e.g. "200")
11 | Code string
12 |
13 | // Text is a short text describing the status code (e.g. "OK")
14 | Text string
15 |
16 | // Desc is an human-readable description of the status code
17 | Desc string
18 |
19 | // Refs are some references for the reader
20 | Refs []string
21 | }
22 |
23 | const (
24 | codesSource = "codes.yml"
25 | )
26 |
27 | func (d Doc) parseStatusCodes() (m map[string]StatusCode, err error) {
28 | m = make(map[string]StatusCode)
29 | err = d.loadSource(codesSource, m)
30 |
31 | return m, err
32 | }
33 |
34 | // GetStatusCode gets a code and returns a new StatusCode struct describing it.
35 | // If it can’t find the code an ErrUnknownStatusCode is returned.
36 | func (d Doc) GetStatusCode(code string) (c StatusCode, err error) {
37 | codes, err := d.parseStatusCodes()
38 | if err != nil {
39 | return
40 | }
41 |
42 | c, ok := codes[code]
43 | if !ok {
44 | err = ErrUnknownStatusCode
45 | }
46 |
47 | c.Code = code
48 |
49 | return
50 | }
51 |
52 | func (c StatusCode) String() string {
53 | return fmt.Sprintf("%s %s", c.Code, c.Text)
54 | }
55 |
56 | // PrettyString returns a string describing the status code with a long
57 | // description and a references list.
58 | func (c StatusCode) PrettyString() string {
59 | return fmt.Sprintf("%s %s\n\n%s\n\nReferences:\n * %s\n",
60 | c.Code, c.Text,
61 | c.Desc,
62 | strings.Join(c.Refs, "\n * "),
63 | )
64 | }
65 |
--------------------------------------------------------------------------------
/httpdoc/codes_test.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestValidCode(t *testing.T) {
10 | s, err := DefaultDoc.GetStatusCode("200")
11 |
12 | assert.Nil(t, err)
13 | assert.Equal(t, s.Code, "200")
14 | assert.Equal(t, s.Text, "OK")
15 | }
16 |
17 | func TestInValidCode(t *testing.T) {
18 | _, err := DefaultDoc.GetStatusCode("123")
19 |
20 | assert.Equal(t, err, ErrUnknownStatusCode)
21 | }
22 |
--------------------------------------------------------------------------------
/httpdoc/doc.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "go/build"
5 | "io/ioutil"
6 | "path/filepath"
7 | "strings"
8 |
9 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/gopkg.in/yaml.v2"
10 | )
11 |
12 | // Doc represents a documentation source
13 | type Doc struct {
14 | // the root dir in which are the documentation files
15 | RootDir string
16 | }
17 |
18 | // DefaultDoc is a Doc which assumes you installed the binary/library using
19 | // `go get`.
20 | var DefaultDoc Doc
21 |
22 | func (d Doc) loadSource(filename string, target interface{}) (err error) {
23 | var data []byte
24 |
25 | path := filepath.Join(d.RootDir, filename)
26 |
27 | data, err = ioutil.ReadFile(path)
28 | if err != nil {
29 | return
30 | }
31 |
32 | return yaml.Unmarshal(data, target)
33 | }
34 |
35 | func defaultDocDir() string {
36 | gopath := strings.SplitN(build.Default.GOPATH, ":", 2)[0]
37 |
38 | return filepath.Join(gopath, "src",
39 | "github.com", "bfontaine", "httpdoc", "_docs")
40 | }
41 |
42 | func init() {
43 | // set the default doc
44 | DefaultDoc = Doc{RootDir: defaultDocDir()}
45 | }
46 |
47 | // This should be kept ordered
48 | var methods = [...]string{
49 | "CONNECT",
50 | "DELETE",
51 | "GET",
52 | "HEAD",
53 | "OPTIONS",
54 | "PATCH",
55 | "POST",
56 | "PUT",
57 | "TRACE",
58 | }
59 |
60 | // GetResourceFor gets a name and tries to find a corresponding resource. It'll
61 | // return ErrUnknownResource if it can’t find it.
62 | func (d Doc) GetResourceFor(name string) (Resource, error) {
63 | if name == "" {
64 | return InvalidResource, ErrUnknownResource
65 | }
66 |
67 | // simple heuristic
68 | if name[0] >= '0' && name[0] <= '9' {
69 | return d.GetStatusCode(name)
70 | }
71 |
72 | uppercaseName := strings.ToUpper(name)
73 |
74 | for i := 0; i < len(methods); i++ {
75 | if methods[i] == uppercaseName {
76 | return d.GetMethod(uppercaseName)
77 | }
78 | }
79 |
80 | r, err := d.GetHeader(name)
81 |
82 | if err == ErrUnknownHeader {
83 | err = ErrUnknownResource
84 | }
85 |
86 | return r, err
87 | }
88 |
--------------------------------------------------------------------------------
/httpdoc/doc_test.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 |
7 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/github.com/stretchr/testify/assert"
8 | "github.com/bfontaine/httpdoc/Godeps/_workspace/src/github.com/stretchr/testify/require"
9 | )
10 |
11 | func TestDefaultDocRootDir(t *testing.T) {
12 | assert.NotEqual(t, DefaultDoc.RootDir, "")
13 | }
14 |
15 | func TestDocRecognizeStatus(t *testing.T) {
16 | s, err := DefaultDoc.GetResourceFor("304")
17 |
18 | require.Nil(t, err)
19 |
20 | switch s.(type) {
21 | case StatusCode:
22 | // success
23 | default:
24 | t.Fatal("GetResourceFor(\"304\") should return a StatusCode")
25 | }
26 |
27 | assert.Equal(t, "304", s.(StatusCode).Code)
28 | }
29 |
30 | func TestDocRecognizeMethod(t *testing.T) {
31 | s, err := DefaultDoc.GetResourceFor("options")
32 |
33 | require.Nil(t, err)
34 |
35 | switch s.(type) {
36 | case Method:
37 | // success
38 | default:
39 | t.Fatal("GetResourceFor(\"options\") should return a Method")
40 | }
41 |
42 | assert.Equal(t, "OPTIONS", s.(Method).Verb)
43 | }
44 |
45 | func TestDocRecognizeAllMethods(t *testing.T) {
46 | check := func(name, expected string) {
47 | s, err := DefaultDoc.GetResourceFor(name)
48 | require.Nil(t, err,
49 | fmt.Sprintf("GetResourceFor(%s) shouldn't return an error", name))
50 | assert.Equal(t, expected, s.(Method).Verb,
51 | fmt.Sprintf("GetResourceFor(%s) should return %s", name, expected))
52 | }
53 |
54 | check("connect", "CONNECT")
55 | check("delete", "DELETE")
56 | check("get", "GET")
57 | check("head", "HEAD")
58 | check("options", "OPTIONS")
59 | check("patch", "PATCH")
60 | check("post", "POST")
61 | check("put", "PUT")
62 | check("trace", "TRACE")
63 | }
64 |
65 | func TestDocRecognizeHeader(t *testing.T) {
66 | s, err := DefaultDoc.GetResourceFor("te")
67 |
68 | require.Nil(t, err)
69 |
70 | switch s.(type) {
71 | case Header:
72 | // success
73 | default:
74 | t.Fatal("GetResourceFor(\"te\") should return a Header")
75 | }
76 |
77 | assert.Equal(t, "TE", s.(Header).Text)
78 | }
79 |
--------------------------------------------------------------------------------
/httpdoc/errors.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import "errors"
4 |
5 | var (
6 | // ErrUnknownResource is returned by GetResourceFor if it can’t find a
7 | // resource
8 | ErrUnknownResource = errors.New("Unknown resource")
9 |
10 | // ErrUnknownStatusCode is returned by GetStatusCode if it can’t find a
11 | // status code
12 | ErrUnknownStatusCode = errors.New("Unknown status code")
13 |
14 | // ErrUnknownHeader is returned by GetHeader if it can’t find an header
15 | // field
16 | ErrUnknownHeader = errors.New("Unknown header field")
17 |
18 | // ErrUnknownMethod is returned by GetMethod if it can’t find a method
19 | ErrUnknownMethod = errors.New("Unknown method")
20 | )
21 |
--------------------------------------------------------------------------------
/httpdoc/headers.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | // Header is an HTTP header field
9 | type Header struct {
10 | // Type is either "request", "response", or "both"
11 | Type string
12 |
13 | // Text is the header’s text
14 | Text string
15 |
16 | // Desc is an human-readable description of the header
17 | Desc string
18 |
19 | // Refs are some references for the reader
20 | Refs []string
21 | }
22 |
23 | const (
24 | headersSource = "headers.yml"
25 | )
26 |
27 | func (d Doc) parseHeaders() (m map[string]Header, err error) {
28 | m = make(map[string]Header)
29 | err = d.loadSource(headersSource, m)
30 |
31 | return m, err
32 | }
33 |
34 | // GetHeader returns a Header
35 | func (d Doc) GetHeader(name string) (h Header, err error) {
36 | headers, err := d.parseHeaders()
37 | if err != nil {
38 | return
39 | }
40 |
41 | // normalize the name
42 | if len(name) > 2 {
43 | name = strings.Title(strings.ToLower(name))
44 | } else {
45 | name = strings.ToUpper(name)
46 | }
47 |
48 | h, ok := headers[name]
49 | if !ok {
50 | err = ErrUnknownHeader
51 | }
52 |
53 | h.Text = name
54 |
55 | return
56 | }
57 |
58 | func (h Header) String() string {
59 | return h.Text
60 | }
61 |
62 | // PrettyString returns an human-readable description of the header
63 | func (h Header) PrettyString() string {
64 | t := h.Type
65 | if t == "both" {
66 | t = "request and response"
67 | }
68 |
69 | return fmt.Sprintf("%s (%s field)\n\n%s\n\nReferences:\n * %s\n",
70 | h.Text,
71 | t,
72 | h.Desc,
73 | strings.Join(h.Refs, "\n * "),
74 | )
75 | }
76 |
--------------------------------------------------------------------------------
/httpdoc/methods.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | // Method is an HTTP method
9 | type Method struct {
10 | // Verb is the method’s verb
11 | Verb string
12 |
13 | // Desc is an human-readable description of the method
14 | Desc string
15 |
16 | // Refs are some references for the reader
17 | Refs []string
18 | }
19 |
20 | const (
21 | methodsSource = "methods.yml"
22 | )
23 |
24 | func (d Doc) parseMethods() (m map[string]Method, err error) {
25 | m = make(map[string]Method)
26 | err = d.loadSource(methodsSource, m)
27 |
28 | return m, err
29 | }
30 |
31 | // GetMethod returns a Method from its verb
32 | func (d Doc) GetMethod(name string) (m Method, err error) {
33 | methods, err := d.parseMethods()
34 | if err != nil {
35 | return
36 | }
37 |
38 | name = strings.ToUpper(name)
39 |
40 | m, ok := methods[name]
41 | if !ok {
42 | err = ErrUnknownMethod
43 | }
44 |
45 | m.Verb = name
46 |
47 | return
48 | }
49 |
50 | func (m Method) String() string {
51 | return m.Verb
52 | }
53 |
54 | // PrettyString returns an human-readable description of this method
55 | func (m Method) PrettyString() string {
56 | return fmt.Sprintf("%s\n\n%s\n\nReferences:\n * %s\n",
57 | m.Verb,
58 | m.Desc,
59 | strings.Join(m.Refs, "\n * "),
60 | )
61 | }
62 |
--------------------------------------------------------------------------------
/httpdoc/resource.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | // A Resource is a documented resource
4 | type Resource interface {
5 | String() string
6 |
7 | // PrettyString is intended as a more verbose `String()` for user display
8 | PrettyString() string
9 | }
10 |
11 | // NilResource is an empty resource
12 | type NilResource struct{}
13 |
14 | // PrettyString returns an empty string
15 | func (n NilResource) PrettyString() string { return "" }
16 | func (n NilResource) String() string { return "" }
17 |
18 | // InvalidResource is returned by some functions where a Resource is needed but
19 | // no one can be found
20 | var InvalidResource NilResource
21 |
--------------------------------------------------------------------------------
/httpdoc/version.go:
--------------------------------------------------------------------------------
1 | package httpdoc
2 |
3 | // Version is the current version of the package
4 | const Version = "0.1.0"
5 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "os"
7 |
8 | "github.com/bfontaine/httpdoc/httpdoc"
9 | )
10 |
11 | func printUsage() {
12 | fmt.Fprintf(os.Stderr, "Usage:\n %s [] \n\n", os.Args[0])
13 | fmt.Fprintln(os.Stderr, "Where are:")
14 | flag.PrintDefaults()
15 | }
16 |
17 | func main() {
18 | var doc httpdoc.Doc
19 |
20 | var versionFlag bool
21 |
22 | flag.StringVar(&doc.RootDir, "root-dir", "",
23 | "Documentation root directory")
24 | flag.BoolVar(&versionFlag, "version", false,
25 | "Show the current version and exit")
26 |
27 | flag.Parse()
28 |
29 | args := flag.Args()
30 |
31 | if versionFlag {
32 | fmt.Println(httpdoc.Version)
33 | return
34 | }
35 |
36 | if len(args) != 1 {
37 | printUsage()
38 | os.Exit(1)
39 | }
40 |
41 | if doc.RootDir == "" {
42 | doc = httpdoc.DefaultDoc
43 | }
44 |
45 | if res, err := doc.GetResourceFor(args[0]); err != nil {
46 | fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
47 | os.Exit(1)
48 | } else {
49 | fmt.Printf("%s\n", res.PrettyString())
50 | }
51 | }
52 |
--------------------------------------------------------------------------------