├── .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 | [![GoDoc](https://godoc.org/github.com/bfontaine/httpdoc?status.svg)](https://godoc.org/github.com/bfontaine/httpdoc) 7 | [![Build Status](https://travis-ci.org/bfontaine/httpdoc.svg?branch=master)](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 | --------------------------------------------------------------------------------