mirror of
https://github.com/minio/minio.git
synced 2024-12-26 23:25:54 -05:00
Merge pull request #796 from harshavardhana/migrate-to-govendor
Migrate to govendor to avoid limitations of godep
This commit is contained in:
commit
e4dc8ee7b4
@ -18,8 +18,7 @@ $ make
|
||||
Checking if proper environment variables are set.. Done
|
||||
...
|
||||
Checking dependencies for Minio.. Done
|
||||
Installed godep
|
||||
Installed cover
|
||||
Installed govet
|
||||
Building Libraries
|
||||
...
|
||||
...
|
||||
@ -37,8 +36,7 @@ $ make
|
||||
Checking if proper environment variables are set.. Done
|
||||
...
|
||||
Checking dependencies for Minio.. Done
|
||||
Installed godep
|
||||
Installed cover
|
||||
Installed govet
|
||||
Building Libraries
|
||||
...
|
||||
```
|
||||
@ -52,20 +50,17 @@ Building Libraries
|
||||
- Push to the branch (git push origin my-new-feature)
|
||||
- Create new Pull Request
|
||||
|
||||
* If you have additional dependencies for ``Minio``, ``Minio`` manages its depedencies using [godep](https://github.com/tools/godep)
|
||||
* If you have additional dependencies for ``Minio``, ``Minio`` manages its depedencies using [govendor](https://github.com/kardianos/govendor)
|
||||
- Run `go get foo/bar`
|
||||
- Edit your code to import foo/bar
|
||||
- Run `make save` from top-level directory (or `godep restore && godep save ./...`).
|
||||
- Run `govendor add foo/bar` from top-level directory
|
||||
|
||||
* When you're ready to create a pull request, be sure to:
|
||||
- Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
|
||||
- Run `go fmt
|
||||
- Run `golint`
|
||||
```
|
||||
$ go get github.com/golang/lint/golint
|
||||
$ golint ./...
|
||||
```
|
||||
- Run `make verifiers`
|
||||
- Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
|
||||
- Make sure `go test -race ./...` and `go build` completes.
|
||||
|
||||
* Read [Effective Go](https://github.com/golang/go/wiki/CodeReviewComments) article from Golang project
|
||||
- `Minio` project is strictly conformant with Golang style
|
||||
- `Minio` project is fully conformant with Golang style
|
||||
- if you happen to observe offending code, please feel free to send a pull request
|
||||
|
50
Godeps/Godeps.json
generated
50
Godeps/Godeps.json
generated
@ -1,50 +0,0 @@
|
||||
{
|
||||
"ImportPath": "github.com/minio/minio",
|
||||
"GoVersion": "go1.4.2",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/dustin/go-humanize",
|
||||
"Rev": "8cc1aaa2d955ee82833337cfb10babc42be6bce6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/facebookgo/clock",
|
||||
"Rev": "600d898af40aa09a7a93ecb9265d87b0504b6f03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/facebookgo/httpdown",
|
||||
"Rev": "3d94c3159d8ba15fa8e9499134ccc0d8acf6adb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/facebookgo/stats",
|
||||
"Rev": "31fb71caf5a4f04c9f8bb3fa8e7c2597ba6eb50a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fatih/structs",
|
||||
"Rev": "c00d27128bb88e9c1adab1a53cda9c72c6d1ff9b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/context",
|
||||
"Rev": "50c25fb3b2b3b3cc724e9b6ac75fb44b3bccd0da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/mux",
|
||||
"Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/rpc/v2",
|
||||
"Rev": "f6dbf92d77c723632269bf29154cc91f2507693b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/minio/cli",
|
||||
"Comment": "1.2.0-114-g9280cba",
|
||||
"Rev": "9280cbaadcdd26d50b5ae85123682e37944701de"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/check.v1",
|
||||
"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673"
|
||||
}
|
||||
]
|
||||
}
|
5
Godeps/Readme
generated
5
Godeps/Readme
generated
@ -1,5 +0,0 @@
|
||||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
2
Godeps/_workspace/.gitignore
generated
vendored
2
Godeps/_workspace/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
||||
/pkg
|
||||
/bin
|
6
Godeps/_workspace/src/github.com/dustin/go-humanize/.gitignore
generated
vendored
6
Godeps/_workspace/src/github.com/dustin/go-humanize/.gitignore
generated
vendored
@ -1,6 +0,0 @@
|
||||
#*
|
||||
*.[568]
|
||||
*.a
|
||||
*~
|
||||
[568].out
|
||||
_*
|
219
Godeps/_workspace/src/github.com/dustin/go-humanize/bigbytes_test.go
generated
vendored
219
Godeps/_workspace/src/github.com/dustin/go-humanize/bigbytes_test.go
generated
vendored
@ -1,219 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBigByteParsing(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
exp uint64
|
||||
}{
|
||||
{"42", 42},
|
||||
{"42MB", 42000000},
|
||||
{"42MiB", 44040192},
|
||||
{"42mb", 42000000},
|
||||
{"42mib", 44040192},
|
||||
{"42MIB", 44040192},
|
||||
{"42 MB", 42000000},
|
||||
{"42 MiB", 44040192},
|
||||
{"42 mb", 42000000},
|
||||
{"42 mib", 44040192},
|
||||
{"42 MIB", 44040192},
|
||||
{"42.5MB", 42500000},
|
||||
{"42.5MiB", 44564480},
|
||||
{"42.5 MB", 42500000},
|
||||
{"42.5 MiB", 44564480},
|
||||
// No need to say B
|
||||
{"42M", 42000000},
|
||||
{"42Mi", 44040192},
|
||||
{"42m", 42000000},
|
||||
{"42mi", 44040192},
|
||||
{"42MI", 44040192},
|
||||
{"42 M", 42000000},
|
||||
{"42 Mi", 44040192},
|
||||
{"42 m", 42000000},
|
||||
{"42 mi", 44040192},
|
||||
{"42 MI", 44040192},
|
||||
{"42.5M", 42500000},
|
||||
{"42.5Mi", 44564480},
|
||||
{"42.5 M", 42500000},
|
||||
{"42.5 Mi", 44564480},
|
||||
// Large testing, breaks when too much larger than
|
||||
// this.
|
||||
{"12.5 EB", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 E", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 EiB", uint64(12.5 * float64(EiByte))},
|
||||
}
|
||||
|
||||
for _, p := range tests {
|
||||
got, err := ParseBigBytes(p.in)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't parse %v: %v", p.in, err)
|
||||
} else {
|
||||
if got.Uint64() != p.exp {
|
||||
t.Errorf("Expected %v for %v, got %v",
|
||||
p.exp, p.in, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBigByteErrors(t *testing.T) {
|
||||
got, err := ParseBigBytes("84 JB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
got, err = ParseBigBytes("")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error parsing nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func bbyte(in uint64) string {
|
||||
return BigBytes((&big.Int{}).SetUint64(in))
|
||||
}
|
||||
|
||||
func bibyte(in uint64) string {
|
||||
return BigIBytes((&big.Int{}).SetUint64(in))
|
||||
}
|
||||
|
||||
func TestBigBytes(t *testing.T) {
|
||||
testList{
|
||||
{"bytes(0)", bbyte(0), "0B"},
|
||||
{"bytes(1)", bbyte(1), "1B"},
|
||||
{"bytes(803)", bbyte(803), "803B"},
|
||||
{"bytes(999)", bbyte(999), "999B"},
|
||||
|
||||
{"bytes(1024)", bbyte(1024), "1.0KB"},
|
||||
{"bytes(1MB - 1)", bbyte(MByte - Byte), "1000KB"},
|
||||
|
||||
{"bytes(1MB)", bbyte(1024 * 1024), "1.0MB"},
|
||||
{"bytes(1GB - 1K)", bbyte(GByte - KByte), "1000MB"},
|
||||
|
||||
{"bytes(1GB)", bbyte(GByte), "1.0GB"},
|
||||
{"bytes(1TB - 1M)", bbyte(TByte - MByte), "1000GB"},
|
||||
|
||||
{"bytes(1TB)", bbyte(TByte), "1.0TB"},
|
||||
{"bytes(1PB - 1T)", bbyte(PByte - TByte), "999TB"},
|
||||
|
||||
{"bytes(1PB)", bbyte(PByte), "1.0PB"},
|
||||
{"bytes(1PB - 1T)", bbyte(EByte - PByte), "999PB"},
|
||||
|
||||
{"bytes(1EB)", bbyte(EByte), "1.0EB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", Bytes((KByte*EByte)-PByte), "1023EB"},
|
||||
|
||||
{"bytes(0)", bibyte(0), "0B"},
|
||||
{"bytes(1)", bibyte(1), "1B"},
|
||||
{"bytes(803)", bibyte(803), "803B"},
|
||||
{"bytes(1023)", bibyte(1023), "1023B"},
|
||||
|
||||
{"bytes(1024)", bibyte(1024), "1.0KiB"},
|
||||
{"bytes(1MB - 1)", bibyte(MiByte - IByte), "1024KiB"},
|
||||
|
||||
{"bytes(1MB)", bibyte(1024 * 1024), "1.0MiB"},
|
||||
{"bytes(1GB - 1K)", bibyte(GiByte - KiByte), "1024MiB"},
|
||||
|
||||
{"bytes(1GB)", bibyte(GiByte), "1.0GiB"},
|
||||
{"bytes(1TB - 1M)", bibyte(TiByte - MiByte), "1024GiB"},
|
||||
|
||||
{"bytes(1TB)", bibyte(TiByte), "1.0TiB"},
|
||||
{"bytes(1PB - 1T)", bibyte(PiByte - TiByte), "1023TiB"},
|
||||
|
||||
{"bytes(1PB)", bibyte(PiByte), "1.0PiB"},
|
||||
{"bytes(1PB - 1T)", bibyte(EiByte - PiByte), "1023PiB"},
|
||||
|
||||
{"bytes(1EiB)", bibyte(EiByte), "1.0EiB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", bibyte((KIByte*EIByte)-PiByte), "1023EB"},
|
||||
|
||||
{"bytes(5.5GiB)", bibyte(5.5 * GiByte), "5.5GiB"},
|
||||
|
||||
{"bytes(5.5GB)", bbyte(5.5 * GByte), "5.5GB"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestVeryBigBytes(t *testing.T) {
|
||||
b, _ := (&big.Int{}).SetString("15347691069326346944512", 10)
|
||||
s := BigBytes(b)
|
||||
if s != "15ZB" {
|
||||
t.Errorf("Expected 15ZB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13ZiB" {
|
||||
t.Errorf("Expected 13ZiB, got %v", s)
|
||||
}
|
||||
|
||||
b, _ = (&big.Int{}).SetString("15716035654990179271180288", 10)
|
||||
s = BigBytes(b)
|
||||
if s != "16YB" {
|
||||
t.Errorf("Expected 16YB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13YiB" {
|
||||
t.Errorf("Expected 13YiB, got %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVeryVeryBigBytes(t *testing.T) {
|
||||
b, _ := (&big.Int{}).SetString("16093220510709943573688614912", 10)
|
||||
s := BigBytes(b)
|
||||
if s != "16093YB" {
|
||||
t.Errorf("Expected 16093YB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13312YiB" {
|
||||
t.Errorf("Expected 13312YiB, got %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseVeryBig(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"16ZB", "16000000000000000000000"},
|
||||
{"16ZiB", "18889465931478580854784"},
|
||||
{"16.5ZB", "16500000000000000000000"},
|
||||
{"16.5ZiB", "19479761741837286506496"},
|
||||
{"16Z", "16000000000000000000000"},
|
||||
{"16Zi", "18889465931478580854784"},
|
||||
{"16.5Z", "16500000000000000000000"},
|
||||
{"16.5Zi", "19479761741837286506496"},
|
||||
|
||||
{"16YB", "16000000000000000000000000"},
|
||||
{"16YiB", "19342813113834066795298816"},
|
||||
{"16.5YB", "16500000000000000000000000"},
|
||||
{"16.5YiB", "19947276023641381382651904"},
|
||||
{"16Y", "16000000000000000000000000"},
|
||||
{"16Yi", "19342813113834066795298816"},
|
||||
{"16.5Y", "16500000000000000000000000"},
|
||||
{"16.5Yi", "19947276023641381382651904"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
x, err := ParseBigBytes(test.in)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %q: %v", test.in, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if x.String() != test.out {
|
||||
t.Errorf("Expected %q for %q, got %v", test.out, test.in, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseBigBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseBigBytes("16.5Z")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBigBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
bibyte(16.5 * GByte)
|
||||
}
|
||||
}
|
144
Godeps/_workspace/src/github.com/dustin/go-humanize/bytes_test.go
generated
vendored
144
Godeps/_workspace/src/github.com/dustin/go-humanize/bytes_test.go
generated
vendored
@ -1,144 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestByteParsing(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
exp uint64
|
||||
}{
|
||||
{"42", 42},
|
||||
{"42MB", 42000000},
|
||||
{"42MiB", 44040192},
|
||||
{"42mb", 42000000},
|
||||
{"42mib", 44040192},
|
||||
{"42MIB", 44040192},
|
||||
{"42 MB", 42000000},
|
||||
{"42 MiB", 44040192},
|
||||
{"42 mb", 42000000},
|
||||
{"42 mib", 44040192},
|
||||
{"42 MIB", 44040192},
|
||||
{"42.5MB", 42500000},
|
||||
{"42.5MiB", 44564480},
|
||||
{"42.5 MB", 42500000},
|
||||
{"42.5 MiB", 44564480},
|
||||
// No need to say B
|
||||
{"42M", 42000000},
|
||||
{"42Mi", 44040192},
|
||||
{"42m", 42000000},
|
||||
{"42mi", 44040192},
|
||||
{"42MI", 44040192},
|
||||
{"42 M", 42000000},
|
||||
{"42 Mi", 44040192},
|
||||
{"42 m", 42000000},
|
||||
{"42 mi", 44040192},
|
||||
{"42 MI", 44040192},
|
||||
{"42.5M", 42500000},
|
||||
{"42.5Mi", 44564480},
|
||||
{"42.5 M", 42500000},
|
||||
{"42.5 Mi", 44564480},
|
||||
// Large testing, breaks when too much larger than
|
||||
// this.
|
||||
{"12.5 EB", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 E", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 EiB", uint64(12.5 * float64(EiByte))},
|
||||
}
|
||||
|
||||
for _, p := range tests {
|
||||
got, err := ParseBytes(p.in)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't parse %v: %v", p.in, err)
|
||||
}
|
||||
if got != p.exp {
|
||||
t.Errorf("Expected %v for %v, got %v",
|
||||
p.exp, p.in, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestByteErrors(t *testing.T) {
|
||||
got, err := ParseBytes("84 JB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
got, err = ParseBytes("")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error parsing nothing")
|
||||
}
|
||||
got, err = ParseBytes("16 EiB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBytes(t *testing.T) {
|
||||
testList{
|
||||
{"bytes(0)", Bytes(0), "0B"},
|
||||
{"bytes(1)", Bytes(1), "1B"},
|
||||
{"bytes(803)", Bytes(803), "803B"},
|
||||
{"bytes(999)", Bytes(999), "999B"},
|
||||
|
||||
{"bytes(1024)", Bytes(1024), "1.0KB"},
|
||||
{"bytes(9999)", Bytes(9999), "10KB"},
|
||||
{"bytes(1MB - 1)", Bytes(MByte - Byte), "1000KB"},
|
||||
|
||||
{"bytes(1MB)", Bytes(1024 * 1024), "1.0MB"},
|
||||
{"bytes(1GB - 1K)", Bytes(GByte - KByte), "1000MB"},
|
||||
|
||||
{"bytes(1GB)", Bytes(GByte), "1.0GB"},
|
||||
{"bytes(1TB - 1M)", Bytes(TByte - MByte), "1000GB"},
|
||||
{"bytes(10MB)", Bytes(9999 * 1000), "10MB"},
|
||||
|
||||
{"bytes(1TB)", Bytes(TByte), "1.0TB"},
|
||||
{"bytes(1PB - 1T)", Bytes(PByte - TByte), "999TB"},
|
||||
|
||||
{"bytes(1PB)", Bytes(PByte), "1.0PB"},
|
||||
{"bytes(1PB - 1T)", Bytes(EByte - PByte), "999PB"},
|
||||
|
||||
{"bytes(1EB)", Bytes(EByte), "1.0EB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", Bytes((KByte*EByte)-PByte), "1023EB"},
|
||||
|
||||
{"bytes(0)", IBytes(0), "0B"},
|
||||
{"bytes(1)", IBytes(1), "1B"},
|
||||
{"bytes(803)", IBytes(803), "803B"},
|
||||
{"bytes(1023)", IBytes(1023), "1023B"},
|
||||
|
||||
{"bytes(1024)", IBytes(1024), "1.0KiB"},
|
||||
{"bytes(1MB - 1)", IBytes(MiByte - IByte), "1024KiB"},
|
||||
|
||||
{"bytes(1MB)", IBytes(1024 * 1024), "1.0MiB"},
|
||||
{"bytes(1GB - 1K)", IBytes(GiByte - KiByte), "1024MiB"},
|
||||
|
||||
{"bytes(1GB)", IBytes(GiByte), "1.0GiB"},
|
||||
{"bytes(1TB - 1M)", IBytes(TiByte - MiByte), "1024GiB"},
|
||||
|
||||
{"bytes(1TB)", IBytes(TiByte), "1.0TiB"},
|
||||
{"bytes(1PB - 1T)", IBytes(PiByte - TiByte), "1023TiB"},
|
||||
|
||||
{"bytes(1PB)", IBytes(PiByte), "1.0PiB"},
|
||||
{"bytes(1PB - 1T)", IBytes(EiByte - PiByte), "1023PiB"},
|
||||
|
||||
{"bytes(1EiB)", IBytes(EiByte), "1.0EiB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", IBytes((KIByte*EIByte)-PiByte), "1023EB"},
|
||||
|
||||
{"bytes(5.5GiB)", IBytes(5.5 * GiByte), "5.5GiB"},
|
||||
|
||||
{"bytes(5.5GB)", Bytes(5.5 * GByte), "5.5GB"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkParseBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseBytes("16.5GB")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Bytes(16.5 * GByte)
|
||||
}
|
||||
}
|
134
Godeps/_workspace/src/github.com/dustin/go-humanize/comma_test.go
generated
vendored
134
Godeps/_workspace/src/github.com/dustin/go-humanize/comma_test.go
generated
vendored
@ -1,134 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCommas(t *testing.T) {
|
||||
testList{
|
||||
{"0", Comma(0), "0"},
|
||||
{"10", Comma(10), "10"},
|
||||
{"100", Comma(100), "100"},
|
||||
{"1,000", Comma(1000), "1,000"},
|
||||
{"10,000", Comma(10000), "10,000"},
|
||||
{"100,000", Comma(100000), "100,000"},
|
||||
{"10,000,000", Comma(10000000), "10,000,000"},
|
||||
{"10,100,000", Comma(10100000), "10,100,000"},
|
||||
{"10,010,000", Comma(10010000), "10,010,000"},
|
||||
{"10,001,000", Comma(10001000), "10,001,000"},
|
||||
{"123,456,789", Comma(123456789), "123,456,789"},
|
||||
{"maxint", Comma(9.223372e+18), "9,223,372,000,000,000,000"},
|
||||
{"minint", Comma(-9.223372e+18), "-9,223,372,000,000,000,000"},
|
||||
{"-123,456,789", Comma(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", Comma(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", Comma(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", Comma(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", Comma(-10000000), "-10,000,000"},
|
||||
{"-100,000", Comma(-100000), "-100,000"},
|
||||
{"-10,000", Comma(-10000), "-10,000"},
|
||||
{"-1,000", Comma(-1000), "-1,000"},
|
||||
{"-100", Comma(-100), "-100"},
|
||||
{"-10", Comma(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestCommafs(t *testing.T) {
|
||||
testList{
|
||||
{"0", Commaf(0), "0"},
|
||||
{"10.11", Commaf(10.11), "10.11"},
|
||||
{"100", Commaf(100), "100"},
|
||||
{"1,000", Commaf(1000), "1,000"},
|
||||
{"10,000", Commaf(10000), "10,000"},
|
||||
{"100,000", Commaf(100000), "100,000"},
|
||||
{"834,142.32", Commaf(834142.32), "834,142.32"},
|
||||
{"10,000,000", Commaf(10000000), "10,000,000"},
|
||||
{"10,100,000", Commaf(10100000), "10,100,000"},
|
||||
{"10,010,000", Commaf(10010000), "10,010,000"},
|
||||
{"10,001,000", Commaf(10001000), "10,001,000"},
|
||||
{"123,456,789", Commaf(123456789), "123,456,789"},
|
||||
{"maxf64", Commaf(math.MaxFloat64), "179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000"},
|
||||
{"minf64", Commaf(math.SmallestNonzeroFloat64), "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005"},
|
||||
{"-123,456,789", Commaf(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", Commaf(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", Commaf(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", Commaf(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", Commaf(-10000000), "-10,000,000"},
|
||||
{"-100,000", Commaf(-100000), "-100,000"},
|
||||
{"-10,000", Commaf(-10000), "-10,000"},
|
||||
{"-1,000", Commaf(-1000), "-1,000"},
|
||||
{"-100.11", Commaf(-100.11), "-100.11"},
|
||||
{"-10", Commaf(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkCommas(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Comma(1234567890)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommaf(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Commaf(1234567890.83584)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBigCommas(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
BigComma(big.NewInt(1234567890))
|
||||
}
|
||||
}
|
||||
|
||||
func bigComma(i int64) string {
|
||||
return BigComma(big.NewInt(i))
|
||||
}
|
||||
|
||||
func TestBigCommas(t *testing.T) {
|
||||
testList{
|
||||
{"0", bigComma(0), "0"},
|
||||
{"10", bigComma(10), "10"},
|
||||
{"100", bigComma(100), "100"},
|
||||
{"1,000", bigComma(1000), "1,000"},
|
||||
{"10,000", bigComma(10000), "10,000"},
|
||||
{"100,000", bigComma(100000), "100,000"},
|
||||
{"10,000,000", bigComma(10000000), "10,000,000"},
|
||||
{"10,100,000", bigComma(10100000), "10,100,000"},
|
||||
{"10,010,000", bigComma(10010000), "10,010,000"},
|
||||
{"10,001,000", bigComma(10001000), "10,001,000"},
|
||||
{"123,456,789", bigComma(123456789), "123,456,789"},
|
||||
{"maxint", bigComma(9.223372e+18), "9,223,372,000,000,000,000"},
|
||||
{"minint", bigComma(-9.223372e+18), "-9,223,372,000,000,000,000"},
|
||||
{"-123,456,789", bigComma(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", bigComma(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", bigComma(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", bigComma(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", bigComma(-10000000), "-10,000,000"},
|
||||
{"-100,000", bigComma(-100000), "-100,000"},
|
||||
{"-10,000", bigComma(-10000), "-10,000"},
|
||||
{"-1,000", bigComma(-1000), "-1,000"},
|
||||
{"-100", bigComma(-100), "-100"},
|
||||
{"-10", bigComma(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestVeryBigCommas(t *testing.T) {
|
||||
tests := []struct{ in, exp string }{
|
||||
{
|
||||
"84889279597249724975972597249849757294578485",
|
||||
"84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
|
||||
},
|
||||
{
|
||||
"-84889279597249724975972597249849757294578485",
|
||||
"-84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
n, _ := (&big.Int{}).SetString(test.in, 10)
|
||||
got := BigComma(n)
|
||||
if test.exp != got {
|
||||
t.Errorf("Expected %q, got %q", test.exp, got)
|
||||
}
|
||||
}
|
||||
}
|
18
Godeps/_workspace/src/github.com/dustin/go-humanize/common_test.go
generated
vendored
18
Godeps/_workspace/src/github.com/dustin/go-humanize/common_test.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testList []struct {
|
||||
name, got, exp string
|
||||
}
|
||||
|
||||
func (tl testList) validate(t *testing.T) {
|
||||
for _, test := range tl {
|
||||
if test.got != test.exp {
|
||||
t.Errorf("On %v, expected '%v', but got '%v'",
|
||||
test.name, test.exp, test.got)
|
||||
}
|
||||
}
|
||||
}
|
55
Godeps/_workspace/src/github.com/dustin/go-humanize/ftoa_test.go
generated
vendored
55
Godeps/_workspace/src/github.com/dustin/go-humanize/ftoa_test.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFtoa(t *testing.T) {
|
||||
testList{
|
||||
{"200", Ftoa(200), "200"},
|
||||
{"2", Ftoa(2), "2"},
|
||||
{"2.2", Ftoa(2.2), "2.2"},
|
||||
{"2.02", Ftoa(2.02), "2.02"},
|
||||
{"200.02", Ftoa(200.02), "200.02"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkFtoaRegexTrailing(b *testing.B) {
|
||||
trailingZerosRegex := regexp.MustCompile(`\.?0+$`)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
trailingZerosRegex.ReplaceAllString("2.00000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.0000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.00", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.0", "")
|
||||
trailingZerosRegex.ReplaceAllString("2", "")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFtoaFunc(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
stripTrailingZeros("2.00000")
|
||||
stripTrailingZeros("2.0000")
|
||||
stripTrailingZeros("2.000")
|
||||
stripTrailingZeros("2.00")
|
||||
stripTrailingZeros("2.0")
|
||||
stripTrailingZeros("2")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFmtF(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
fmt.Sprintf("%f", 2.03584)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStrconvF(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
strconv.FormatFloat(2.03584, 'f', 6, 64)
|
||||
}
|
||||
}
|
22
Godeps/_workspace/src/github.com/dustin/go-humanize/ordinals_test.go
generated
vendored
22
Godeps/_workspace/src/github.com/dustin/go-humanize/ordinals_test.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOrdinals(t *testing.T) {
|
||||
testList{
|
||||
{"0", Ordinal(0), "0th"},
|
||||
{"1", Ordinal(1), "1st"},
|
||||
{"2", Ordinal(2), "2nd"},
|
||||
{"3", Ordinal(3), "3rd"},
|
||||
{"4", Ordinal(4), "4th"},
|
||||
{"10", Ordinal(10), "10th"},
|
||||
{"11", Ordinal(11), "11th"},
|
||||
{"12", Ordinal(12), "12th"},
|
||||
{"13", Ordinal(13), "13th"},
|
||||
{"101", Ordinal(101), "101st"},
|
||||
{"102", Ordinal(102), "102nd"},
|
||||
{"103", Ordinal(103), "103rd"},
|
||||
}.validate(t)
|
||||
}
|
98
Godeps/_workspace/src/github.com/dustin/go-humanize/si_test.go
generated
vendored
98
Godeps/_workspace/src/github.com/dustin/go-humanize/si_test.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSI(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
num float64
|
||||
formatted string
|
||||
}{
|
||||
{"e-24", 1e-24, "1yF"},
|
||||
{"e-21", 1e-21, "1zF"},
|
||||
{"e-18", 1e-18, "1aF"},
|
||||
{"e-15", 1e-15, "1fF"},
|
||||
{"e-12", 1e-12, "1pF"},
|
||||
{"e-12", 2.2345e-12, "2.2345pF"},
|
||||
{"e-12", 2.23e-12, "2.23pF"},
|
||||
{"e-11", 2.23e-11, "22.3pF"},
|
||||
{"e-10", 2.2e-10, "220pF"},
|
||||
{"e-9", 2.2e-9, "2.2nF"},
|
||||
{"e-8", 2.2e-8, "22nF"},
|
||||
{"e-7", 2.2e-7, "220nF"},
|
||||
{"e-6", 2.2e-6, "2.2µF"},
|
||||
{"e-6", 1e-6, "1µF"},
|
||||
{"e-5", 2.2e-5, "22µF"},
|
||||
{"e-4", 2.2e-4, "220µF"},
|
||||
{"e-3", 2.2e-3, "2.2mF"},
|
||||
{"e-2", 2.2e-2, "22mF"},
|
||||
{"e-1", 2.2e-1, "220mF"},
|
||||
{"e+0", 2.2e-0, "2.2F"},
|
||||
{"e+0", 2.2, "2.2F"},
|
||||
{"e+1", 2.2e+1, "22F"},
|
||||
{"0", 0, "0F"},
|
||||
{"e+1", 22, "22F"},
|
||||
{"e+2", 2.2e+2, "220F"},
|
||||
{"e+2", 220, "220F"},
|
||||
{"e+3", 2.2e+3, "2.2kF"},
|
||||
{"e+3", 2200, "2.2kF"},
|
||||
{"e+4", 2.2e+4, "22kF"},
|
||||
{"e+4", 22000, "22kF"},
|
||||
{"e+5", 2.2e+5, "220kF"},
|
||||
{"e+6", 2.2e+6, "2.2MF"},
|
||||
{"e+6", 1e+6, "1MF"},
|
||||
{"e+7", 2.2e+7, "22MF"},
|
||||
{"e+8", 2.2e+8, "220MF"},
|
||||
{"e+9", 2.2e+9, "2.2GF"},
|
||||
{"e+10", 2.2e+10, "22GF"},
|
||||
{"e+11", 2.2e+11, "220GF"},
|
||||
{"e+12", 2.2e+12, "2.2TF"},
|
||||
{"e+15", 2.2e+15, "2.2PF"},
|
||||
{"e+18", 2.2e+18, "2.2EF"},
|
||||
{"e+21", 2.2e+21, "2.2ZF"},
|
||||
{"e+24", 2.2e+24, "2.2YF"},
|
||||
|
||||
// special case
|
||||
{"1F", 1000 * 1000, "1MF"},
|
||||
{"1F", 1e6, "1MF"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got := SI(test.num, "F")
|
||||
if got != test.formatted {
|
||||
t.Errorf("On %v (%v), got %v, wanted %v",
|
||||
test.name, test.num, got, test.formatted)
|
||||
}
|
||||
|
||||
gotf, gotu, err := ParseSI(test.formatted)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %v (%v): %v", test.name, test.formatted, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if math.Abs(1-(gotf/test.num)) > 0.01 {
|
||||
t.Errorf("On %v (%v), got %v, wanted %v (±%v)",
|
||||
test.name, test.formatted, gotf, test.num,
|
||||
math.Abs(1-(gotf/test.num)))
|
||||
}
|
||||
if gotu != "F" {
|
||||
t.Errorf("On %v (%v), expected unit F, got %v",
|
||||
test.name, test.formatted, gotu)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse error
|
||||
gotf, gotu, err := ParseSI("x1.21JW") // 1.21 jigga whats
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on x1.21JW, got %v %v", gotf, gotu)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSI(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseSI("2.2346ZB")
|
||||
}
|
||||
}
|
71
Godeps/_workspace/src/github.com/dustin/go-humanize/times_test.go
generated
vendored
71
Godeps/_workspace/src/github.com/dustin/go-humanize/times_test.go
generated
vendored
@ -1,71 +0,0 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPast(t *testing.T) {
|
||||
now := time.Now().Unix()
|
||||
testList{
|
||||
{"now", Time(time.Unix(now, 0)), "now"},
|
||||
{"1 second ago", Time(time.Unix(now-1, 0)), "1 second ago"},
|
||||
{"12 seconds ago", Time(time.Unix(now-12, 0)), "12 seconds ago"},
|
||||
{"30 seconds ago", Time(time.Unix(now-30, 0)), "30 seconds ago"},
|
||||
{"45 seconds ago", Time(time.Unix(now-45, 0)), "45 seconds ago"},
|
||||
{"1 minute ago", Time(time.Unix(now-63, 0)), "1 minute ago"},
|
||||
{"15 minutes ago", Time(time.Unix(now-15*Minute, 0)), "15 minutes ago"},
|
||||
{"1 hour ago", Time(time.Unix(now-63*Minute, 0)), "1 hour ago"},
|
||||
{"2 hours ago", Time(time.Unix(now-2*Hour, 0)), "2 hours ago"},
|
||||
{"21 hours ago", Time(time.Unix(now-21*Hour, 0)), "21 hours ago"},
|
||||
{"1 day ago", Time(time.Unix(now-26*Hour, 0)), "1 day ago"},
|
||||
{"2 days ago", Time(time.Unix(now-49*Hour, 0)), "2 days ago"},
|
||||
{"3 days ago", Time(time.Unix(now-3*Day, 0)), "3 days ago"},
|
||||
{"1 week ago (1)", Time(time.Unix(now-7*Day, 0)), "1 week ago"},
|
||||
{"1 week ago (2)", Time(time.Unix(now-12*Day, 0)), "1 week ago"},
|
||||
{"2 weeks ago", Time(time.Unix(now-15*Day, 0)), "2 weeks ago"},
|
||||
{"1 month ago", Time(time.Unix(now-39*Day, 0)), "1 month ago"},
|
||||
{"3 months ago", Time(time.Unix(now-99*Day, 0)), "3 months ago"},
|
||||
{"1 year ago (1)", Time(time.Unix(now-365*Day, 0)), "1 year ago"},
|
||||
{"1 year ago (1)", Time(time.Unix(now-400*Day, 0)), "1 year ago"},
|
||||
{"2 years ago (1)", Time(time.Unix(now-548*Day, 0)), "2 years ago"},
|
||||
{"2 years ago (2)", Time(time.Unix(now-725*Day, 0)), "2 years ago"},
|
||||
{"2 years ago (3)", Time(time.Unix(now-800*Day, 0)), "2 years ago"},
|
||||
{"3 years ago", Time(time.Unix(now-3*Year, 0)), "3 years ago"},
|
||||
{"long ago", Time(time.Unix(now-LongTime, 0)), "a long while ago"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestFuture(t *testing.T) {
|
||||
now := time.Now().Unix()
|
||||
testList{
|
||||
{"now", Time(time.Unix(now, 0)), "now"},
|
||||
{"1 second from now", Time(time.Unix(now+1, 0)), "1 second from now"},
|
||||
{"12 seconds from now", Time(time.Unix(now+12, 0)), "12 seconds from now"},
|
||||
{"30 seconds from now", Time(time.Unix(now+30, 0)), "30 seconds from now"},
|
||||
{"45 seconds from now", Time(time.Unix(now+45, 0)), "45 seconds from now"},
|
||||
{"15 minutes from now", Time(time.Unix(now+15*Minute, 0)), "15 minutes from now"},
|
||||
{"2 hours from now", Time(time.Unix(now+2*Hour, 0)), "2 hours from now"},
|
||||
{"21 hours from now", Time(time.Unix(now+21*Hour, 0)), "21 hours from now"},
|
||||
{"1 day from now", Time(time.Unix(now+26*Hour, 0)), "1 day from now"},
|
||||
{"2 days from now", Time(time.Unix(now+49*Hour, 0)), "2 days from now"},
|
||||
{"3 days from now", Time(time.Unix(now+3*Day, 0)), "3 days from now"},
|
||||
{"1 week from now (1)", Time(time.Unix(now+7*Day, 0)), "1 week from now"},
|
||||
{"1 week from now (2)", Time(time.Unix(now+12*Day, 0)), "1 week from now"},
|
||||
{"2 weeks from now", Time(time.Unix(now+15*Day, 0)), "2 weeks from now"},
|
||||
{"1 month from now", Time(time.Unix(now+30*Day, 0)), "1 month from now"},
|
||||
{"1 year from now", Time(time.Unix(now+365*Day, 0)), "1 year from now"},
|
||||
{"2 years from now", Time(time.Unix(now+2*Year, 0)), "2 years from now"},
|
||||
{"a while from now", Time(time.Unix(now+LongTime, 0)), "a long while from now"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
start := time.Time{}
|
||||
end := time.Unix(math.MaxInt64, math.MaxInt64)
|
||||
x := RelTime(start, end, "ago", "from now")
|
||||
if x != "a long while from now" {
|
||||
t.Errorf("Expected a long while from now, got %q", x)
|
||||
}
|
||||
}
|
536
Godeps/_workspace/src/github.com/facebookgo/clock/clock_test.go
generated
vendored
536
Godeps/_workspace/src/github.com/facebookgo/clock/clock_test.go
generated
vendored
@ -1,536 +0,0 @@
|
||||
package clock_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/clock"
|
||||
)
|
||||
|
||||
// Ensure that the clock's After channel sends at the correct time.
|
||||
func TestClock_After(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
<-clock.New().After(20 * time.Millisecond)
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's AfterFunc executes at the correct time.
|
||||
func TestClock_AfterFunc(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
clock.New().AfterFunc(20*time.Millisecond, func() {
|
||||
wg.Done()
|
||||
})
|
||||
wg.Wait()
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's time matches the standary library.
|
||||
func TestClock_Now(t *testing.T) {
|
||||
a := time.Now().Round(time.Second)
|
||||
b := clock.New().Now().Round(time.Second)
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("not equal: %s != %s", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock sleeps for the appropriate amount of time.
|
||||
func TestClock_Sleep(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
clock.New().Sleep(20 * time.Millisecond)
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock ticks correctly.
|
||||
func TestClock_Tick(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
c := clock.New().Tick(20 * time.Millisecond)
|
||||
<-c
|
||||
<-c
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's ticker ticks correctly.
|
||||
func TestClock_Ticker(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
ticker := clock.New().Ticker(50 * time.Millisecond)
|
||||
<-ticker.C
|
||||
<-ticker.C
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's ticker can stop correctly.
|
||||
func TestClock_Ticker_Stp(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
gosched()
|
||||
|
||||
ticker := clock.New().Ticker(20 * time.Millisecond)
|
||||
<-ticker.C
|
||||
ticker.Stop()
|
||||
select {
|
||||
case <-ticker.C:
|
||||
t.Fatal("unexpected send")
|
||||
case <-time.After(30 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's timer waits correctly.
|
||||
func TestClock_Timer(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
t.Fatal("too late")
|
||||
}()
|
||||
gosched()
|
||||
|
||||
timer := clock.New().Timer(20 * time.Millisecond)
|
||||
<-timer.C
|
||||
if !ok {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the clock's timer can be stopped.
|
||||
func TestClock_Timer_Stop(t *testing.T) {
|
||||
var ok bool
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
ok = true
|
||||
}()
|
||||
|
||||
timer := clock.New().Timer(20 * time.Millisecond)
|
||||
timer.Stop()
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Fatal("unexpected send")
|
||||
case <-time.After(30 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's After channel sends at the correct time.
|
||||
func TestMock_After(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
ch := clock.After(10 * time.Second)
|
||||
go func(ch <-chan time.Time) {
|
||||
<-ch
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
}(ch)
|
||||
|
||||
// Move clock forward to just before the time.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after channel's time.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's AfterFunc executes at the correct time.
|
||||
func TestMock_AfterFunc(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Execute function after duration.
|
||||
clock.AfterFunc(10*time.Second, func() {
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
})
|
||||
|
||||
// Move clock forward to just before the time.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after channel's time.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's AfterFunc doesn't execute if stopped.
|
||||
func TestMock_AfterFunc_Stop(t *testing.T) {
|
||||
// Execute function after duration.
|
||||
clock := clock.NewMock()
|
||||
timer := clock.AfterFunc(10*time.Second, func() {
|
||||
t.Fatal("unexpected function execution")
|
||||
})
|
||||
gosched()
|
||||
|
||||
// Stop timer & move clock forward.
|
||||
timer.Stop()
|
||||
clock.Add(10 * time.Second)
|
||||
gosched()
|
||||
}
|
||||
|
||||
// Ensure that the mock's current time can be changed.
|
||||
func TestMock_Now(t *testing.T) {
|
||||
clock := clock.NewMock()
|
||||
if now := clock.Now(); !now.Equal(time.Unix(0, 0)) {
|
||||
t.Fatalf("expected epoch, got: ", now)
|
||||
}
|
||||
|
||||
// Add 10 seconds and check the time.
|
||||
clock.Add(10 * time.Second)
|
||||
if now := clock.Now(); !now.Equal(time.Unix(10, 0)) {
|
||||
t.Fatalf("expected epoch, got: ", now)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock can sleep for the correct time.
|
||||
func TestMock_Sleep(t *testing.T) {
|
||||
var ok int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
go func() {
|
||||
clock.Sleep(10 * time.Second)
|
||||
atomic.StoreInt32(&ok, 1)
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward to just before the sleep duration.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 1 {
|
||||
t.Fatal("too early")
|
||||
}
|
||||
|
||||
// Move clock forward to the after the sleep duration.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&ok) == 0 {
|
||||
t.Fatal("too late")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Tick channel sends at the correct time.
|
||||
func TestMock_Tick(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every 10 seconds.
|
||||
go func() {
|
||||
tick := clock.Tick(10 * time.Second)
|
||||
for {
|
||||
<-tick
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward to just before the first tick.
|
||||
clock.Add(9 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 0 {
|
||||
t.Fatalf("expected 0, got %d", n)
|
||||
}
|
||||
|
||||
// Move clock forward to the start of the first tick.
|
||||
clock.Add(1 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 1 {
|
||||
t.Fatalf("expected 1, got %d", n)
|
||||
}
|
||||
|
||||
// Move clock forward over several ticks.
|
||||
clock.Add(30 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 4 {
|
||||
t.Fatalf("expected 4, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker channel sends at the correct time.
|
||||
func TestMock_Ticker(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every microsecond.
|
||||
go func() {
|
||||
ticker := clock.Ticker(1 * time.Microsecond)
|
||||
for {
|
||||
<-ticker.C
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(10 * time.Microsecond)
|
||||
if atomic.LoadInt32(&n) != 10 {
|
||||
t.Fatalf("unexpected: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker channel won't block if not read from.
|
||||
func TestMock_Ticker_Overflow(t *testing.T) {
|
||||
clock := clock.NewMock()
|
||||
ticker := clock.Ticker(1 * time.Microsecond)
|
||||
clock.Add(10 * time.Microsecond)
|
||||
ticker.Stop()
|
||||
}
|
||||
|
||||
// Ensure that the mock's Ticker can be stopped.
|
||||
func TestMock_Ticker_Stop(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
// Create a channel to increment every second.
|
||||
ticker := clock.Ticker(1 * time.Second)
|
||||
go func() {
|
||||
for {
|
||||
<-ticker.C
|
||||
atomic.AddInt32(&n, 1)
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(5 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 5 {
|
||||
t.Fatalf("expected 5, got: %d", n)
|
||||
}
|
||||
|
||||
ticker.Stop()
|
||||
|
||||
// Move clock forward again.
|
||||
clock.Add(5 * time.Second)
|
||||
if atomic.LoadInt32(&n) != 5 {
|
||||
t.Fatalf("still expected 5, got: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that multiple tickers can be used together.
|
||||
func TestMock_Ticker_Multi(t *testing.T) {
|
||||
var n int32
|
||||
clock := clock.NewMock()
|
||||
|
||||
go func() {
|
||||
a := clock.Ticker(1 * time.Microsecond)
|
||||
b := clock.Ticker(3 * time.Microsecond)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-a.C:
|
||||
atomic.AddInt32(&n, 1)
|
||||
case <-b.C:
|
||||
atomic.AddInt32(&n, 100)
|
||||
}
|
||||
}
|
||||
}()
|
||||
gosched()
|
||||
|
||||
// Move clock forward.
|
||||
clock.Add(10 * time.Microsecond)
|
||||
gosched()
|
||||
if atomic.LoadInt32(&n) != 310 {
|
||||
t.Fatalf("unexpected: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleMock_After() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Create a channel to execute after 10 mock seconds.
|
||||
go func() {
|
||||
<-clock.After(10 * time.Second)
|
||||
count = 100
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 5 seconds and print the value again.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 5 seconds to the tick time and check the value.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:05 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_AfterFunc() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Execute a function after 10 mock seconds.
|
||||
clock.AfterFunc(10*time.Second, func() {
|
||||
count = 100
|
||||
})
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_Sleep() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Execute a function after 10 mock seconds.
|
||||
go func() {
|
||||
clock.Sleep(10 * time.Second)
|
||||
count = 100
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Print the starting value.
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("%s: %d\n", clock.Now().UTC(), count)
|
||||
|
||||
// Output:
|
||||
// 1970-01-01 00:00:00 +0000 UTC: 0
|
||||
// 1970-01-01 00:00:10 +0000 UTC: 100
|
||||
}
|
||||
|
||||
func ExampleMock_Ticker() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Increment count every mock second.
|
||||
go func() {
|
||||
ticker := clock.Ticker(1 * time.Second)
|
||||
for {
|
||||
<-ticker.C
|
||||
count++
|
||||
}
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("Count is %d after 10 seconds\n", count)
|
||||
|
||||
// Move the clock forward 5 more seconds and print the new value.
|
||||
clock.Add(5 * time.Second)
|
||||
fmt.Printf("Count is %d after 15 seconds\n", count)
|
||||
|
||||
// Output:
|
||||
// Count is 10 after 10 seconds
|
||||
// Count is 15 after 15 seconds
|
||||
}
|
||||
|
||||
func ExampleMock_Timer() {
|
||||
// Create a new mock clock.
|
||||
clock := clock.NewMock()
|
||||
count := 0
|
||||
|
||||
// Increment count after a mock second.
|
||||
go func() {
|
||||
timer := clock.Timer(1 * time.Second)
|
||||
<-timer.C
|
||||
count++
|
||||
}()
|
||||
runtime.Gosched()
|
||||
|
||||
// Move the clock forward 10 seconds and print the new value.
|
||||
clock.Add(10 * time.Second)
|
||||
fmt.Printf("Count is %d after 10 seconds\n", count)
|
||||
|
||||
// Output:
|
||||
// Count is 1 after 10 seconds
|
||||
}
|
||||
|
||||
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
|
||||
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }
|
||||
|
||||
func gosched() { time.Sleep(1 * time.Millisecond) }
|
23
Godeps/_workspace/src/github.com/facebookgo/httpdown/.travis.yml
generated
vendored
23
Godeps/_workspace/src/github.com/facebookgo/httpdown/.travis.yml
generated
vendored
@ -1,23 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- go get -v code.google.com/p/go.tools/cmd/vet
|
||||
- go get -v github.com/golang/lint/golint
|
||||
- go get -v code.google.com/p/go.tools/cmd/cover
|
||||
|
||||
install:
|
||||
- go install -race -v std
|
||||
- go get -race -t -v ./...
|
||||
- go install -race -v ./...
|
||||
|
||||
script:
|
||||
- go vet ./...
|
||||
- $HOME/gopath/bin/golint .
|
||||
- go test -cpu=2 -race -v ./...
|
||||
- go test -cpu=2 -covermode=atomic ./...
|
43
Godeps/_workspace/src/github.com/facebookgo/httpdown/httpdown_example/main.go
generated
vendored
43
Godeps/_workspace/src/github.com/facebookgo/httpdown/httpdown_example/main.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/httpdown"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
duration, err := time.ParseDuration(r.FormValue("duration"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "going to sleep %s with pid %d\n", duration, os.Getpid())
|
||||
w.(http.Flusher).Flush()
|
||||
time.Sleep(duration)
|
||||
fmt.Fprintf(w, "slept %s with pid %d\n", duration, os.Getpid())
|
||||
}
|
||||
|
||||
func main() {
|
||||
server := &http.Server{
|
||||
Addr: "127.0.0.1:8080",
|
||||
Handler: http.HandlerFunc(handler),
|
||||
}
|
||||
hd := &httpdown.HTTP{
|
||||
StopTimeout: 10 * time.Second,
|
||||
KillTimeout: 1 * time.Second,
|
||||
}
|
||||
|
||||
flag.StringVar(&server.Addr, "addr", server.Addr, "http address")
|
||||
flag.DurationVar(&hd.StopTimeout, "stop-timeout", hd.StopTimeout, "stop timeout")
|
||||
flag.DurationVar(&hd.KillTimeout, "kill-timeout", hd.KillTimeout, "kill timeout")
|
||||
flag.Parse()
|
||||
|
||||
if err := httpdown.ListenAndServe(server, hd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
677
Godeps/_workspace/src/github.com/facebookgo/httpdown/httpdown_test.go
generated
vendored
677
Godeps/_workspace/src/github.com/facebookgo/httpdown/httpdown_test.go
generated
vendored
@ -1,677 +0,0 @@
|
||||
package httpdown_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/clock"
|
||||
"github.com/facebookgo/ensure"
|
||||
"github.com/facebookgo/freeport"
|
||||
"github.com/facebookgo/httpdown"
|
||||
"github.com/facebookgo/stats"
|
||||
)
|
||||
|
||||
type onCloseListener struct {
|
||||
net.Listener
|
||||
mutex sync.Mutex
|
||||
onClose chan struct{}
|
||||
}
|
||||
|
||||
func (o *onCloseListener) Close() error {
|
||||
// Listener is closed twice, once by Grace, and once by the http library, so
|
||||
// we guard against a double close of the chan.
|
||||
defer func() {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
if o.onClose != nil {
|
||||
close(o.onClose)
|
||||
o.onClose = nil
|
||||
}
|
||||
}()
|
||||
return o.Listener.Close()
|
||||
}
|
||||
|
||||
func NewOnCloseListener(l net.Listener) (net.Listener, chan struct{}) {
|
||||
c := make(chan struct{})
|
||||
return &onCloseListener{Listener: l, onClose: c}, c
|
||||
}
|
||||
|
||||
type closeErrListener struct {
|
||||
net.Listener
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *closeErrListener) Close() error {
|
||||
c.Listener.Close()
|
||||
return c.err
|
||||
}
|
||||
|
||||
type acceptErrListener struct {
|
||||
net.Listener
|
||||
err chan error
|
||||
}
|
||||
|
||||
func (c *acceptErrListener) Accept() (net.Conn, error) {
|
||||
return nil, <-c.err
|
||||
}
|
||||
|
||||
type closeErrConn struct {
|
||||
net.Conn
|
||||
unblockClose chan chan struct{}
|
||||
}
|
||||
|
||||
func (c *closeErrConn) Close() error {
|
||||
ch := <-c.unblockClose
|
||||
|
||||
// Close gets called multiple times, but only the first one gets this ch
|
||||
if ch != nil {
|
||||
defer close(ch)
|
||||
}
|
||||
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
type closeErrConnListener struct {
|
||||
net.Listener
|
||||
unblockClose chan chan struct{}
|
||||
}
|
||||
|
||||
func (l *closeErrConnListener) Accept() (net.Conn, error) {
|
||||
c, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
return &closeErrConn{Conn: c, unblockClose: l.unblockClose}, nil
|
||||
}
|
||||
|
||||
func TestHTTPStopWithNoRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
|
||||
statsDone := make(chan struct{}, 2)
|
||||
hc := &stats.HookClient{
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
if key == "serve" && val == 1 {
|
||||
statsDone <- struct{}{}
|
||||
}
|
||||
if key == "stop" && val == 1 {
|
||||
statsDone <- struct{}{}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
server := &http.Server{}
|
||||
down := &httpdown.HTTP{Stats: hc}
|
||||
s := down.Serve(server, listener)
|
||||
ensure.Nil(t, s.Stop())
|
||||
<-statsDone
|
||||
<-statsDone
|
||||
}
|
||||
|
||||
func TestHTTPStopWithFinishedRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
hello := []byte("hello")
|
||||
fin := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(fin)
|
||||
w.Write(hello)
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, hello)
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
|
||||
// At this point the request is finished, and the connection should be alive
|
||||
// but idle (because we have keep alive enabled by default in our Transport).
|
||||
ensure.Nil(t, s.Stop())
|
||||
<-fin
|
||||
|
||||
ensure.Nil(t, s.Wait())
|
||||
}
|
||||
|
||||
func TestHTTPStopWithActiveRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, bytes.Repeat(hello, count))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
func TestNewRequestAfterStop(t *testing.T) {
|
||||
t.Parallel()
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
unblockOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
const diff = 500
|
||||
for i := 0; i < count-diff; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
<-unblockOkHandler
|
||||
for i := 0; i < diff; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
listener, onClose := NewOnCloseListener(listener)
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
// Wait until the listener is closed.
|
||||
<-onClose
|
||||
|
||||
// Now the next request should not be able to connect as the listener is
|
||||
// now closed.
|
||||
_, err = client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
|
||||
// We should just get "connection refused" here, but sometimes, very rarely,
|
||||
// we get a "connection reset" instead. Unclear why this happens.
|
||||
ensure.Err(t, err, regexp.MustCompile("(connection refused|connection reset by peer)$"))
|
||||
|
||||
// Unblock the handler and ensure we finish writing the rest of the body
|
||||
// successfully.
|
||||
close(unblockOkHandler)
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, bytes.Repeat(hello, count))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
func TestHTTPListenerCloseError(t *testing.T) {
|
||||
t.Parallel()
|
||||
expectedError := errors.New("foo")
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
listener = &closeErrListener{Listener: listener, err: expectedError}
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
ensure.DeepEqual(t, s.Stop(), expectedError)
|
||||
}
|
||||
|
||||
func TestHTTPServeError(t *testing.T) {
|
||||
t.Parallel()
|
||||
expectedError := errors.New("foo")
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
errChan := make(chan error)
|
||||
listener = &acceptErrListener{Listener: listener, err: errChan}
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
errChan <- expectedError
|
||||
ensure.DeepEqual(t, s.Wait(), expectedError)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}
|
||||
|
||||
func TestHTTPWithinStopTimeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
w.Write(hello)
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{StopTimeout: time.Minute}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, hello)
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
func TestHTTPStopTimeoutMissed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
klock := clock.NewMock()
|
||||
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
unblockOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.Header().Set("Content-Length", fmt.Sprint(len(hello)*count))
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
<-unblockOkHandler
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{
|
||||
StopTimeout: time.Minute,
|
||||
Clock: klock,
|
||||
}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
klock.Wait(clock.Calls{After: 1}) // wait for Stop to call After
|
||||
klock.Add(down.StopTimeout)
|
||||
|
||||
_, err = ioutil.ReadAll(res.Body)
|
||||
ensure.Err(t, err, regexp.MustCompile("^unexpected EOF$"))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
close(unblockOkHandler)
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
func TestHTTPKillTimeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
klock := clock.NewMock()
|
||||
|
||||
statsDone := make(chan struct{}, 1)
|
||||
hc := &stats.HookClient{
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
if key == "kill" && val == 1 {
|
||||
statsDone <- struct{}{}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
unblockOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.Header().Set("Content-Length", fmt.Sprint(len(hello)*count))
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
<-unblockOkHandler
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{
|
||||
StopTimeout: time.Minute,
|
||||
KillTimeout: time.Minute,
|
||||
Stats: hc,
|
||||
Clock: klock,
|
||||
}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
klock.Wait(clock.Calls{After: 1}) // wait for Stop to call After
|
||||
klock.Add(down.StopTimeout)
|
||||
|
||||
_, err = ioutil.ReadAll(res.Body)
|
||||
ensure.Err(t, err, regexp.MustCompile("^unexpected EOF$"))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
close(unblockOkHandler)
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
<-statsDone
|
||||
}
|
||||
|
||||
func TestHTTPKillTimeoutMissed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
klock := clock.NewMock()
|
||||
|
||||
statsDone := make(chan struct{}, 1)
|
||||
hc := &stats.HookClient{
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
if key == "kill.timeout" && val == 1 {
|
||||
statsDone <- struct{}{}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
unblockOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.Header().Set("Content-Length", fmt.Sprint(len(hello)*count))
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
<-unblockOkHandler
|
||||
for i := 0; i < count/2; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
unblockConnClose := make(chan chan struct{}, 1)
|
||||
listener = &closeErrConnListener{
|
||||
Listener: listener,
|
||||
unblockClose: unblockConnClose,
|
||||
}
|
||||
|
||||
server := &http.Server{Handler: http.HandlerFunc(okHandler)}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{
|
||||
StopTimeout: time.Minute,
|
||||
KillTimeout: time.Minute,
|
||||
Stats: hc,
|
||||
Clock: klock,
|
||||
}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
// Start the Stop process.
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
klock.Wait(clock.Calls{After: 1}) // wait for Stop to call After
|
||||
klock.Add(down.StopTimeout) // trigger stop timeout
|
||||
klock.Wait(clock.Calls{After: 2}) // wait for Kill to call After
|
||||
klock.Add(down.KillTimeout) // trigger kill timeout
|
||||
|
||||
// We hit both the StopTimeout & the KillTimeout.
|
||||
<-finStop
|
||||
|
||||
// Then we unblock the Close, so we get an unexpected EOF since we close
|
||||
// before we finish writing the response.
|
||||
connCloseDone := make(chan struct{})
|
||||
unblockConnClose <- connCloseDone
|
||||
<-connCloseDone
|
||||
close(unblockConnClose)
|
||||
|
||||
// Then we unblock the handler which tries to write the rest of the data.
|
||||
close(unblockOkHandler)
|
||||
|
||||
_, err = ioutil.ReadAll(res.Body)
|
||||
ensure.Err(t, err, regexp.MustCompile("^unexpected EOF$"))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-statsDone
|
||||
}
|
||||
|
||||
func TestDoubleStop(t *testing.T) {
|
||||
t.Parallel()
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
ensure.Nil(t, s.Stop())
|
||||
ensure.Nil(t, s.Stop())
|
||||
}
|
||||
|
||||
func TestExistingConnState(t *testing.T) {
|
||||
t.Parallel()
|
||||
hello := []byte("hello")
|
||||
fin := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(fin)
|
||||
w.Write(hello)
|
||||
}
|
||||
|
||||
var called int32
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
ensure.Nil(t, err)
|
||||
server := &http.Server{
|
||||
Handler: http.HandlerFunc(okHandler),
|
||||
ConnState: func(c net.Conn, s http.ConnState) {
|
||||
atomic.AddInt32(&called, 1)
|
||||
},
|
||||
}
|
||||
transport := &http.Transport{}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s := down.Serve(server, listener)
|
||||
res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String()))
|
||||
ensure.Nil(t, err)
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, hello)
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
|
||||
ensure.Nil(t, s.Stop())
|
||||
<-fin
|
||||
|
||||
ensure.True(t, atomic.LoadInt32(&called) > 0)
|
||||
}
|
||||
|
||||
func TestHTTPDefaultListenError(t *testing.T) {
|
||||
if os.Getuid() == 0 {
|
||||
t.Skip("cant run this test as root")
|
||||
}
|
||||
|
||||
statsDone := make(chan struct{}, 1)
|
||||
hc := &stats.HookClient{
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
if key == "listen.error" && val == 1 {
|
||||
statsDone <- struct{}{}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
down := &httpdown.HTTP{Stats: hc}
|
||||
_, err := down.ListenAndServe(&http.Server{})
|
||||
ensure.Err(t, err, regexp.MustCompile("listen tcp :80: bind: permission denied"))
|
||||
<-statsDone
|
||||
}
|
||||
|
||||
func TestHTTPSDefaultListenError(t *testing.T) {
|
||||
if os.Getuid() == 0 {
|
||||
t.Skip("cant run this test as root")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
cert, err := tls.X509KeyPair(localhostCert, localhostKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error loading cert: %v", err)
|
||||
}
|
||||
|
||||
down := &httpdown.HTTP{}
|
||||
_, err = down.ListenAndServe(&http.Server{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: []string{"http/1.1"},
|
||||
Certificates: []tls.Certificate{cert},
|
||||
},
|
||||
})
|
||||
ensure.Err(t, err, regexp.MustCompile("listen tcp :443: bind: permission denied"))
|
||||
}
|
||||
|
||||
func TestTLS(t *testing.T) {
|
||||
t.Parallel()
|
||||
port, err := freeport.Get()
|
||||
ensure.Nil(t, err)
|
||||
|
||||
cert, err := tls.X509KeyPair(localhostCert, localhostKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error loading cert: %v", err)
|
||||
}
|
||||
const count = 10000
|
||||
hello := []byte("hello")
|
||||
finOkHandler := make(chan struct{})
|
||||
okHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
defer close(finOkHandler)
|
||||
w.WriteHeader(200)
|
||||
for i := 0; i < count; i++ {
|
||||
w.Write(hello)
|
||||
}
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf("0.0.0.0:%d", port),
|
||||
Handler: http.HandlerFunc(okHandler),
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: []string{"http/1.1"},
|
||||
Certificates: []tls.Certificate{cert},
|
||||
},
|
||||
}
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{Transport: transport}
|
||||
down := &httpdown.HTTP{}
|
||||
s, err := down.ListenAndServe(server)
|
||||
ensure.Nil(t, err)
|
||||
res, err := client.Get(fmt.Sprintf("https://%s/", server.Addr))
|
||||
ensure.Nil(t, err)
|
||||
|
||||
finStop := make(chan struct{})
|
||||
go func() {
|
||||
defer close(finStop)
|
||||
ensure.Nil(t, s.Stop())
|
||||
}()
|
||||
|
||||
actualBody, err := ioutil.ReadAll(res.Body)
|
||||
ensure.Nil(t, err)
|
||||
ensure.DeepEqual(t, actualBody, bytes.Repeat(hello, count))
|
||||
ensure.Nil(t, res.Body.Close())
|
||||
<-finOkHandler
|
||||
<-finStop
|
||||
}
|
||||
|
||||
// localhostCert is a PEM-encoded TLS cert with SAN IPs
|
||||
// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
|
||||
// of ASN.1 time).
|
||||
// generated from src/pkg/crypto/tls:
|
||||
// go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||
var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
|
||||
bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
|
||||
bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBALyCfqwwip8BvTKgVKGdmjZTU8DD
|
||||
ndR+WALmFPIRqn89bOU3s30olKiqYEju/SFoEvMyFRT/TWEhXHDaufThqaMCAwEA
|
||||
AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
|
||||
AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAr/09uy108p51rheIOSnz4zgduyTl
|
||||
M+4AmRo8/U1twEZLgfAGG/GZjREv2y4mCEUIM3HebCAqlA5jpRg76Rf8jw==
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
// localhostKey is the private key for localhostCert.
|
||||
var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOQIBAAJBALyCfqwwip8BvTKgVKGdmjZTU8DDndR+WALmFPIRqn89bOU3s30o
|
||||
lKiqYEju/SFoEvMyFRT/TWEhXHDaufThqaMCAwEAAQJAPXuWUxTV8XyAt8VhNQER
|
||||
LgzJcUKb9JVsoS1nwXgPksXnPDKnL9ax8VERrdNr+nZbj2Q9cDSXBUovfdtehcdP
|
||||
qQIhAO48ZsPylbTrmtjDEKiHT2Ik04rLotZYS2U873J6I7WlAiEAypDjYxXyafv/
|
||||
Yo1pm9onwcetQKMW8CS3AjuV9Axzj6cCIEx2Il19fEMG4zny0WPlmbrcKvD/DpJQ
|
||||
4FHrzsYlIVTpAiAas7S1uAvneqd0l02HlN9OxQKKlbUNXNme+rnOnOGS2wIgS0jW
|
||||
zl1jvrOSJeP1PpAHohWz6LOhEr8uvltWkN6x3vE=
|
||||
-----END RSA PRIVATE KEY-----`)
|
24
Godeps/_workspace/src/github.com/facebookgo/stats/.travis.yml
generated
vendored
24
Godeps/_workspace/src/github.com/facebookgo/stats/.travis.yml
generated
vendored
@ -1,24 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- go get -v code.google.com/p/go.tools/cmd/vet
|
||||
- go get -v github.com/golang/lint/golint
|
||||
- go get -v code.google.com/p/go.tools/cmd/cover
|
||||
|
||||
install:
|
||||
- go install -race -v std
|
||||
- go get -race -t -v ./...
|
||||
- go install -race -v ./...
|
||||
|
||||
script:
|
||||
- go vet ./...
|
||||
- $HOME/gopath/bin/golint .
|
||||
- go test -cpu=2 -race -v ./...
|
||||
- go test -cpu=2 -covermode=atomic ./...
|
77
Godeps/_workspace/src/github.com/facebookgo/stats/stats_test.go
generated
vendored
77
Godeps/_workspace/src/github.com/facebookgo/stats/stats_test.go
generated
vendored
@ -1,77 +0,0 @@
|
||||
package stats_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/facebookgo/ensure"
|
||||
"github.com/facebookgo/stats"
|
||||
)
|
||||
|
||||
// Ensure calling End works even when a BumpTimeHook isn't provided.
|
||||
func TestHookClientBumpTime(t *testing.T) {
|
||||
(&stats.HookClient{}).BumpTime("foo").End()
|
||||
}
|
||||
|
||||
func TestPrefixClient(t *testing.T) {
|
||||
const (
|
||||
prefix1 = "prefix1"
|
||||
prefix2 = "prefix2"
|
||||
avgKey = "avg"
|
||||
avgVal = float64(1)
|
||||
sumKey = "sum"
|
||||
sumVal = float64(2)
|
||||
histogramKey = "histogram"
|
||||
histogramVal = float64(3)
|
||||
timeKey = "time"
|
||||
)
|
||||
|
||||
var keys []string
|
||||
hc := &stats.HookClient{
|
||||
BumpAvgHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, avgVal)
|
||||
},
|
||||
BumpSumHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, sumVal)
|
||||
},
|
||||
BumpHistogramHook: func(key string, val float64) {
|
||||
keys = append(keys, key)
|
||||
ensure.DeepEqual(t, val, histogramVal)
|
||||
},
|
||||
BumpTimeHook: func(key string) interface {
|
||||
End()
|
||||
} {
|
||||
return multiEnderTest{
|
||||
EndHook: func() {
|
||||
keys = append(keys, key)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
pc := stats.PrefixClient([]string{prefix1, prefix2}, hc)
|
||||
pc.BumpAvg(avgKey, avgVal)
|
||||
pc.BumpSum(sumKey, sumVal)
|
||||
pc.BumpHistogram(histogramKey, histogramVal)
|
||||
pc.BumpTime(timeKey).End()
|
||||
|
||||
ensure.SameElements(t, keys, []string{
|
||||
prefix1 + avgKey,
|
||||
prefix1 + sumKey,
|
||||
prefix1 + histogramKey,
|
||||
prefix1 + timeKey,
|
||||
prefix2 + avgKey,
|
||||
prefix2 + sumKey,
|
||||
prefix2 + histogramKey,
|
||||
prefix2 + timeKey,
|
||||
})
|
||||
}
|
||||
|
||||
type multiEnderTest struct {
|
||||
EndHook func()
|
||||
}
|
||||
|
||||
func (e multiEnderTest) End() {
|
||||
e.EndHook()
|
||||
}
|
23
Godeps/_workspace/src/github.com/fatih/structs/.gitignore
generated
vendored
23
Godeps/_workspace/src/github.com/fatih/structs/.gitignore
generated
vendored
@ -1,23 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
11
Godeps/_workspace/src/github.com/fatih/structs/.travis.yml
generated
vendored
11
Godeps/_workspace/src/github.com/fatih/structs/.travis.yml
generated
vendored
@ -1,11 +0,0 @@
|
||||
language: go
|
||||
go: 1.3
|
||||
before_install:
|
||||
- go get github.com/axw/gocov/gocov
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get code.google.com/p/go.tools/cmd/cover
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken $COVERALLS_TOKEN
|
||||
env:
|
||||
global:
|
||||
- secure: hkc+92KPmMFqIH9n4yWdnH1JpZjahmOyDJwpTh8Yl0JieJNG0XEXpOqNao27eA0cLF+UHdyjFeGcPUJKNmgE46AoQjtovt+ICjCXKR2yF6S2kKJcUOz/Vd6boZF7qHV06jjxyxOebpID5iSoW6UfFr001bFxpd3jaSLFTzSHWRQ=
|
324
Godeps/_workspace/src/github.com/fatih/structs/field_test.go
generated
vendored
324
Godeps/_workspace/src/github.com/fatih/structs/field_test.go
generated
vendored
@ -1,324 +0,0 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A test struct that defines all cases
|
||||
type Foo struct {
|
||||
A string
|
||||
B int `structs:"y"`
|
||||
C bool `json:"c"`
|
||||
d string // not exported
|
||||
E *Baz
|
||||
x string `xml:"x"` // not exported, with tag
|
||||
Y []string
|
||||
Z map[string]interface{}
|
||||
*Bar // embedded
|
||||
}
|
||||
|
||||
type Baz struct {
|
||||
A string
|
||||
B int
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
E string
|
||||
F int
|
||||
g []string
|
||||
}
|
||||
|
||||
func newStruct() *Struct {
|
||||
b := &Bar{
|
||||
E: "example",
|
||||
F: 2,
|
||||
g: []string{"zeynep", "fatih"},
|
||||
}
|
||||
|
||||
// B and x is not initialized for testing
|
||||
f := &Foo{
|
||||
A: "gopher",
|
||||
C: true,
|
||||
d: "small",
|
||||
E: nil,
|
||||
Y: []string{"example"},
|
||||
Z: nil,
|
||||
}
|
||||
f.Bar = b
|
||||
|
||||
return New(f)
|
||||
}
|
||||
|
||||
func TestField_Set(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
f := s.Field("A")
|
||||
err := f.Set("fatih")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if f.Value().(string) != "fatih" {
|
||||
t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih")
|
||||
}
|
||||
|
||||
f = s.Field("Y")
|
||||
err = f.Set([]string{"override", "with", "this"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
sliceLen := len(f.Value().([]string))
|
||||
if sliceLen != 3 {
|
||||
t.Errorf("Setted values slice length is wrong: %d, want: %d", sliceLen, 3)
|
||||
}
|
||||
|
||||
f = s.Field("C")
|
||||
err = f.Set(false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if f.Value().(bool) {
|
||||
t.Errorf("Setted value is wrong: %s want: %s", f.Value().(bool), false)
|
||||
}
|
||||
|
||||
// let's pass a different type
|
||||
f = s.Field("A")
|
||||
err = f.Set(123) // Field A is of type string, but we are going to pass an integer
|
||||
if err == nil {
|
||||
t.Error("Setting a field's value with a different type than the field's type should return an error")
|
||||
}
|
||||
|
||||
// old value should be still there :)
|
||||
if f.Value().(string) != "fatih" {
|
||||
t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih")
|
||||
}
|
||||
|
||||
// let's access an unexported field, which should give an error
|
||||
f = s.Field("d")
|
||||
err = f.Set("large")
|
||||
if err != errNotExported {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// let's set a pointer to struct
|
||||
b := &Bar{
|
||||
E: "gopher",
|
||||
F: 2,
|
||||
}
|
||||
|
||||
f = s.Field("Bar")
|
||||
err = f.Set(b)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
baz := &Baz{
|
||||
A: "helloWorld",
|
||||
B: 42,
|
||||
}
|
||||
|
||||
f = s.Field("E")
|
||||
err = f.Set(baz)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
ba := s.Field("E").Value().(*Baz)
|
||||
|
||||
if ba.A != "helloWorld" {
|
||||
t.Errorf("could not set baz. Got: %s Want: helloWorld", ba.A)
|
||||
}
|
||||
}
|
||||
|
||||
func TestField(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Retrieveing a non existing field from the struct should panic")
|
||||
}
|
||||
}()
|
||||
|
||||
_ = s.Field("no-field")
|
||||
}
|
||||
|
||||
func TestField_Kind(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
f := s.Field("A")
|
||||
if f.Kind() != reflect.String {
|
||||
t.Errorf("Field A has wrong kind: %s want: %s", f.Kind(), reflect.String)
|
||||
}
|
||||
|
||||
f = s.Field("B")
|
||||
if f.Kind() != reflect.Int {
|
||||
t.Errorf("Field B has wrong kind: %s want: %s", f.Kind(), reflect.Int)
|
||||
}
|
||||
|
||||
// unexported
|
||||
f = s.Field("d")
|
||||
if f.Kind() != reflect.String {
|
||||
t.Errorf("Field d has wrong kind: %s want: %s", f.Kind(), reflect.String)
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_Tag(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
v := s.Field("B").Tag("json")
|
||||
if v != "" {
|
||||
t.Errorf("Field's tag value of a non existing tag should return empty, got: %s", v)
|
||||
}
|
||||
|
||||
v = s.Field("C").Tag("json")
|
||||
if v != "c" {
|
||||
t.Errorf("Field's tag value of the existing field C should return 'c', got: %s", v)
|
||||
}
|
||||
|
||||
v = s.Field("d").Tag("json")
|
||||
if v != "" {
|
||||
t.Errorf("Field's tag value of a non exported field should return empty, got: %s", v)
|
||||
}
|
||||
|
||||
v = s.Field("x").Tag("xml")
|
||||
if v != "x" {
|
||||
t.Errorf("Field's tag value of a non exported field with a tag should return 'x', got: %s", v)
|
||||
}
|
||||
|
||||
v = s.Field("A").Tag("json")
|
||||
if v != "" {
|
||||
t.Errorf("Field's tag value of a existing field without a tag should return empty, got: %s", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_Value(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
v := s.Field("A").Value()
|
||||
val, ok := v.(string)
|
||||
if !ok {
|
||||
t.Errorf("Field's value of a A should be string")
|
||||
}
|
||||
|
||||
if val != "gopher" {
|
||||
t.Errorf("Field's value of a existing tag should return 'gopher', got: %s", val)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Value of a non exported field from the field should panic")
|
||||
}
|
||||
}()
|
||||
|
||||
// should panic
|
||||
_ = s.Field("d").Value()
|
||||
}
|
||||
|
||||
func TestField_IsEmbedded(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
if !s.Field("Bar").IsEmbedded() {
|
||||
t.Errorf("Fields 'Bar' field is an embedded field")
|
||||
}
|
||||
|
||||
if s.Field("d").IsEmbedded() {
|
||||
t.Errorf("Fields 'd' field is not an embedded field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_IsExported(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
if !s.Field("Bar").IsExported() {
|
||||
t.Errorf("Fields 'Bar' field is an exported field")
|
||||
}
|
||||
|
||||
if !s.Field("A").IsExported() {
|
||||
t.Errorf("Fields 'A' field is an exported field")
|
||||
}
|
||||
|
||||
if s.Field("d").IsExported() {
|
||||
t.Errorf("Fields 'd' field is not an exported field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_IsZero(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
if s.Field("A").IsZero() {
|
||||
t.Errorf("Fields 'A' field is an initialized field")
|
||||
}
|
||||
|
||||
if !s.Field("B").IsZero() {
|
||||
t.Errorf("Fields 'B' field is not an initialized field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_Name(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
if s.Field("A").Name() != "A" {
|
||||
t.Errorf("Fields 'A' field should have the name 'A'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_Field(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
e := s.Field("Bar").Field("E")
|
||||
|
||||
val, ok := e.Value().(string)
|
||||
if !ok {
|
||||
t.Error("The value of the field 'e' inside 'Bar' struct should be string")
|
||||
}
|
||||
|
||||
if val != "example" {
|
||||
t.Errorf("The value of 'e' should be 'example, got: %s", val)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Field of a non existing nested struct should panic")
|
||||
}
|
||||
}()
|
||||
|
||||
_ = s.Field("Bar").Field("e")
|
||||
}
|
||||
|
||||
func TestField_Fields(t *testing.T) {
|
||||
s := newStruct()
|
||||
fields := s.Field("Bar").Fields()
|
||||
|
||||
if len(fields) != 3 {
|
||||
t.Errorf("We expect 3 fields in embedded struct, was: %d", len(fields))
|
||||
}
|
||||
}
|
||||
|
||||
func TestField_FieldOk(t *testing.T) {
|
||||
s := newStruct()
|
||||
|
||||
b, ok := s.FieldOk("Bar")
|
||||
if !ok {
|
||||
t.Error("The field 'Bar' should exists.")
|
||||
}
|
||||
|
||||
e, ok := b.FieldOk("E")
|
||||
if !ok {
|
||||
t.Error("The field 'E' should exists.")
|
||||
}
|
||||
|
||||
val, ok := e.Value().(string)
|
||||
if !ok {
|
||||
t.Error("The value of the field 'e' inside 'Bar' struct should be string")
|
||||
}
|
||||
|
||||
if val != "example" {
|
||||
t.Errorf("The value of 'e' should be 'example, got: %s", val)
|
||||
}
|
||||
}
|
351
Godeps/_workspace/src/github.com/fatih/structs/structs_example_test.go
generated
vendored
351
Godeps/_workspace/src/github.com/fatih/structs/structs_example_test.go
generated
vendored
@ -1,351 +0,0 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleNew() {
|
||||
type Server struct {
|
||||
Name string
|
||||
ID int32
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
server := &Server{
|
||||
Name: "Arslan",
|
||||
ID: 123456,
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
s := New(server)
|
||||
|
||||
fmt.Printf("Name : %v\n", s.Name())
|
||||
fmt.Printf("Values : %v\n", s.Values())
|
||||
fmt.Printf("Value of ID : %v\n", s.Field("ID").Value())
|
||||
// Output:
|
||||
// Name : Server
|
||||
// Values : [Arslan 123456 true]
|
||||
// Value of ID : 123456
|
||||
|
||||
}
|
||||
|
||||
func ExampleMap() {
|
||||
type Server struct {
|
||||
Name string
|
||||
ID int32
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
Name: "Arslan",
|
||||
ID: 123456,
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
m := Map(s)
|
||||
|
||||
fmt.Printf("%#v\n", m["Name"])
|
||||
fmt.Printf("%#v\n", m["ID"])
|
||||
fmt.Printf("%#v\n", m["Enabled"])
|
||||
// Output:
|
||||
// "Arslan"
|
||||
// 123456
|
||||
// true
|
||||
|
||||
}
|
||||
|
||||
func ExampleMap_tags() {
|
||||
// Custom tags can change the map keys instead of using the fields name
|
||||
type Server struct {
|
||||
Name string `structs:"server_name"`
|
||||
ID int32 `structs:"server_id"`
|
||||
Enabled bool `structs:"enabled"`
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
Name: "Zeynep",
|
||||
ID: 789012,
|
||||
}
|
||||
|
||||
m := Map(s)
|
||||
|
||||
// access them by the custom tags defined above
|
||||
fmt.Printf("%#v\n", m["server_name"])
|
||||
fmt.Printf("%#v\n", m["server_id"])
|
||||
fmt.Printf("%#v\n", m["enabled"])
|
||||
// Output:
|
||||
// "Zeynep"
|
||||
// 789012
|
||||
// false
|
||||
|
||||
}
|
||||
|
||||
func ExampleMap_nested() {
|
||||
// By default field with struct types are processed too. We can stop
|
||||
// processing them via "omitnested" tag option.
|
||||
type Server struct {
|
||||
Name string `structs:"server_name"`
|
||||
ID int32 `structs:"server_id"`
|
||||
Time time.Time `structs:"time,omitnested"` // do not convert to map[string]interface{}
|
||||
}
|
||||
|
||||
const shortForm = "2006-Jan-02"
|
||||
t, _ := time.Parse("2006-Jan-02", "2013-Feb-03")
|
||||
|
||||
s := &Server{
|
||||
Name: "Zeynep",
|
||||
ID: 789012,
|
||||
Time: t,
|
||||
}
|
||||
|
||||
m := Map(s)
|
||||
|
||||
// access them by the custom tags defined above
|
||||
fmt.Printf("%v\n", m["server_name"])
|
||||
fmt.Printf("%v\n", m["server_id"])
|
||||
fmt.Printf("%v\n", m["time"].(time.Time))
|
||||
// Output:
|
||||
// Zeynep
|
||||
// 789012
|
||||
// 2013-02-03 00:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleMap_omitEmpty() {
|
||||
// By default field with struct types of zero values are processed too. We
|
||||
// can stop processing them via "omitempty" tag option.
|
||||
type Server struct {
|
||||
Name string `structs:",omitempty"`
|
||||
ID int32 `structs:"server_id,omitempty"`
|
||||
Location string
|
||||
}
|
||||
|
||||
// Only add location
|
||||
s := &Server{
|
||||
Location: "Tokyo",
|
||||
}
|
||||
|
||||
m := Map(s)
|
||||
|
||||
// map contains only the Location field
|
||||
fmt.Printf("%v\n", m)
|
||||
// Output:
|
||||
// map[Location:Tokyo]
|
||||
}
|
||||
|
||||
func ExampleValues() {
|
||||
type Server struct {
|
||||
Name string
|
||||
ID int32
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
Name: "Fatih",
|
||||
ID: 135790,
|
||||
Enabled: false,
|
||||
}
|
||||
|
||||
m := Values(s)
|
||||
|
||||
fmt.Printf("Values: %+v\n", m)
|
||||
// Output:
|
||||
// Values: [Fatih 135790 false]
|
||||
}
|
||||
|
||||
func ExampleValues_omitEmpty() {
|
||||
// By default field with struct types of zero values are processed too. We
|
||||
// can stop processing them via "omitempty" tag option.
|
||||
type Server struct {
|
||||
Name string `structs:",omitempty"`
|
||||
ID int32 `structs:"server_id,omitempty"`
|
||||
Location string
|
||||
}
|
||||
|
||||
// Only add location
|
||||
s := &Server{
|
||||
Location: "Ankara",
|
||||
}
|
||||
|
||||
m := Values(s)
|
||||
|
||||
// values contains only the Location field
|
||||
fmt.Printf("Values: %+v\n", m)
|
||||
// Output:
|
||||
// Values: [Ankara]
|
||||
}
|
||||
|
||||
func ExampleValues_tags() {
|
||||
type Location struct {
|
||||
City string
|
||||
Country string
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Name string
|
||||
ID int32
|
||||
Enabled bool
|
||||
Location Location `structs:"-"` // values from location are not included anymore
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
Name: "Fatih",
|
||||
ID: 135790,
|
||||
Enabled: false,
|
||||
Location: Location{City: "Ankara", Country: "Turkey"},
|
||||
}
|
||||
|
||||
// Let get all values from the struct s. Note that we don't include values
|
||||
// from the Location field
|
||||
m := Values(s)
|
||||
|
||||
fmt.Printf("Values: %+v\n", m)
|
||||
// Output:
|
||||
// Values: [Fatih 135790 false]
|
||||
}
|
||||
|
||||
func ExampleFields() {
|
||||
type Access struct {
|
||||
Name string
|
||||
LastAccessed time.Time
|
||||
Number int
|
||||
}
|
||||
|
||||
s := &Access{
|
||||
Name: "Fatih",
|
||||
LastAccessed: time.Now(),
|
||||
Number: 1234567,
|
||||
}
|
||||
|
||||
fields := Fields(s)
|
||||
|
||||
for i, field := range fields {
|
||||
fmt.Printf("[%d] %+v\n", i, field.Name())
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [0] Name
|
||||
// [1] LastAccessed
|
||||
// [2] Number
|
||||
}
|
||||
|
||||
func ExampleFields_nested() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Number int
|
||||
}
|
||||
|
||||
type Access struct {
|
||||
Person Person
|
||||
HasPermission bool
|
||||
LastAccessed time.Time
|
||||
}
|
||||
|
||||
s := &Access{
|
||||
Person: Person{Name: "fatih", Number: 1234567},
|
||||
LastAccessed: time.Now(),
|
||||
HasPermission: true,
|
||||
}
|
||||
|
||||
// Let's get all fields from the struct s.
|
||||
fields := Fields(s)
|
||||
|
||||
for _, field := range fields {
|
||||
if field.Name() == "Person" {
|
||||
fmt.Printf("Access.Person.Name: %+v\n", field.Field("Name").Value())
|
||||
}
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Access.Person.Name: fatih
|
||||
}
|
||||
|
||||
func ExampleField() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Number int
|
||||
}
|
||||
|
||||
type Access struct {
|
||||
Person Person
|
||||
HasPermission bool
|
||||
LastAccessed time.Time
|
||||
}
|
||||
|
||||
access := &Access{
|
||||
Person: Person{Name: "fatih", Number: 1234567},
|
||||
LastAccessed: time.Now(),
|
||||
HasPermission: true,
|
||||
}
|
||||
|
||||
// Create a new Struct type
|
||||
s := New(access)
|
||||
|
||||
// Get the Field type for "Person" field
|
||||
p := s.Field("Person")
|
||||
|
||||
// Get the underlying "Name field" and print the value of it
|
||||
name := p.Field("Name")
|
||||
|
||||
fmt.Printf("Value of Person.Access.Name: %+v\n", name.Value())
|
||||
|
||||
// Output:
|
||||
// Value of Person.Access.Name: fatih
|
||||
|
||||
}
|
||||
|
||||
func ExampleIsZero() {
|
||||
type Server struct {
|
||||
Name string
|
||||
ID int32
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// Nothing is initalized
|
||||
a := &Server{}
|
||||
isZeroA := IsZero(a)
|
||||
|
||||
// Name and Enabled is initialized, but not ID
|
||||
b := &Server{
|
||||
Name: "Golang",
|
||||
Enabled: true,
|
||||
}
|
||||
isZeroB := IsZero(b)
|
||||
|
||||
fmt.Printf("%#v\n", isZeroA)
|
||||
fmt.Printf("%#v\n", isZeroB)
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleHasZero() {
|
||||
// Let's define an Access struct. Note that the "Enabled" field is not
|
||||
// going to be checked because we added the "structs" tag to the field.
|
||||
type Access struct {
|
||||
Name string
|
||||
LastAccessed time.Time
|
||||
Number int
|
||||
Enabled bool `structs:"-"`
|
||||
}
|
||||
|
||||
// Name and Number is not initialized.
|
||||
a := &Access{
|
||||
LastAccessed: time.Now(),
|
||||
}
|
||||
hasZeroA := HasZero(a)
|
||||
|
||||
// Name and Number is initialized.
|
||||
b := &Access{
|
||||
Name: "Fatih",
|
||||
LastAccessed: time.Now(),
|
||||
Number: 12345,
|
||||
}
|
||||
hasZeroB := HasZero(b)
|
||||
|
||||
fmt.Printf("%#v\n", hasZeroA)
|
||||
fmt.Printf("%#v\n", hasZeroB)
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
847
Godeps/_workspace/src/github.com/fatih/structs/structs_test.go
generated
vendored
847
Godeps/_workspace/src/github.com/fatih/structs/structs_test.go
generated
vendored
@ -1,847 +0,0 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMapNonStruct(t *testing.T) {
|
||||
foo := []string{"foo"}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Passing a non struct into Map should panic")
|
||||
}
|
||||
}()
|
||||
|
||||
// this should panic. We are going to recover and and test it
|
||||
_ = Map(foo)
|
||||
}
|
||||
|
||||
func TestStructIndexes(t *testing.T) {
|
||||
type C struct {
|
||||
something int
|
||||
Props map[string]interface{}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
fmt.Printf("err %+v\n", err)
|
||||
t.Error("Using mixed indexes should not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
// They should not panic
|
||||
_ = Map(&C{})
|
||||
_ = Fields(&C{})
|
||||
_ = Values(&C{})
|
||||
_ = IsZero(&C{})
|
||||
_ = HasZero(&C{})
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
var T = struct {
|
||||
A string
|
||||
B int
|
||||
C bool
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
C: true,
|
||||
}
|
||||
|
||||
a := Map(T)
|
||||
|
||||
if typ := reflect.TypeOf(a).Kind(); typ != reflect.Map {
|
||||
t.Errorf("Map should return a map type, got: %v", typ)
|
||||
}
|
||||
|
||||
// we have three fields
|
||||
if len(a) != 3 {
|
||||
t.Errorf("Map should return a map of len 3, got: %d", len(a))
|
||||
}
|
||||
|
||||
inMap := func(val interface{}) bool {
|
||||
for _, v := range a {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"a-value", 2, true} {
|
||||
if !inMap(val) {
|
||||
t.Errorf("Map should have the value %v", val)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMap_Tag(t *testing.T) {
|
||||
var T = struct {
|
||||
A string `structs:"x"`
|
||||
B int `structs:"y"`
|
||||
C bool `structs:"z"`
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
C: true,
|
||||
}
|
||||
|
||||
a := Map(T)
|
||||
|
||||
inMap := func(key interface{}) bool {
|
||||
for k := range a {
|
||||
if reflect.DeepEqual(k, key) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, key := range []string{"x", "y", "z"} {
|
||||
if !inMap(key) {
|
||||
t.Errorf("Map should have the key %v", key)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMap_CustomTag(t *testing.T) {
|
||||
var T = struct {
|
||||
A string `dd:"x"`
|
||||
B int `dd:"y"`
|
||||
C bool `dd:"z"`
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
C: true,
|
||||
}
|
||||
|
||||
s := New(T)
|
||||
s.TagName = "dd"
|
||||
|
||||
a := s.Map()
|
||||
|
||||
inMap := func(key interface{}) bool {
|
||||
for k := range a {
|
||||
if reflect.DeepEqual(k, key) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, key := range []string{"x", "y", "z"} {
|
||||
if !inMap(key) {
|
||||
t.Errorf("Map should have the key %v", key)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMap_MultipleCustomTag(t *testing.T) {
|
||||
var A = struct {
|
||||
X string `aa:"ax"`
|
||||
}{"a_value"}
|
||||
|
||||
aStruct := New(A)
|
||||
aStruct.TagName = "aa"
|
||||
|
||||
var B = struct {
|
||||
X string `bb:"bx"`
|
||||
}{"b_value"}
|
||||
|
||||
bStruct := New(B)
|
||||
bStruct.TagName = "bb"
|
||||
|
||||
a, b := aStruct.Map(), bStruct.Map()
|
||||
if !reflect.DeepEqual(a, map[string]interface{}{"ax": "a_value"}) {
|
||||
t.Error("Map should have field ax with value a_value")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(b, map[string]interface{}{"bx": "b_value"}) {
|
||||
t.Error("Map should have field bx with value b_value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap_OmitEmpty(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Value string `structs:",omitempty"`
|
||||
Time time.Time `structs:",omitempty"`
|
||||
}
|
||||
a := A{}
|
||||
|
||||
m := Map(a)
|
||||
|
||||
_, ok := m["Value"].(map[string]interface{})
|
||||
if ok {
|
||||
t.Error("Map should not contain the Value field that is tagged as omitempty")
|
||||
}
|
||||
|
||||
_, ok = m["Time"].(map[string]interface{})
|
||||
if ok {
|
||||
t.Error("Map should not contain the Time field that is tagged as omitempty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Value string
|
||||
Time time.Time `structs:",omitnested"`
|
||||
}
|
||||
a := A{Time: time.Now()}
|
||||
|
||||
type B struct {
|
||||
Desc string
|
||||
A A
|
||||
}
|
||||
b := &B{A: a}
|
||||
|
||||
m := Map(b)
|
||||
|
||||
in, ok := m["A"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Error("Map nested structs is not available in the map")
|
||||
}
|
||||
|
||||
// should not happen
|
||||
if _, ok := in["Time"].(map[string]interface{}); ok {
|
||||
t.Error("Map nested struct should omit recursiving parsing of Time")
|
||||
}
|
||||
|
||||
if _, ok := in["Time"].(time.Time); !ok {
|
||||
t.Error("Map nested struct should stop parsing of Time at is current value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap_Nested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
}
|
||||
a := &A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A *A
|
||||
}
|
||||
b := &B{A: a}
|
||||
|
||||
m := Map(b)
|
||||
|
||||
if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map {
|
||||
t.Errorf("Map should return a map type, got: %v", typ)
|
||||
}
|
||||
|
||||
in, ok := m["A"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Error("Map nested structs is not available in the map")
|
||||
}
|
||||
|
||||
if name := in["Name"].(string); name != "example" {
|
||||
t.Errorf("Map nested struct's name field should give example, got: %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap_Anonymous(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
}
|
||||
a := &A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
*A
|
||||
}
|
||||
b := &B{}
|
||||
b.A = a
|
||||
|
||||
m := Map(b)
|
||||
|
||||
if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map {
|
||||
t.Errorf("Map should return a map type, got: %v", typ)
|
||||
}
|
||||
|
||||
in, ok := m["A"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Error("Embedded structs is not available in the map")
|
||||
}
|
||||
|
||||
if name := in["Name"].(string); name != "example" {
|
||||
t.Errorf("Embedded A struct's Name field should give example, got: %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStruct(t *testing.T) {
|
||||
var T = struct{}{}
|
||||
|
||||
if !IsStruct(T) {
|
||||
t.Errorf("T should be a struct, got: %T", T)
|
||||
}
|
||||
|
||||
if !IsStruct(&T) {
|
||||
t.Errorf("T should be a struct, got: %T", T)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestValues(t *testing.T) {
|
||||
var T = struct {
|
||||
A string
|
||||
B int
|
||||
C bool
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
C: true,
|
||||
}
|
||||
|
||||
s := Values(T)
|
||||
|
||||
if typ := reflect.TypeOf(s).Kind(); typ != reflect.Slice {
|
||||
t.Errorf("Values should return a slice type, got: %v", typ)
|
||||
}
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"a-value", 2, true} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Values should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValues_OmitEmpty(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Value int `structs:",omitempty"`
|
||||
}
|
||||
|
||||
a := A{Name: "example"}
|
||||
s := Values(a)
|
||||
|
||||
if len(s) != 1 {
|
||||
t.Errorf("Values of omitted empty fields should be not counted")
|
||||
}
|
||||
|
||||
if s[0].(string) != "example" {
|
||||
t.Errorf("Values of omitted empty fields should left the value example")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValues_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Value int
|
||||
}
|
||||
|
||||
a := A{
|
||||
Name: "example",
|
||||
Value: 123,
|
||||
}
|
||||
|
||||
type B struct {
|
||||
A A `structs:",omitnested"`
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
s := Values(b)
|
||||
|
||||
if len(s) != 2 {
|
||||
t.Errorf("Values of omitted nested struct should be not counted")
|
||||
}
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{123, a} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Values should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValues_Nested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
s := Values(b)
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"example", 123} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Values should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValues_Anonymous(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A
|
||||
C int
|
||||
}
|
||||
b := &B{C: 123}
|
||||
b.A = a
|
||||
|
||||
s := Values(b)
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v, val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"example", 123} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Values should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFields(t *testing.T) {
|
||||
var T = struct {
|
||||
A string
|
||||
B int
|
||||
C bool
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
C: true,
|
||||
}
|
||||
|
||||
s := Fields(T)
|
||||
|
||||
if len(s) != 3 {
|
||||
t.Errorf("Fields should return a slice of len 3, got: %d", len(s))
|
||||
}
|
||||
|
||||
inSlice := func(val string) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v.Name(), val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []string{"A", "B", "C"} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Fields should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFields_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
Enabled bool
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A
|
||||
C int
|
||||
Value string `structs:"-"`
|
||||
Number int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
s := Fields(b)
|
||||
|
||||
if len(s) != 3 {
|
||||
t.Errorf("Fields should omit nested struct. Expecting 2 got: %d", len(s))
|
||||
}
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v.Name(), val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"A", "C"} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Fields should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFields_Anonymous(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A
|
||||
C int
|
||||
}
|
||||
b := &B{C: 123}
|
||||
b.A = a
|
||||
|
||||
s := Fields(b)
|
||||
|
||||
inSlice := func(val interface{}) bool {
|
||||
for _, v := range s {
|
||||
if reflect.DeepEqual(v.Name(), val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, val := range []interface{}{"A", "C"} {
|
||||
if !inSlice(val) {
|
||||
t.Errorf("Fields should have the value %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsZero(t *testing.T) {
|
||||
var T = struct {
|
||||
A string
|
||||
B int
|
||||
C bool `structs:"-"`
|
||||
D []string
|
||||
}{}
|
||||
|
||||
ok := IsZero(T)
|
||||
if !ok {
|
||||
t.Error("IsZero should return true because none of the fields are initialized.")
|
||||
}
|
||||
|
||||
var X = struct {
|
||||
A string
|
||||
F *bool
|
||||
}{
|
||||
A: "a-value",
|
||||
}
|
||||
|
||||
ok = IsZero(X)
|
||||
if ok {
|
||||
t.Error("IsZero should return false because A is initialized")
|
||||
}
|
||||
|
||||
var Y = struct {
|
||||
A string
|
||||
B int
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 123,
|
||||
}
|
||||
|
||||
ok = IsZero(Y)
|
||||
if ok {
|
||||
t.Error("IsZero should return false because A and B is initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsZero_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A `structs:",omitnested"`
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
ok := IsZero(b)
|
||||
if ok {
|
||||
t.Error("IsZero should return false because A, B and C are initialized")
|
||||
}
|
||||
|
||||
aZero := A{}
|
||||
bZero := &B{A: aZero}
|
||||
|
||||
ok = IsZero(bZero)
|
||||
if !ok {
|
||||
t.Error("IsZero should return true because neither A nor B is initialized")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsZero_Nested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
ok := IsZero(b)
|
||||
if ok {
|
||||
t.Error("IsZero should return false because A, B and C are initialized")
|
||||
}
|
||||
|
||||
aZero := A{}
|
||||
bZero := &B{A: aZero}
|
||||
|
||||
ok = IsZero(bZero)
|
||||
if !ok {
|
||||
t.Error("IsZero should return true because neither A nor B is initialized")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsZero_Anonymous(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A
|
||||
C int
|
||||
}
|
||||
b := &B{C: 123}
|
||||
b.A = a
|
||||
|
||||
ok := IsZero(b)
|
||||
if ok {
|
||||
t.Error("IsZero should return false because A, B and C are initialized")
|
||||
}
|
||||
|
||||
aZero := A{}
|
||||
bZero := &B{}
|
||||
bZero.A = aZero
|
||||
|
||||
ok = IsZero(bZero)
|
||||
if !ok {
|
||||
t.Error("IsZero should return true because neither A nor B is initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasZero(t *testing.T) {
|
||||
var T = struct {
|
||||
A string
|
||||
B int
|
||||
C bool `structs:"-"`
|
||||
D []string
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 2,
|
||||
}
|
||||
|
||||
ok := HasZero(T)
|
||||
if !ok {
|
||||
t.Error("HasZero should return true because A and B are initialized.")
|
||||
}
|
||||
|
||||
var X = struct {
|
||||
A string
|
||||
F *bool
|
||||
}{
|
||||
A: "a-value",
|
||||
}
|
||||
|
||||
ok = HasZero(X)
|
||||
if !ok {
|
||||
t.Error("HasZero should return true because A is initialized")
|
||||
}
|
||||
|
||||
var Y = struct {
|
||||
A string
|
||||
B int
|
||||
}{
|
||||
A: "a-value",
|
||||
B: 123,
|
||||
}
|
||||
|
||||
ok = HasZero(Y)
|
||||
if ok {
|
||||
t.Error("HasZero should return false because A and B is initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasZero_OmitNested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A `structs:",omitnested"`
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
// Because the Field A inside B is omitted HasZero should return false
|
||||
// because it will stop iterating deeper andnot going to lookup for D
|
||||
ok := HasZero(b)
|
||||
if ok {
|
||||
t.Error("HasZero should return false because A and C are initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasZero_Nested(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A A
|
||||
C int
|
||||
}
|
||||
b := &B{A: a, C: 123}
|
||||
|
||||
ok := HasZero(b)
|
||||
if !ok {
|
||||
t.Error("HasZero should return true because D is not initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasZero_Anonymous(t *testing.T) {
|
||||
type A struct {
|
||||
Name string
|
||||
D string
|
||||
}
|
||||
a := A{Name: "example"}
|
||||
|
||||
type B struct {
|
||||
A
|
||||
C int
|
||||
}
|
||||
b := &B{C: 123}
|
||||
b.A = a
|
||||
|
||||
ok := HasZero(b)
|
||||
if !ok {
|
||||
t.Error("HasZero should return false because D is not initialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
type Foo struct {
|
||||
A string
|
||||
B bool
|
||||
}
|
||||
f := &Foo{}
|
||||
|
||||
n := Name(f)
|
||||
if n != "Foo" {
|
||||
t.Errorf("Name should return Foo, got: %s", n)
|
||||
}
|
||||
|
||||
unnamed := struct{ Name string }{Name: "Cihangir"}
|
||||
m := Name(unnamed)
|
||||
if m != "" {
|
||||
t.Errorf("Name should return empty string for unnamed struct, got: %s", n)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Name should panic if a non struct is passed")
|
||||
}
|
||||
}()
|
||||
|
||||
Name([]string{})
|
||||
}
|
||||
|
||||
func TestNestedNilPointer(t *testing.T) {
|
||||
type Collar struct {
|
||||
Engraving string
|
||||
}
|
||||
|
||||
type Dog struct {
|
||||
Name string
|
||||
Collar *Collar
|
||||
}
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
Dog *Dog
|
||||
}
|
||||
|
||||
person := &Person{
|
||||
Name: "John",
|
||||
}
|
||||
|
||||
personWithDog := &Person{
|
||||
Name: "Ron",
|
||||
Dog: &Dog{
|
||||
Name: "Rover",
|
||||
},
|
||||
}
|
||||
|
||||
personWithDogWithCollar := &Person{
|
||||
Name: "Kon",
|
||||
Dog: &Dog{
|
||||
Name: "Ruffles",
|
||||
Collar: &Collar{
|
||||
Engraving: "If lost, call Kon",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
fmt.Printf("err %+v\n", err)
|
||||
t.Error("Internal nil pointer should not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
_ = Map(person) // Panics
|
||||
_ = Map(personWithDog) // Panics
|
||||
_ = Map(personWithDogWithCollar) // Doesn't panic
|
||||
}
|
46
Godeps/_workspace/src/github.com/fatih/structs/tags_test.go
generated
vendored
46
Godeps/_workspace/src/github.com/fatih/structs/tags_test.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
package structs
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseTag_Name(t *testing.T) {
|
||||
tags := []struct {
|
||||
tag string
|
||||
has bool
|
||||
}{
|
||||
{"", false},
|
||||
{"name", true},
|
||||
{"name,opt", true},
|
||||
{"name , opt, opt2", false}, // has a single whitespace
|
||||
{", opt, opt2", false},
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
name, _ := parseTag(tag.tag)
|
||||
|
||||
if (name != "name") && tag.has {
|
||||
t.Errorf("Parse tag should return name: %#v", tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTag_Opts(t *testing.T) {
|
||||
tags := []struct {
|
||||
opts string
|
||||
has bool
|
||||
}{
|
||||
{"name", false},
|
||||
{"name,opt", true},
|
||||
{"name , opt, opt2", false}, // has a single whitespace
|
||||
{",opt, opt2", true},
|
||||
{", opt3, opt4", false},
|
||||
}
|
||||
|
||||
// search for "opt"
|
||||
for _, tag := range tags {
|
||||
_, opts := parseTag(tag.opts)
|
||||
|
||||
if opts.Has("opt") != tag.has {
|
||||
t.Errorf("Tag opts should have opt: %#v", tag)
|
||||
}
|
||||
}
|
||||
}
|
7
Godeps/_workspace/src/github.com/gorilla/context/.travis.yml
generated
vendored
7
Godeps/_workspace/src/github.com/gorilla/context/.travis.yml
generated
vendored
@ -1,7 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.0
|
||||
- 1.1
|
||||
- 1.2
|
||||
- tip
|
161
Godeps/_workspace/src/github.com/gorilla/context/context_test.go
generated
vendored
161
Godeps/_workspace/src/github.com/gorilla/context/context_test.go
generated
vendored
@ -1,161 +0,0 @@
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type keyType int
|
||||
|
||||
const (
|
||||
key1 keyType = iota
|
||||
key2
|
||||
)
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
assertEqual := func(val interface{}, exp interface{}) {
|
||||
if val != exp {
|
||||
t.Errorf("Expected %v, got %v.", exp, val)
|
||||
}
|
||||
}
|
||||
|
||||
r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||
emptyR, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||
|
||||
// Get()
|
||||
assertEqual(Get(r, key1), nil)
|
||||
|
||||
// Set()
|
||||
Set(r, key1, "1")
|
||||
assertEqual(Get(r, key1), "1")
|
||||
assertEqual(len(data[r]), 1)
|
||||
|
||||
Set(r, key2, "2")
|
||||
assertEqual(Get(r, key2), "2")
|
||||
assertEqual(len(data[r]), 2)
|
||||
|
||||
//GetOk
|
||||
value, ok := GetOk(r, key1)
|
||||
assertEqual(value, "1")
|
||||
assertEqual(ok, true)
|
||||
|
||||
value, ok = GetOk(r, "not exists")
|
||||
assertEqual(value, nil)
|
||||
assertEqual(ok, false)
|
||||
|
||||
Set(r, "nil value", nil)
|
||||
value, ok = GetOk(r, "nil value")
|
||||
assertEqual(value, nil)
|
||||
assertEqual(ok, true)
|
||||
|
||||
// GetAll()
|
||||
values := GetAll(r)
|
||||
assertEqual(len(values), 3)
|
||||
|
||||
// GetAll() for empty request
|
||||
values = GetAll(emptyR)
|
||||
if values != nil {
|
||||
t.Error("GetAll didn't return nil value for invalid request")
|
||||
}
|
||||
|
||||
// GetAllOk()
|
||||
values, ok = GetAllOk(r)
|
||||
assertEqual(len(values), 3)
|
||||
assertEqual(ok, true)
|
||||
|
||||
// GetAllOk() for empty request
|
||||
values, ok = GetAllOk(emptyR)
|
||||
assertEqual(value, nil)
|
||||
assertEqual(ok, false)
|
||||
|
||||
// Delete()
|
||||
Delete(r, key1)
|
||||
assertEqual(Get(r, key1), nil)
|
||||
assertEqual(len(data[r]), 2)
|
||||
|
||||
Delete(r, key2)
|
||||
assertEqual(Get(r, key2), nil)
|
||||
assertEqual(len(data[r]), 1)
|
||||
|
||||
// Clear()
|
||||
Clear(r)
|
||||
assertEqual(len(data), 0)
|
||||
}
|
||||
|
||||
func parallelReader(r *http.Request, key string, iterations int, wait, done chan struct{}) {
|
||||
<-wait
|
||||
for i := 0; i < iterations; i++ {
|
||||
Get(r, key)
|
||||
}
|
||||
done <- struct{}{}
|
||||
|
||||
}
|
||||
|
||||
func parallelWriter(r *http.Request, key, value string, iterations int, wait, done chan struct{}) {
|
||||
<-wait
|
||||
for i := 0; i < iterations; i++ {
|
||||
Set(r, key, value)
|
||||
}
|
||||
done <- struct{}{}
|
||||
|
||||
}
|
||||
|
||||
func benchmarkMutex(b *testing.B, numReaders, numWriters, iterations int) {
|
||||
|
||||
b.StopTimer()
|
||||
r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||
done := make(chan struct{})
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
wait := make(chan struct{})
|
||||
|
||||
for i := 0; i < numReaders; i++ {
|
||||
go parallelReader(r, "test", iterations, wait, done)
|
||||
}
|
||||
|
||||
for i := 0; i < numWriters; i++ {
|
||||
go parallelWriter(r, "test", "123", iterations, wait, done)
|
||||
}
|
||||
|
||||
close(wait)
|
||||
|
||||
for i := 0; i < numReaders+numWriters; i++ {
|
||||
<-done
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkMutexSameReadWrite1(b *testing.B) {
|
||||
benchmarkMutex(b, 1, 1, 32)
|
||||
}
|
||||
func BenchmarkMutexSameReadWrite2(b *testing.B) {
|
||||
benchmarkMutex(b, 2, 2, 32)
|
||||
}
|
||||
func BenchmarkMutexSameReadWrite4(b *testing.B) {
|
||||
benchmarkMutex(b, 4, 4, 32)
|
||||
}
|
||||
func BenchmarkMutex1(b *testing.B) {
|
||||
benchmarkMutex(b, 2, 8, 32)
|
||||
}
|
||||
func BenchmarkMutex2(b *testing.B) {
|
||||
benchmarkMutex(b, 16, 4, 64)
|
||||
}
|
||||
func BenchmarkMutex3(b *testing.B) {
|
||||
benchmarkMutex(b, 1, 2, 128)
|
||||
}
|
||||
func BenchmarkMutex4(b *testing.B) {
|
||||
benchmarkMutex(b, 128, 32, 256)
|
||||
}
|
||||
func BenchmarkMutex5(b *testing.B) {
|
||||
benchmarkMutex(b, 1024, 2048, 64)
|
||||
}
|
||||
func BenchmarkMutex6(b *testing.B) {
|
||||
benchmarkMutex(b, 2048, 1024, 512)
|
||||
}
|
7
Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml
generated
vendored
7
Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml
generated
vendored
@ -1,7 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.0
|
||||
- 1.1
|
||||
- 1.2
|
||||
- tip
|
7
Godeps/_workspace/src/github.com/gorilla/mux/README.md
generated
vendored
7
Godeps/_workspace/src/github.com/gorilla/mux/README.md
generated
vendored
@ -1,7 +0,0 @@
|
||||
mux
|
||||
===
|
||||
[![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux)
|
||||
|
||||
gorilla/mux is a powerful URL router and dispatcher.
|
||||
|
||||
Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux
|
21
Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go
generated
vendored
21
Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mux
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMux(b *testing.B) {
|
||||
router := new(Router)
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {}
|
||||
router.HandleFunc("/v1/{v1}", handler)
|
||||
|
||||
request, _ := http.NewRequest("GET", "/v1/anything", nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
router.ServeHTTP(nil, request)
|
||||
}
|
||||
}
|
943
Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go
generated
vendored
943
Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go
generated
vendored
@ -1,943 +0,0 @@
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/context"
|
||||
)
|
||||
|
||||
type routeTest struct {
|
||||
title string // title of the test
|
||||
route *Route // the route being tested
|
||||
request *http.Request // a request to test the route
|
||||
vars map[string]string // the expected vars of the match
|
||||
host string // the expected host of the match
|
||||
path string // the expected path of the match
|
||||
shouldMatch bool // whether the request is expected to match the route at all
|
||||
shouldRedirect bool // whether the request should result in a redirect
|
||||
}
|
||||
|
||||
func TestHost(t *testing.T) {
|
||||
// newRequestHost a new request with a method, url, and host header
|
||||
newRequestHost := func(method, url, host string) *http.Request {
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Host = host
|
||||
return req
|
||||
}
|
||||
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Host route match",
|
||||
route: new(Route).Host("aaa.bbb.ccc"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host route, wrong host in request URL",
|
||||
route: new(Route).Host("aaa.bbb.ccc"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host route with port, match",
|
||||
route: new(Route).Host("aaa.bbb.ccc:1234"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc:1234/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc:1234",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host route with port, wrong port in request URL",
|
||||
route: new(Route).Host("aaa.bbb.ccc:1234"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc:9999/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc:1234",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host route, match with host in request header",
|
||||
route: new(Route).Host("aaa.bbb.ccc"),
|
||||
request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host route, wrong host in request header",
|
||||
route: new(Route).Host("aaa.bbb.ccc"),
|
||||
request: newRequestHost("GET", "/111/222/333", "aaa.222.ccc"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
// BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true},
|
||||
{
|
||||
title: "Host route with port, wrong host in request header",
|
||||
route: new(Route).Host("aaa.bbb.ccc:1234"),
|
||||
request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:9999"),
|
||||
vars: map[string]string{},
|
||||
host: "aaa.bbb.ccc:1234",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host route with pattern, match",
|
||||
route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "bbb"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host route with pattern, wrong host in request URL",
|
||||
route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "bbb"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host route with multiple patterns, match",
|
||||
route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host route with multiple patterns, wrong host in request URL",
|
||||
route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPath(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Path route, match",
|
||||
route: new(Route).Path("/111/222/333"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route, match with trailing slash in request and path",
|
||||
route: new(Route).Path("/111/"),
|
||||
request: newRequest("GET", "http://localhost/111/"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route, do not match with trailing slash in path",
|
||||
route: new(Route).Path("/111/"),
|
||||
request: newRequest("GET", "http://localhost/111"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Path route, do not match with trailing slash in request",
|
||||
route: new(Route).Path("/111"),
|
||||
request: newRequest("GET", "http://localhost/111/"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Path route, wrong path in request in request URL",
|
||||
route: new(Route).Path("/111/222/333"),
|
||||
request: newRequest("GET", "http://localhost/1/2/3"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Path route with pattern, match",
|
||||
route: new(Route).Path("/111/{v1:[0-9]{3}}/333"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{"v1": "222"},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route with pattern, URL in request does not match",
|
||||
route: new(Route).Path("/111/{v1:[0-9]{3}}/333"),
|
||||
request: newRequest("GET", "http://localhost/111/aaa/333"),
|
||||
vars: map[string]string{"v1": "222"},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Path route with multiple patterns, match",
|
||||
route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route with multiple patterns, URL in request does not match",
|
||||
route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/aaa/333"),
|
||||
vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"},
|
||||
host: "",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathPrefix(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "PathPrefix route, match",
|
||||
route: new(Route).PathPrefix("/111"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route, match substring",
|
||||
route: new(Route).PathPrefix("/1"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route, URL prefix in request does not match",
|
||||
route: new(Route).PathPrefix("/111"),
|
||||
request: newRequest("GET", "http://localhost/1/2/3"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route with pattern, match",
|
||||
route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{"v1": "222"},
|
||||
host: "",
|
||||
path: "/111/222",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route with pattern, URL prefix in request does not match",
|
||||
route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/aaa/333"),
|
||||
vars: map[string]string{"v1": "222"},
|
||||
host: "",
|
||||
path: "/111/222",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route with multiple patterns, match",
|
||||
route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/222/333"),
|
||||
vars: map[string]string{"v1": "111", "v2": "222"},
|
||||
host: "",
|
||||
path: "/111/222",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "PathPrefix route with multiple patterns, URL prefix in request does not match",
|
||||
route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://localhost/111/aaa/333"),
|
||||
vars: map[string]string{"v1": "111", "v2": "222"},
|
||||
host: "",
|
||||
path: "/111/222",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHostPath(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Host and Path route, match",
|
||||
route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host and Path route, wrong host in request URL",
|
||||
route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host and Path route with pattern, match",
|
||||
route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "bbb", "v2": "222"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host and Path route with pattern, URL in request does not match",
|
||||
route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "bbb", "v2": "222"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Host and Path route with multiple patterns, match",
|
||||
route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Host and Path route with multiple patterns, URL in request does not match",
|
||||
route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"),
|
||||
request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"},
|
||||
host: "aaa.bbb.ccc",
|
||||
path: "/111/222/333",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders(t *testing.T) {
|
||||
// newRequestHeaders creates a new request with a method, url, and headers
|
||||
newRequestHeaders := func(method, url string, headers map[string]string) *http.Request {
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for k, v := range headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Headers route, match",
|
||||
route: new(Route).Headers("foo", "bar", "baz", "ding"),
|
||||
request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "ding"}),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Headers route, bad header values",
|
||||
route: new(Route).Headers("foo", "bar", "baz", "ding"),
|
||||
request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "dong"}),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMethods(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Methods route, match GET",
|
||||
route: new(Route).Methods("GET", "POST"),
|
||||
request: newRequest("GET", "http://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Methods route, match POST",
|
||||
route: new(Route).Methods("GET", "POST"),
|
||||
request: newRequest("POST", "http://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Methods route, bad method",
|
||||
route: new(Route).Methods("GET", "POST"),
|
||||
request: newRequest("PUT", "http://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueries(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Queries route, match",
|
||||
route: new(Route).Queries("foo", "bar", "baz", "ding"),
|
||||
request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route, match with a query string",
|
||||
route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"),
|
||||
request: newRequest("GET", "http://www.example.com/api?foo=bar&baz=ding"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route, match with a query string out of order",
|
||||
route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"),
|
||||
request: newRequest("GET", "http://www.example.com/api?baz=ding&foo=bar"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route, bad query",
|
||||
route: new(Route).Queries("foo", "bar", "baz", "ding"),
|
||||
request: newRequest("GET", "http://localhost?foo=bar&baz=dong"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Queries route with pattern, match",
|
||||
route: new(Route).Queries("foo", "{v1}"),
|
||||
request: newRequest("GET", "http://localhost?foo=bar"),
|
||||
vars: map[string]string{"v1": "bar"},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route with multiple patterns, match",
|
||||
route: new(Route).Queries("foo", "{v1}", "baz", "{v2}"),
|
||||
request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
|
||||
vars: map[string]string{"v1": "bar", "v2": "ding"},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route with regexp pattern, match",
|
||||
route: new(Route).Queries("foo", "{v1:[0-9]+}"),
|
||||
request: newRequest("GET", "http://localhost?foo=10"),
|
||||
vars: map[string]string{"v1": "10"},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Queries route with regexp pattern, regexp does not match",
|
||||
route: new(Route).Queries("foo", "{v1:[0-9]+}"),
|
||||
request: newRequest("GET", "http://localhost?foo=a"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchemes(t *testing.T) {
|
||||
tests := []routeTest{
|
||||
// Schemes
|
||||
{
|
||||
title: "Schemes route, match https",
|
||||
route: new(Route).Schemes("https", "ftp"),
|
||||
request: newRequest("GET", "https://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Schemes route, match ftp",
|
||||
route: new(Route).Schemes("https", "ftp"),
|
||||
request: newRequest("GET", "ftp://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Schemes route, bad scheme",
|
||||
route: new(Route).Schemes("https", "ftp"),
|
||||
request: newRequest("GET", "http://localhost"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatcherFunc(t *testing.T) {
|
||||
m := func(r *http.Request, m *RouteMatch) bool {
|
||||
if r.URL.Host == "aaa.bbb.ccc" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "MatchFunc route, match",
|
||||
route: new(Route).MatcherFunc(m),
|
||||
request: newRequest("GET", "http://aaa.bbb.ccc"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "MatchFunc route, non-match",
|
||||
route: new(Route).MatcherFunc(m),
|
||||
request: newRequest("GET", "http://aaa.222.ccc"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubRouter(t *testing.T) {
|
||||
subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter()
|
||||
subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter()
|
||||
|
||||
tests := []routeTest{
|
||||
{
|
||||
route: subrouter1.Path("/{v2:[a-z]+}"),
|
||||
request: newRequest("GET", "http://aaa.google.com/bbb"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb"},
|
||||
host: "aaa.google.com",
|
||||
path: "/bbb",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
route: subrouter1.Path("/{v2:[a-z]+}"),
|
||||
request: newRequest("GET", "http://111.google.com/111"),
|
||||
vars: map[string]string{"v1": "aaa", "v2": "bbb"},
|
||||
host: "aaa.google.com",
|
||||
path: "/bbb",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
route: subrouter2.Path("/baz/{v2}"),
|
||||
request: newRequest("GET", "http://localhost/foo/bar/baz/ding"),
|
||||
vars: map[string]string{"v1": "bar", "v2": "ding"},
|
||||
host: "",
|
||||
path: "/foo/bar/baz/ding",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
route: subrouter2.Path("/baz/{v2}"),
|
||||
request: newRequest("GET", "http://localhost/foo/bar"),
|
||||
vars: map[string]string{"v1": "bar", "v2": "ding"},
|
||||
host: "",
|
||||
path: "/foo/bar/baz/ding",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedRoutes(t *testing.T) {
|
||||
r1 := NewRouter()
|
||||
r1.NewRoute().Name("a")
|
||||
r1.NewRoute().Name("b")
|
||||
r1.NewRoute().Name("c")
|
||||
|
||||
r2 := r1.NewRoute().Subrouter()
|
||||
r2.NewRoute().Name("d")
|
||||
r2.NewRoute().Name("e")
|
||||
r2.NewRoute().Name("f")
|
||||
|
||||
r3 := r2.NewRoute().Subrouter()
|
||||
r3.NewRoute().Name("g")
|
||||
r3.NewRoute().Name("h")
|
||||
r3.NewRoute().Name("i")
|
||||
|
||||
if r1.namedRoutes == nil || len(r1.namedRoutes) != 9 {
|
||||
t.Errorf("Expected 9 named routes, got %v", r1.namedRoutes)
|
||||
} else if r1.Get("i") == nil {
|
||||
t.Errorf("Subroute name not registered")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrictSlash(t *testing.T) {
|
||||
r := NewRouter()
|
||||
r.StrictSlash(true)
|
||||
|
||||
tests := []routeTest{
|
||||
{
|
||||
title: "Redirect path without slash",
|
||||
route: r.NewRoute().Path("/111/"),
|
||||
request: newRequest("GET", "http://localhost/111"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: true,
|
||||
},
|
||||
{
|
||||
title: "Do not redirect path with slash",
|
||||
route: r.NewRoute().Path("/111/"),
|
||||
request: newRequest("GET", "http://localhost/111/"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111/",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: false,
|
||||
},
|
||||
{
|
||||
title: "Redirect path with slash",
|
||||
route: r.NewRoute().Path("/111"),
|
||||
request: newRequest("GET", "http://localhost/111/"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: true,
|
||||
},
|
||||
{
|
||||
title: "Do not redirect path without slash",
|
||||
route: r.NewRoute().Path("/111"),
|
||||
request: newRequest("GET", "http://localhost/111"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/111",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: false,
|
||||
},
|
||||
{
|
||||
title: "Propagate StrictSlash to subrouters",
|
||||
route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"),
|
||||
request: newRequest("GET", "http://localhost/static/images"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/static/images/",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: true,
|
||||
},
|
||||
{
|
||||
title: "Ignore StrictSlash for path prefix",
|
||||
route: r.NewRoute().PathPrefix("/static/"),
|
||||
request: newRequest("GET", "http://localhost/static/logo.png"),
|
||||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "/static/",
|
||||
shouldMatch: true,
|
||||
shouldRedirect: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func getRouteTemplate(route *Route) string {
|
||||
host, path := "none", "none"
|
||||
if route.regexp != nil {
|
||||
if route.regexp.host != nil {
|
||||
host = route.regexp.host.template
|
||||
}
|
||||
if route.regexp.path != nil {
|
||||
path = route.regexp.path.template
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("Host: %v, Path: %v", host, path)
|
||||
}
|
||||
|
||||
func testRoute(t *testing.T, test routeTest) {
|
||||
request := test.request
|
||||
route := test.route
|
||||
vars := test.vars
|
||||
shouldMatch := test.shouldMatch
|
||||
host := test.host
|
||||
path := test.path
|
||||
url := test.host + test.path
|
||||
shouldRedirect := test.shouldRedirect
|
||||
|
||||
var match RouteMatch
|
||||
ok := route.Match(request, &match)
|
||||
if ok != shouldMatch {
|
||||
msg := "Should match"
|
||||
if !shouldMatch {
|
||||
msg = "Should not match"
|
||||
}
|
||||
t.Errorf("(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n", test.title, msg, route, request, vars)
|
||||
return
|
||||
}
|
||||
if shouldMatch {
|
||||
if test.vars != nil && !stringMapEqual(test.vars, match.Vars) {
|
||||
t.Errorf("(%v) Vars not equal: expected %v, got %v", test.title, vars, match.Vars)
|
||||
return
|
||||
}
|
||||
if host != "" {
|
||||
u, _ := test.route.URLHost(mapToPairs(match.Vars)...)
|
||||
if host != u.Host {
|
||||
t.Errorf("(%v) URLHost not equal: expected %v, got %v -- %v", test.title, host, u.Host, getRouteTemplate(route))
|
||||
return
|
||||
}
|
||||
}
|
||||
if path != "" {
|
||||
u, _ := route.URLPath(mapToPairs(match.Vars)...)
|
||||
if path != u.Path {
|
||||
t.Errorf("(%v) URLPath not equal: expected %v, got %v -- %v", test.title, path, u.Path, getRouteTemplate(route))
|
||||
return
|
||||
}
|
||||
}
|
||||
if url != "" {
|
||||
u, _ := route.URL(mapToPairs(match.Vars)...)
|
||||
if url != u.Host+u.Path {
|
||||
t.Errorf("(%v) URL not equal: expected %v, got %v -- %v", test.title, url, u.Host+u.Path, getRouteTemplate(route))
|
||||
return
|
||||
}
|
||||
}
|
||||
if shouldRedirect && match.Handler == nil {
|
||||
t.Errorf("(%v) Did not redirect", test.title)
|
||||
return
|
||||
}
|
||||
if !shouldRedirect && match.Handler != nil {
|
||||
t.Errorf("(%v) Unexpected redirect", test.title)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that the context is cleared or not cleared properly depending on
|
||||
// the configuration of the router
|
||||
func TestKeepContext(t *testing.T) {
|
||||
func1 := func(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
r := NewRouter()
|
||||
r.HandleFunc("/", func1).Name("func1")
|
||||
|
||||
req, _ := http.NewRequest("GET", "http://localhost/", nil)
|
||||
context.Set(req, "t", 1)
|
||||
|
||||
res := new(http.ResponseWriter)
|
||||
r.ServeHTTP(*res, req)
|
||||
|
||||
if _, ok := context.GetOk(req, "t"); ok {
|
||||
t.Error("Context should have been cleared at end of request")
|
||||
}
|
||||
|
||||
r.KeepContext = true
|
||||
|
||||
req, _ = http.NewRequest("GET", "http://localhost/", nil)
|
||||
context.Set(req, "t", 1)
|
||||
|
||||
r.ServeHTTP(*res, req)
|
||||
if _, ok := context.GetOk(req, "t"); !ok {
|
||||
t.Error("Context should NOT have been cleared at end of request")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type TestA301ResponseWriter struct {
|
||||
hh http.Header
|
||||
status int
|
||||
}
|
||||
|
||||
func (ho TestA301ResponseWriter) Header() http.Header {
|
||||
return http.Header(ho.hh)
|
||||
}
|
||||
|
||||
func (ho TestA301ResponseWriter) Write(b []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (ho TestA301ResponseWriter) WriteHeader(code int) {
|
||||
ho.status = code
|
||||
}
|
||||
|
||||
func Test301Redirect(t *testing.T) {
|
||||
m := make(http.Header)
|
||||
|
||||
func1 := func(w http.ResponseWriter, r *http.Request) {}
|
||||
func2 := func(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
r := NewRouter()
|
||||
r.HandleFunc("/api/", func2).Name("func2")
|
||||
r.HandleFunc("/", func1).Name("func1")
|
||||
|
||||
req, _ := http.NewRequest("GET", "http://localhost//api/?abc=def", nil)
|
||||
|
||||
res := TestA301ResponseWriter{
|
||||
hh: m,
|
||||
status: 0,
|
||||
}
|
||||
r.ServeHTTP(&res, req)
|
||||
|
||||
if "http://localhost/api/?abc=def" != res.hh["Location"][0] {
|
||||
t.Errorf("Should have complete URL with query string")
|
||||
}
|
||||
}
|
||||
|
||||
// https://plus.google.com/101022900381697718949/posts/eWy6DjFJ6uW
|
||||
func TestSubrouterHeader(t *testing.T) {
|
||||
expected := "func1 response"
|
||||
func1 := func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, expected)
|
||||
}
|
||||
func2 := func(http.ResponseWriter, *http.Request) {}
|
||||
|
||||
r := NewRouter()
|
||||
s := r.Headers("SomeSpecialHeader", "").Subrouter()
|
||||
s.HandleFunc("/", func1).Name("func1")
|
||||
r.HandleFunc("/", func2).Name("func2")
|
||||
|
||||
req, _ := http.NewRequest("GET", "http://localhost/", nil)
|
||||
req.Header.Add("SomeSpecialHeader", "foo")
|
||||
match := new(RouteMatch)
|
||||
matched := r.Match(req, match)
|
||||
if !matched {
|
||||
t.Errorf("Should match request")
|
||||
}
|
||||
if match.Route.GetName() != "func1" {
|
||||
t.Errorf("Expecting func1 handler, got %s", match.Route.GetName())
|
||||
}
|
||||
resp := NewRecorder()
|
||||
match.Handler.ServeHTTP(resp, req)
|
||||
if resp.Body.String() != expected {
|
||||
t.Errorf("Expecting %q", expected)
|
||||
}
|
||||
}
|
||||
|
||||
// mapToPairs converts a string map to a slice of string pairs
|
||||
func mapToPairs(m map[string]string) []string {
|
||||
var i int
|
||||
p := make([]string, len(m)*2)
|
||||
for k, v := range m {
|
||||
p[i] = k
|
||||
p[i+1] = v
|
||||
i += 2
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// stringMapEqual checks the equality of two string maps
|
||||
func stringMapEqual(m1, m2 map[string]string) bool {
|
||||
nil1 := m1 == nil
|
||||
nil2 := m2 == nil
|
||||
if nil1 != nil2 || len(m1) != len(m2) {
|
||||
return false
|
||||
}
|
||||
for k, v := range m1 {
|
||||
if v != m2[k] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// newRequest is a helper function to create a new request with a method and url
|
||||
func newRequest(method, url string) *http.Request {
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return req
|
||||
}
|
714
Godeps/_workspace/src/github.com/gorilla/mux/old_test.go
generated
vendored
714
Godeps/_workspace/src/github.com/gorilla/mux/old_test.go
generated
vendored
@ -1,714 +0,0 @@
|
||||
// Old tests ported to Go1. This is a mess. Want to drop it one day.
|
||||
|
||||
// Copyright 2011 Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mux
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ResponseRecorder
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// ResponseRecorder is an implementation of http.ResponseWriter that
|
||||
// records its mutations for later inspection in tests.
|
||||
type ResponseRecorder struct {
|
||||
Code int // the HTTP response code from WriteHeader
|
||||
HeaderMap http.Header // the HTTP response headers
|
||||
Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
|
||||
Flushed bool
|
||||
}
|
||||
|
||||
// NewRecorder returns an initialized ResponseRecorder.
|
||||
func NewRecorder() *ResponseRecorder {
|
||||
return &ResponseRecorder{
|
||||
HeaderMap: make(http.Header),
|
||||
Body: new(bytes.Buffer),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultRemoteAddr is the default remote address to return in RemoteAddr if
|
||||
// an explicit DefaultRemoteAddr isn't set on ResponseRecorder.
|
||||
const DefaultRemoteAddr = "1.2.3.4"
|
||||
|
||||
// Header returns the response headers.
|
||||
func (rw *ResponseRecorder) Header() http.Header {
|
||||
return rw.HeaderMap
|
||||
}
|
||||
|
||||
// Write always succeeds and writes to rw.Body, if not nil.
|
||||
func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
|
||||
if rw.Body != nil {
|
||||
rw.Body.Write(buf)
|
||||
}
|
||||
if rw.Code == 0 {
|
||||
rw.Code = http.StatusOK
|
||||
}
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
// WriteHeader sets rw.Code.
|
||||
func (rw *ResponseRecorder) WriteHeader(code int) {
|
||||
rw.Code = code
|
||||
}
|
||||
|
||||
// Flush sets rw.Flushed to true.
|
||||
func (rw *ResponseRecorder) Flush() {
|
||||
rw.Flushed = true
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func TestRouteMatchers(t *testing.T) {
|
||||
var scheme, host, path, query, method string
|
||||
var headers map[string]string
|
||||
var resultVars map[bool]map[string]string
|
||||
|
||||
router := NewRouter()
|
||||
router.NewRoute().Host("{var1}.google.com").
|
||||
Path("/{var2:[a-z]+}/{var3:[0-9]+}").
|
||||
Queries("foo", "bar").
|
||||
Methods("GET").
|
||||
Schemes("https").
|
||||
Headers("x-requested-with", "XMLHttpRequest")
|
||||
router.NewRoute().Host("www.{var4}.com").
|
||||
PathPrefix("/foo/{var5:[a-z]+}/{var6:[0-9]+}").
|
||||
Queries("baz", "ding").
|
||||
Methods("POST").
|
||||
Schemes("http").
|
||||
Headers("Content-Type", "application/json")
|
||||
|
||||
reset := func() {
|
||||
// Everything match.
|
||||
scheme = "https"
|
||||
host = "www.google.com"
|
||||
path = "/product/42"
|
||||
query = "?foo=bar"
|
||||
method = "GET"
|
||||
headers = map[string]string{"X-Requested-With": "XMLHttpRequest"}
|
||||
resultVars = map[bool]map[string]string{
|
||||
true: {"var1": "www", "var2": "product", "var3": "42"},
|
||||
false: {},
|
||||
}
|
||||
}
|
||||
|
||||
reset2 := func() {
|
||||
// Everything match.
|
||||
scheme = "http"
|
||||
host = "www.google.com"
|
||||
path = "/foo/product/42/path/that/is/ignored"
|
||||
query = "?baz=ding"
|
||||
method = "POST"
|
||||
headers = map[string]string{"Content-Type": "application/json"}
|
||||
resultVars = map[bool]map[string]string{
|
||||
true: {"var4": "google", "var5": "product", "var6": "42"},
|
||||
false: {},
|
||||
}
|
||||
}
|
||||
|
||||
match := func(shouldMatch bool) {
|
||||
url := scheme + "://" + host + path + query
|
||||
request, _ := http.NewRequest(method, url, nil)
|
||||
for key, value := range headers {
|
||||
request.Header.Add(key, value)
|
||||
}
|
||||
|
||||
var routeMatch RouteMatch
|
||||
matched := router.Match(request, &routeMatch)
|
||||
if matched != shouldMatch {
|
||||
// Need better messages. :)
|
||||
if matched {
|
||||
t.Errorf("Should match.")
|
||||
} else {
|
||||
t.Errorf("Should not match.")
|
||||
}
|
||||
}
|
||||
|
||||
if matched {
|
||||
currentRoute := routeMatch.Route
|
||||
if currentRoute == nil {
|
||||
t.Errorf("Expected a current route.")
|
||||
}
|
||||
vars := routeMatch.Vars
|
||||
expectedVars := resultVars[shouldMatch]
|
||||
if len(vars) != len(expectedVars) {
|
||||
t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
|
||||
}
|
||||
for name, value := range vars {
|
||||
if expectedVars[name] != value {
|
||||
t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1st route --------------------------------------------------------------
|
||||
|
||||
// Everything match.
|
||||
reset()
|
||||
match(true)
|
||||
|
||||
// Scheme doesn't match.
|
||||
reset()
|
||||
scheme = "http"
|
||||
match(false)
|
||||
|
||||
// Host doesn't match.
|
||||
reset()
|
||||
host = "www.mygoogle.com"
|
||||
match(false)
|
||||
|
||||
// Path doesn't match.
|
||||
reset()
|
||||
path = "/product/notdigits"
|
||||
match(false)
|
||||
|
||||
// Query doesn't match.
|
||||
reset()
|
||||
query = "?foo=baz"
|
||||
match(false)
|
||||
|
||||
// Method doesn't match.
|
||||
reset()
|
||||
method = "POST"
|
||||
match(false)
|
||||
|
||||
// Header doesn't match.
|
||||
reset()
|
||||
headers = map[string]string{}
|
||||
match(false)
|
||||
|
||||
// Everything match, again.
|
||||
reset()
|
||||
match(true)
|
||||
|
||||
// 2nd route --------------------------------------------------------------
|
||||
|
||||
// Everything match.
|
||||
reset2()
|
||||
match(true)
|
||||
|
||||
// Scheme doesn't match.
|
||||
reset2()
|
||||
scheme = "https"
|
||||
match(false)
|
||||
|
||||
// Host doesn't match.
|
||||
reset2()
|
||||
host = "sub.google.com"
|
||||
match(false)
|
||||
|
||||
// Path doesn't match.
|
||||
reset2()
|
||||
path = "/bar/product/42"
|
||||
match(false)
|
||||
|
||||
// Query doesn't match.
|
||||
reset2()
|
||||
query = "?foo=baz"
|
||||
match(false)
|
||||
|
||||
// Method doesn't match.
|
||||
reset2()
|
||||
method = "GET"
|
||||
match(false)
|
||||
|
||||
// Header doesn't match.
|
||||
reset2()
|
||||
headers = map[string]string{}
|
||||
match(false)
|
||||
|
||||
// Everything match, again.
|
||||
reset2()
|
||||
match(true)
|
||||
}
|
||||
|
||||
type headerMatcherTest struct {
|
||||
matcher headerMatcher
|
||||
headers map[string]string
|
||||
result bool
|
||||
}
|
||||
|
||||
var headerMatcherTests = []headerMatcherTest{
|
||||
{
|
||||
matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
|
||||
headers: map[string]string{"X-Requested-With": "XMLHttpRequest"},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: headerMatcher(map[string]string{"x-requested-with": ""}),
|
||||
headers: map[string]string{"X-Requested-With": "anything"},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
|
||||
headers: map[string]string{},
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
|
||||
type hostMatcherTest struct {
|
||||
matcher *Route
|
||||
url string
|
||||
vars map[string]string
|
||||
result bool
|
||||
}
|
||||
|
||||
var hostMatcherTests = []hostMatcherTest{
|
||||
{
|
||||
matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
|
||||
url: "http://abc.def.ghi/",
|
||||
vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
|
||||
url: "http://a.b.c/",
|
||||
vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
|
||||
type methodMatcherTest struct {
|
||||
matcher methodMatcher
|
||||
method string
|
||||
result bool
|
||||
}
|
||||
|
||||
var methodMatcherTests = []methodMatcherTest{
|
||||
{
|
||||
matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
|
||||
method: "GET",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
|
||||
method: "POST",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
|
||||
method: "PUT",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
|
||||
method: "DELETE",
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
|
||||
type pathMatcherTest struct {
|
||||
matcher *Route
|
||||
url string
|
||||
vars map[string]string
|
||||
result bool
|
||||
}
|
||||
|
||||
var pathMatcherTests = []pathMatcherTest{
|
||||
{
|
||||
matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
|
||||
url: "http://localhost:8080/123/456/789",
|
||||
vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
|
||||
url: "http://localhost:8080/1/2/3",
|
||||
vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
|
||||
type schemeMatcherTest struct {
|
||||
matcher schemeMatcher
|
||||
url string
|
||||
result bool
|
||||
}
|
||||
|
||||
var schemeMatcherTests = []schemeMatcherTest{
|
||||
{
|
||||
matcher: schemeMatcher([]string{"http", "https"}),
|
||||
url: "http://localhost:8080/",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: schemeMatcher([]string{"http", "https"}),
|
||||
url: "https://localhost:8080/",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
matcher: schemeMatcher([]string{"https"}),
|
||||
url: "http://localhost:8080/",
|
||||
result: false,
|
||||
},
|
||||
{
|
||||
matcher: schemeMatcher([]string{"http"}),
|
||||
url: "https://localhost:8080/",
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
|
||||
type urlBuildingTest struct {
|
||||
route *Route
|
||||
vars []string
|
||||
url string
|
||||
}
|
||||
|
||||
var urlBuildingTests = []urlBuildingTest{
|
||||
{
|
||||
route: new(Route).Host("foo.domain.com"),
|
||||
vars: []string{},
|
||||
url: "http://foo.domain.com",
|
||||
},
|
||||
{
|
||||
route: new(Route).Host("{subdomain}.domain.com"),
|
||||
vars: []string{"subdomain", "bar"},
|
||||
url: "http://bar.domain.com",
|
||||
},
|
||||
{
|
||||
route: new(Route).Host("foo.domain.com").Path("/articles"),
|
||||
vars: []string{},
|
||||
url: "http://foo.domain.com/articles",
|
||||
},
|
||||
{
|
||||
route: new(Route).Path("/articles"),
|
||||
vars: []string{},
|
||||
url: "/articles",
|
||||
},
|
||||
{
|
||||
route: new(Route).Path("/articles/{category}/{id:[0-9]+}"),
|
||||
vars: []string{"category", "technology", "id", "42"},
|
||||
url: "/articles/technology/42",
|
||||
},
|
||||
{
|
||||
route: new(Route).Host("{subdomain}.domain.com").Path("/articles/{category}/{id:[0-9]+}"),
|
||||
vars: []string{"subdomain", "foo", "category", "technology", "id", "42"},
|
||||
url: "http://foo.domain.com/articles/technology/42",
|
||||
},
|
||||
}
|
||||
|
||||
func TestHeaderMatcher(t *testing.T) {
|
||||
for _, v := range headerMatcherTests {
|
||||
request, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||
for key, value := range v.headers {
|
||||
request.Header.Add(key, value)
|
||||
}
|
||||
var routeMatch RouteMatch
|
||||
result := v.matcher.Match(request, &routeMatch)
|
||||
if result != v.result {
|
||||
if v.result {
|
||||
t.Errorf("%#v: should match %v.", v.matcher, request.Header)
|
||||
} else {
|
||||
t.Errorf("%#v: should not match %v.", v.matcher, request.Header)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHostMatcher(t *testing.T) {
|
||||
for _, v := range hostMatcherTests {
|
||||
request, _ := http.NewRequest("GET", v.url, nil)
|
||||
var routeMatch RouteMatch
|
||||
result := v.matcher.Match(request, &routeMatch)
|
||||
vars := routeMatch.Vars
|
||||
if result != v.result {
|
||||
if v.result {
|
||||
t.Errorf("%#v: should match %v.", v.matcher, v.url)
|
||||
} else {
|
||||
t.Errorf("%#v: should not match %v.", v.matcher, v.url)
|
||||
}
|
||||
}
|
||||
if result {
|
||||
if len(vars) != len(v.vars) {
|
||||
t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
|
||||
}
|
||||
for name, value := range vars {
|
||||
if v.vars[name] != value {
|
||||
t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(vars) != 0 {
|
||||
t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodMatcher(t *testing.T) {
|
||||
for _, v := range methodMatcherTests {
|
||||
request, _ := http.NewRequest(v.method, "http://localhost:8080/", nil)
|
||||
var routeMatch RouteMatch
|
||||
result := v.matcher.Match(request, &routeMatch)
|
||||
if result != v.result {
|
||||
if v.result {
|
||||
t.Errorf("%#v: should match %v.", v.matcher, v.method)
|
||||
} else {
|
||||
t.Errorf("%#v: should not match %v.", v.matcher, v.method)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathMatcher(t *testing.T) {
|
||||
for _, v := range pathMatcherTests {
|
||||
request, _ := http.NewRequest("GET", v.url, nil)
|
||||
var routeMatch RouteMatch
|
||||
result := v.matcher.Match(request, &routeMatch)
|
||||
vars := routeMatch.Vars
|
||||
if result != v.result {
|
||||
if v.result {
|
||||
t.Errorf("%#v: should match %v.", v.matcher, v.url)
|
||||
} else {
|
||||
t.Errorf("%#v: should not match %v.", v.matcher, v.url)
|
||||
}
|
||||
}
|
||||
if result {
|
||||
if len(vars) != len(v.vars) {
|
||||
t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
|
||||
}
|
||||
for name, value := range vars {
|
||||
if v.vars[name] != value {
|
||||
t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(vars) != 0 {
|
||||
t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchemeMatcher(t *testing.T) {
|
||||
for _, v := range schemeMatcherTests {
|
||||
request, _ := http.NewRequest("GET", v.url, nil)
|
||||
var routeMatch RouteMatch
|
||||
result := v.matcher.Match(request, &routeMatch)
|
||||
if result != v.result {
|
||||
if v.result {
|
||||
t.Errorf("%#v: should match %v.", v.matcher, v.url)
|
||||
} else {
|
||||
t.Errorf("%#v: should not match %v.", v.matcher, v.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUrlBuilding(t *testing.T) {
|
||||
|
||||
for _, v := range urlBuildingTests {
|
||||
u, _ := v.route.URL(v.vars...)
|
||||
url := u.String()
|
||||
if url != v.url {
|
||||
t.Errorf("expected %v, got %v", v.url, url)
|
||||
/*
|
||||
reversePath := ""
|
||||
reverseHost := ""
|
||||
if v.route.pathTemplate != nil {
|
||||
reversePath = v.route.pathTemplate.Reverse
|
||||
}
|
||||
if v.route.hostTemplate != nil {
|
||||
reverseHost = v.route.hostTemplate.Reverse
|
||||
}
|
||||
|
||||
t.Errorf("%#v:\nexpected: %q\ngot: %q\nreverse path: %q\nreverse host: %q", v.route, v.url, url, reversePath, reverseHost)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
ArticleHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
router := NewRouter()
|
||||
router.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")
|
||||
|
||||
url, _ := router.Get("article").URL("category", "technology", "id", "42")
|
||||
expected := "/articles/technology/42"
|
||||
if url.String() != expected {
|
||||
t.Errorf("Expected %v, got %v", expected, url.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchedRouteName(t *testing.T) {
|
||||
routeName := "stock"
|
||||
router := NewRouter()
|
||||
route := router.NewRoute().Path("/products/").Name(routeName)
|
||||
|
||||
url := "http://www.domain.com/products/"
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
var rv RouteMatch
|
||||
ok := router.Match(request, &rv)
|
||||
|
||||
if !ok || rv.Route != route {
|
||||
t.Errorf("Expected same route, got %+v.", rv.Route)
|
||||
}
|
||||
|
||||
retName := rv.Route.GetName()
|
||||
if retName != routeName {
|
||||
t.Errorf("Expected %q, got %q.", routeName, retName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubRouting(t *testing.T) {
|
||||
// Example from docs.
|
||||
router := NewRouter()
|
||||
subrouter := router.NewRoute().Host("www.domain.com").Subrouter()
|
||||
route := subrouter.NewRoute().Path("/products/").Name("products")
|
||||
|
||||
url := "http://www.domain.com/products/"
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
var rv RouteMatch
|
||||
ok := router.Match(request, &rv)
|
||||
|
||||
if !ok || rv.Route != route {
|
||||
t.Errorf("Expected same route, got %+v.", rv.Route)
|
||||
}
|
||||
|
||||
u, _ := router.Get("products").URL()
|
||||
builtUrl := u.String()
|
||||
// Yay, subroute aware of the domain when building!
|
||||
if builtUrl != url {
|
||||
t.Errorf("Expected %q, got %q.", url, builtUrl)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariableNames(t *testing.T) {
|
||||
route := new(Route).Host("{arg1}.domain.com").Path("/{arg1}/{arg2:[0-9]+}")
|
||||
if route.err == nil {
|
||||
t.Errorf("Expected error for duplicated variable names")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedirectSlash(t *testing.T) {
|
||||
var route *Route
|
||||
var routeMatch RouteMatch
|
||||
r := NewRouter()
|
||||
|
||||
r.StrictSlash(false)
|
||||
route = r.NewRoute()
|
||||
if route.strictSlash != false {
|
||||
t.Errorf("Expected false redirectSlash.")
|
||||
}
|
||||
|
||||
r.StrictSlash(true)
|
||||
route = r.NewRoute()
|
||||
if route.strictSlash != true {
|
||||
t.Errorf("Expected true redirectSlash.")
|
||||
}
|
||||
|
||||
route = new(Route)
|
||||
route.strictSlash = true
|
||||
route.Path("/{arg1}/{arg2:[0-9]+}/")
|
||||
request, _ := http.NewRequest("GET", "http://localhost/foo/123", nil)
|
||||
routeMatch = RouteMatch{}
|
||||
_ = route.Match(request, &routeMatch)
|
||||
vars := routeMatch.Vars
|
||||
if vars["arg1"] != "foo" {
|
||||
t.Errorf("Expected foo.")
|
||||
}
|
||||
if vars["arg2"] != "123" {
|
||||
t.Errorf("Expected 123.")
|
||||
}
|
||||
rsp := NewRecorder()
|
||||
routeMatch.Handler.ServeHTTP(rsp, request)
|
||||
if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123/" {
|
||||
t.Errorf("Expected redirect header.")
|
||||
}
|
||||
|
||||
route = new(Route)
|
||||
route.strictSlash = true
|
||||
route.Path("/{arg1}/{arg2:[0-9]+}")
|
||||
request, _ = http.NewRequest("GET", "http://localhost/foo/123/", nil)
|
||||
routeMatch = RouteMatch{}
|
||||
_ = route.Match(request, &routeMatch)
|
||||
vars = routeMatch.Vars
|
||||
if vars["arg1"] != "foo" {
|
||||
t.Errorf("Expected foo.")
|
||||
}
|
||||
if vars["arg2"] != "123" {
|
||||
t.Errorf("Expected 123.")
|
||||
}
|
||||
rsp = NewRecorder()
|
||||
routeMatch.Handler.ServeHTTP(rsp, request)
|
||||
if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123" {
|
||||
t.Errorf("Expected redirect header.")
|
||||
}
|
||||
}
|
||||
|
||||
// Test for the new regexp library, still not available in stable Go.
|
||||
func TestNewRegexp(t *testing.T) {
|
||||
var p *routeRegexp
|
||||
var matches []string
|
||||
|
||||
tests := map[string]map[string][]string{
|
||||
"/{foo:a{2}}": {
|
||||
"/a": nil,
|
||||
"/aa": {"aa"},
|
||||
"/aaa": nil,
|
||||
"/aaaa": nil,
|
||||
},
|
||||
"/{foo:a{2,}}": {
|
||||
"/a": nil,
|
||||
"/aa": {"aa"},
|
||||
"/aaa": {"aaa"},
|
||||
"/aaaa": {"aaaa"},
|
||||
},
|
||||
"/{foo:a{2,3}}": {
|
||||
"/a": nil,
|
||||
"/aa": {"aa"},
|
||||
"/aaa": {"aaa"},
|
||||
"/aaaa": nil,
|
||||
},
|
||||
"/{foo:[a-z]{3}}/{bar:[a-z]{2}}": {
|
||||
"/a": nil,
|
||||
"/ab": nil,
|
||||
"/abc": nil,
|
||||
"/abcd": nil,
|
||||
"/abc/ab": {"abc", "ab"},
|
||||
"/abc/abc": nil,
|
||||
"/abcd/ab": nil,
|
||||
},
|
||||
`/{foo:\w{3,}}/{bar:\d{2,}}`: {
|
||||
"/a": nil,
|
||||
"/ab": nil,
|
||||
"/abc": nil,
|
||||
"/abc/1": nil,
|
||||
"/abc/12": {"abc", "12"},
|
||||
"/abcd/12": {"abcd", "12"},
|
||||
"/abcd/123": {"abcd", "123"},
|
||||
},
|
||||
}
|
||||
|
||||
for pattern, paths := range tests {
|
||||
p, _ = newRouteRegexp(pattern, false, false, false, false)
|
||||
for path, result := range paths {
|
||||
matches = p.regexp.FindStringSubmatch(path)
|
||||
if result == nil {
|
||||
if matches != nil {
|
||||
t.Errorf("%v should not match %v.", pattern, path)
|
||||
}
|
||||
} else {
|
||||
if len(matches) != len(result)+1 {
|
||||
t.Errorf("Expected %v matches, got %v.", len(result)+1, len(matches))
|
||||
} else {
|
||||
for k, v := range result {
|
||||
if matches[k+1] != v {
|
||||
t.Errorf("Expected %v, got %v.", v, matches[k+1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json/json_test.go
generated
vendored
117
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json/json_test.go
generated
vendored
@ -1,117 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrResponseError = errors.New("response error")
|
||||
ErrResponseJsonError = &Error{Data: map[string]interface{}{
|
||||
"stackstrace": map[string]interface{}{"0": "foo()"},
|
||||
"error": "a message",
|
||||
}}
|
||||
)
|
||||
|
||||
type Service1Request struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type Service1Response struct {
|
||||
Result int
|
||||
}
|
||||
|
||||
type Service1 struct {
|
||||
}
|
||||
|
||||
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
res.Result = req.A * req.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Service1) ResponseError(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
return ErrResponseError
|
||||
}
|
||||
|
||||
func (t *Service1) ResponseJsonError(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
return ErrResponseJsonError
|
||||
}
|
||||
|
||||
func execute(t *testing.T, s *rpc.Server, method string, req, res interface{}) error {
|
||||
if !s.HasMethod(method) {
|
||||
t.Fatal("Expected to be registered:", method)
|
||||
}
|
||||
|
||||
buf, _ := EncodeClientRequest(method, req)
|
||||
body := bytes.NewBuffer(buf)
|
||||
r, _ := http.NewRequest("POST", "http://localhost:8080/", body)
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
s.ServeHTTP(w, r)
|
||||
|
||||
return DecodeClientResponse(w.Body, res)
|
||||
}
|
||||
|
||||
func executeRaw(t *testing.T, s *rpc.Server, req json.RawMessage) (int, *bytes.Buffer) {
|
||||
r, _ := http.NewRequest("POST", "http://localhost:8080/", bytes.NewBuffer(req))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
s.ServeHTTP(w, r)
|
||||
|
||||
return w.Code, w.Body
|
||||
}
|
||||
|
||||
func field(name string, blob json.RawMessage) (v interface{}, ok bool) {
|
||||
var obj map[string]interface{}
|
||||
if err := json.Unmarshal(blob, &obj); err != nil {
|
||||
return nil, false
|
||||
}
|
||||
v, ok = obj[name]
|
||||
return
|
||||
}
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
s := rpc.NewServer()
|
||||
s.RegisterCodec(NewCodec(), "application/json")
|
||||
s.RegisterService(new(Service1), "")
|
||||
|
||||
var res Service1Response
|
||||
if err := execute(t, s, "Service1.Multiply", &Service1Request{4, 2}, &res); err != nil {
|
||||
t.Error("Expected err to be nil, but got", err)
|
||||
}
|
||||
if res.Result != 8 {
|
||||
t.Error("Expected res.Result to be 8, but got", res.Result)
|
||||
}
|
||||
if err := execute(t, s, "Service1.ResponseError", &Service1Request{4, 2}, &res); err == nil {
|
||||
t.Errorf("Expected to get %q, but got nil", ErrResponseError)
|
||||
} else if err.Error() != ErrResponseError.Error() {
|
||||
t.Errorf("Expected to get %q, but got %q", ErrResponseError, err)
|
||||
}
|
||||
if code, res := executeRaw(t, s, json.RawMessage(`{"method":"Service1.Multiply","params":null,"id":5}`)); code != 400 {
|
||||
t.Error("Expected response code to be 400, but got", code)
|
||||
} else if v, ok := field("result", res.Bytes()); !ok || v != nil {
|
||||
t.Errorf("Expected ok to be true and v to be nil, but got %v and %v", ok, v)
|
||||
}
|
||||
if err := execute(t, s, "Service1.ResponseJsonError", &Service1Request{4, 2}, &res); err == nil {
|
||||
t.Errorf("Expected to get %q, but got nil", ErrResponseError)
|
||||
} else if jsonErr, ok := err.(*Error); !ok {
|
||||
t.Error("Expected err to be of a *json.Error type")
|
||||
} else if !reflect.DeepEqual(jsonErr.Data, ErrResponseJsonError.Data) {
|
||||
t.Errorf("Expected jsonErr to be %q, but got %q", ErrResponseJsonError, jsonErr)
|
||||
}
|
||||
}
|
75
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/client.go
generated
vendored
75
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/client.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Request and Response
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// clientRequest represents a JSON-RPC request sent by a client.
|
||||
type clientRequest struct {
|
||||
// JSON-RPC protocol.
|
||||
Version string `json:"jsonrpc"`
|
||||
|
||||
// A String containing the name of the method to be invoked.
|
||||
Method string `json:"method"`
|
||||
|
||||
// Object to pass as request parameter to the method.
|
||||
Params interface{} `json:"params"`
|
||||
|
||||
// The request id. This can be of any type. It is used to match the
|
||||
// response with the request that it is replying to.
|
||||
Id uint64 `json:"id"`
|
||||
}
|
||||
|
||||
// clientResponse represents a JSON-RPC response returned to a client.
|
||||
type clientResponse struct {
|
||||
Version string `json:"jsonrpc"`
|
||||
Result *json.RawMessage `json:"result"`
|
||||
Error *json.RawMessage `json:"error"`
|
||||
}
|
||||
|
||||
// EncodeClientRequest encodes parameters for a JSON-RPC client request.
|
||||
func EncodeClientRequest(method string, args interface{}) ([]byte, error) {
|
||||
c := &clientRequest{
|
||||
Version: "2.0",
|
||||
Method: method,
|
||||
Params: args,
|
||||
Id: uint64(rand.Int63()),
|
||||
}
|
||||
return json.Marshal(c)
|
||||
}
|
||||
|
||||
// DecodeClientResponse decodes the response body of a client request into
|
||||
// the interface reply.
|
||||
func DecodeClientResponse(r io.Reader, reply interface{}) error {
|
||||
var c clientResponse
|
||||
if err := json.NewDecoder(r).Decode(&c); err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Error != nil {
|
||||
jsonErr := &Error{}
|
||||
if err := json.Unmarshal(*c.Error, jsonErr); err != nil {
|
||||
return &Error{
|
||||
Code: E_SERVER,
|
||||
Message: string(*c.Error),
|
||||
}
|
||||
}
|
||||
return jsonErr
|
||||
}
|
||||
|
||||
if c.Result == nil {
|
||||
return ErrNullResult
|
||||
}
|
||||
|
||||
return json.Unmarshal(*c.Result, reply)
|
||||
}
|
39
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/error.go
generated
vendored
39
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/error.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type ErrorCode int
|
||||
|
||||
const (
|
||||
E_PARSE ErrorCode = -32700
|
||||
E_INVALID_REQ ErrorCode = -32600
|
||||
E_NO_METHOD ErrorCode = -32601
|
||||
E_BAD_PARAMS ErrorCode = -32602
|
||||
E_INTERNAL ErrorCode = -32603
|
||||
E_SERVER ErrorCode = -32000
|
||||
)
|
||||
|
||||
var ErrNullResult = errors.New("result is null")
|
||||
|
||||
type Error struct {
|
||||
// A Number that indicates the error type that occurred.
|
||||
Code ErrorCode `json:"code"` /* required */
|
||||
|
||||
// A String providing a short description of the error.
|
||||
// The message SHOULD be limited to a concise single sentence.
|
||||
Message string `json:"message"` /* required */
|
||||
|
||||
// A Primitive or Structured value that contains additional information about the error.
|
||||
Data interface{} `json:"data"` /* optional */
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return e.Message
|
||||
}
|
161
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/json_test.go
generated
vendored
161
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/json_test.go
generated
vendored
@ -1,161 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
// ResponseRecorder is an implementation of http.ResponseWriter that
|
||||
// records its mutations for later inspection in tests.
|
||||
type ResponseRecorder struct {
|
||||
Code int // the HTTP response code from WriteHeader
|
||||
HeaderMap http.Header // the HTTP response headers
|
||||
Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
|
||||
Flushed bool
|
||||
}
|
||||
|
||||
// NewRecorder returns an initialized ResponseRecorder.
|
||||
func NewRecorder() *ResponseRecorder {
|
||||
return &ResponseRecorder{
|
||||
HeaderMap: make(http.Header),
|
||||
Body: new(bytes.Buffer),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultRemoteAddr is the default remote address to return in RemoteAddr if
|
||||
// an explicit DefaultRemoteAddr isn't set on ResponseRecorder.
|
||||
const DefaultRemoteAddr = "1.2.3.4"
|
||||
|
||||
// Header returns the response headers.
|
||||
func (rw *ResponseRecorder) Header() http.Header {
|
||||
return rw.HeaderMap
|
||||
}
|
||||
|
||||
// Write always succeeds and writes to rw.Body, if not nil.
|
||||
func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
|
||||
if rw.Body != nil {
|
||||
rw.Body.Write(buf)
|
||||
}
|
||||
if rw.Code == 0 {
|
||||
rw.Code = http.StatusOK
|
||||
}
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
// WriteHeader sets rw.Code.
|
||||
func (rw *ResponseRecorder) WriteHeader(code int) {
|
||||
rw.Code = code
|
||||
}
|
||||
|
||||
// Flush sets rw.Flushed to true.
|
||||
func (rw *ResponseRecorder) Flush() {
|
||||
rw.Flushed = true
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var ErrResponseError = errors.New("response error")
|
||||
|
||||
type Service1Request struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type Service1BadRequest struct {
|
||||
V string `json:"jsonrpc"`
|
||||
M string `json:"method"`
|
||||
ID uint64 `json:"id"`
|
||||
}
|
||||
|
||||
type Service1Response struct {
|
||||
Result int
|
||||
}
|
||||
|
||||
type Service1 struct {
|
||||
}
|
||||
|
||||
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
res.Result = req.A * req.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Service1) ResponseError(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
return ErrResponseError
|
||||
}
|
||||
|
||||
func execute(t *testing.T, s *rpc.Server, method string, req, res interface{}) error {
|
||||
if !s.HasMethod(method) {
|
||||
t.Fatal("Expected to be registered:", method)
|
||||
}
|
||||
|
||||
buf, _ := EncodeClientRequest(method, req)
|
||||
body := bytes.NewBuffer(buf)
|
||||
r, _ := http.NewRequest("POST", "http://localhost:8080/", body)
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := NewRecorder()
|
||||
s.ServeHTTP(w, r)
|
||||
|
||||
return DecodeClientResponse(w.Body, res)
|
||||
}
|
||||
|
||||
func executeRaw(t *testing.T, s *rpc.Server, req interface{}, res interface{}) error {
|
||||
j, _ := json.Marshal(req)
|
||||
r, _ := http.NewRequest("POST", "http://localhost:8080/", bytes.NewBuffer(j))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := NewRecorder()
|
||||
s.ServeHTTP(w, r)
|
||||
|
||||
return DecodeClientResponse(w.Body, res)
|
||||
}
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
s := rpc.NewServer()
|
||||
s.RegisterCodec(NewCodec(), "application/json")
|
||||
s.RegisterService(new(Service1), "")
|
||||
|
||||
var res Service1Response
|
||||
if err := execute(t, s, "Service1.Multiply", &Service1Request{4, 2}, &res); err != nil {
|
||||
t.Error("Expected err to be nil, but got:", err)
|
||||
}
|
||||
if res.Result != 8 {
|
||||
t.Errorf("Wrong response: %v.", res.Result)
|
||||
}
|
||||
|
||||
if err := execute(t, s, "Service1.ResponseError", &Service1Request{4, 2}, &res); err == nil {
|
||||
t.Errorf("Expected to get %q, but got nil", ErrResponseError)
|
||||
} else if err.Error() != ErrResponseError.Error() {
|
||||
t.Errorf("Expected to get %q, but got %q", ErrResponseError, err)
|
||||
}
|
||||
|
||||
if err := executeRaw(t, s, &Service1BadRequest{"2.0", "Service1.Multiply", 1}, &res); err == nil {
|
||||
t.Errorf("Expected error but error in nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeNullResult(t *testing.T) {
|
||||
data := `{"jsonrpc": "2.0", "id": 12345, "result": null}`
|
||||
reader := bytes.NewReader([]byte(data))
|
||||
var result interface{}
|
||||
|
||||
err := DecodeClientResponse(reader, &result)
|
||||
|
||||
if err != ErrNullResult {
|
||||
t.Error("Expected err no be ErrNullResult, but got:", err)
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
t.Error("Expected result to be nil, but got:", result)
|
||||
}
|
||||
}
|
190
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/server.go
generated
vendored
190
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/server.go
generated
vendored
@ -1,190 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
var null = json.RawMessage([]byte("null"))
|
||||
var Version = "2.0"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Request and Response
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// serverRequest represents a JSON-RPC request received by the server.
|
||||
type serverRequest struct {
|
||||
// JSON-RPC protocol.
|
||||
Version string `json:"jsonrpc"`
|
||||
|
||||
// A String containing the name of the method to be invoked.
|
||||
Method string `json:"method"`
|
||||
|
||||
// A Structured value to pass as arguments to the method.
|
||||
Params *json.RawMessage `json:"params"`
|
||||
|
||||
// The request id. MUST be a string, number or null.
|
||||
// Our implementation will not do type checking for id.
|
||||
// It will be copied as it is.
|
||||
Id *json.RawMessage `json:"id"`
|
||||
}
|
||||
|
||||
// serverResponse represents a JSON-RPC response returned by the server.
|
||||
type serverResponse struct {
|
||||
// JSON-RPC protocol.
|
||||
Version string `json:"jsonrpc"`
|
||||
|
||||
// The Object that was returned by the invoked method. This must be null
|
||||
// in case there was an error invoking the method.
|
||||
// As per spec the member will be omitted if there was an error.
|
||||
Result interface{} `json:"result,omitempty"`
|
||||
|
||||
// An Error object if there was an error invoking the method. It must be
|
||||
// null if there was no error.
|
||||
// As per spec the member will be omitted if there was no error.
|
||||
Error *Error `json:"error,omitempty"`
|
||||
|
||||
// This must be the same id as the request it is responding to.
|
||||
Id *json.RawMessage `json:"id"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Codec
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// NewcustomCodec returns a new JSON Codec based on passed encoder selector.
|
||||
func NewCustomCodec(encSel rpc.EncoderSelector) *Codec {
|
||||
return &Codec{encSel: encSel}
|
||||
}
|
||||
|
||||
// NewCodec returns a new JSON Codec.
|
||||
func NewCodec() *Codec {
|
||||
return NewCustomCodec(rpc.DefaultEncoderSelector)
|
||||
}
|
||||
|
||||
// Codec creates a CodecRequest to process each request.
|
||||
type Codec struct {
|
||||
encSel rpc.EncoderSelector
|
||||
}
|
||||
|
||||
// NewRequest returns a CodecRequest.
|
||||
func (c *Codec) NewRequest(r *http.Request) rpc.CodecRequest {
|
||||
return newCodecRequest(r, c.encSel.Select(r))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CodecRequest
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// newCodecRequest returns a new CodecRequest.
|
||||
func newCodecRequest(r *http.Request, encoder rpc.Encoder) rpc.CodecRequest {
|
||||
// Decode the request body and check if RPC method is valid.
|
||||
req := new(serverRequest)
|
||||
err := json.NewDecoder(r.Body).Decode(req)
|
||||
if err != nil {
|
||||
err = &Error{
|
||||
Code: E_PARSE,
|
||||
Message: err.Error(),
|
||||
Data: req,
|
||||
}
|
||||
}
|
||||
if req.Version != Version {
|
||||
err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Message: "jsonrpc must be " + Version,
|
||||
Data: req,
|
||||
}
|
||||
}
|
||||
r.Body.Close()
|
||||
return &CodecRequest{request: req, err: err, encoder: encoder}
|
||||
}
|
||||
|
||||
// CodecRequest decodes and encodes a single request.
|
||||
type CodecRequest struct {
|
||||
request *serverRequest
|
||||
err error
|
||||
encoder rpc.Encoder
|
||||
}
|
||||
|
||||
// Method returns the RPC method for the current request.
|
||||
//
|
||||
// The method uses a dotted notation as in "Service.Method".
|
||||
func (c *CodecRequest) Method() (string, error) {
|
||||
if c.err == nil {
|
||||
return c.request.Method, nil
|
||||
}
|
||||
return "", c.err
|
||||
}
|
||||
|
||||
// ReadRe<quest fills the request object for the RPC method.
|
||||
func (c *CodecRequest) ReadRequest(args interface{}) error {
|
||||
if c.err == nil {
|
||||
if c.request.Params != nil {
|
||||
// JSON params structured object. Unmarshal to the args object.
|
||||
err := json.Unmarshal(*c.request.Params, args)
|
||||
if err != nil {
|
||||
c.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: c.request.Params,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Message: "rpc: method request ill-formed: missing params field",
|
||||
}
|
||||
}
|
||||
}
|
||||
return c.err
|
||||
}
|
||||
|
||||
// WriteResponse encodes the response and writes it to the ResponseWriter.
|
||||
func (c *CodecRequest) WriteResponse(w http.ResponseWriter, reply interface{}) {
|
||||
res := &serverResponse{
|
||||
Version: Version,
|
||||
Result: reply,
|
||||
Id: c.request.Id,
|
||||
}
|
||||
c.writeServerResponse(w, res)
|
||||
}
|
||||
|
||||
func (c *CodecRequest) WriteError(w http.ResponseWriter, status int, err error) {
|
||||
jsonErr, ok := err.(*Error)
|
||||
if !ok {
|
||||
jsonErr = &Error{
|
||||
Code: E_SERVER,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
res := &serverResponse{
|
||||
Version: Version,
|
||||
Error: jsonErr,
|
||||
Id: c.request.Id,
|
||||
}
|
||||
c.writeServerResponse(w, res)
|
||||
}
|
||||
|
||||
func (c *CodecRequest) writeServerResponse(w http.ResponseWriter, res *serverResponse) {
|
||||
// Id is null for notifications and they don't have a response.
|
||||
if c.request.Id != nil {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
encoder := json.NewEncoder(c.encoder.Encode(w))
|
||||
err := encoder.Encode(res)
|
||||
|
||||
// Not sure in which case will this happen. But seems harmless.
|
||||
if err != nil {
|
||||
rpc.WriteError(w, 400, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type EmptyResponse struct {
|
||||
}
|
10
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/README.md
generated
vendored
10
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/README.md
generated
vendored
@ -1,10 +0,0 @@
|
||||
Counter (TestApp)
|
||||
=================
|
||||
|
||||
1) Build
|
||||
|
||||
$ go build counter.go
|
||||
$ ./counter
|
||||
|
||||
|
||||
2) Navigate to localhost:65534 on the browser to access the app.
|
50
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/counter.go
generated
vendored
50
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/counter.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2013 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
"github.com/gorilla/rpc/v2/json2"
|
||||
)
|
||||
|
||||
type Counter struct {
|
||||
Count int
|
||||
}
|
||||
|
||||
type IncrReq struct {
|
||||
Delta int
|
||||
}
|
||||
|
||||
// Notification.
|
||||
func (c *Counter) Incr(r *http.Request, req *IncrReq, res *json2.EmptyResponse) error {
|
||||
log.Printf("<- Incr %+v", *req)
|
||||
c.Count += req.Delta
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetReq struct {
|
||||
}
|
||||
|
||||
func (c *Counter) Get(r *http.Request, req *GetReq, res *Counter) error {
|
||||
log.Printf("<- Get %+v", *req)
|
||||
*res = *c
|
||||
log.Printf("-> %v", *res)
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
address := flag.String("address", ":65534", "")
|
||||
s := rpc.NewServer()
|
||||
s.RegisterCodec(json2.NewCustomCodec(&rpc.CompressionSelector{}), "application/json")
|
||||
s.RegisterService(new(Counter), "")
|
||||
http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("./"))))
|
||||
http.Handle("/jsonrpc/", s)
|
||||
log.Fatal(http.ListenAndServe(*address, nil))
|
||||
}
|
64
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/counter.js
generated
vendored
64
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/counter.js
generated
vendored
@ -1,64 +0,0 @@
|
||||
function log(m, label) {
|
||||
msg = $("<li><span>" + m + "</span></li>");
|
||||
msg.find("span").addClass(label);
|
||||
out = $("#output");
|
||||
out.append(msg);
|
||||
out.animate({"scrollTop": out[0].scrollHeight}, "fast");
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#incr").click(function() {
|
||||
req = {
|
||||
method : "Counter.Incr",
|
||||
params : {delta: 1},
|
||||
};
|
||||
log("<- " + JSON.stringify(req), "secondary label");
|
||||
$.jsonrpc(req);
|
||||
});
|
||||
$("#get").click(function() {
|
||||
req = {
|
||||
method : "Counter.Get",
|
||||
params : {},
|
||||
};
|
||||
log("<- " + JSON.stringify(req), "label");
|
||||
$.jsonrpc(req, {
|
||||
success : function(result) {
|
||||
$("#get").addClass("success");
|
||||
setTimeout(function() {
|
||||
$("#get").removeClass("success");
|
||||
}, 2000);
|
||||
log("-> " + JSON.stringify(result), "success label");
|
||||
},
|
||||
error : function(error) {
|
||||
$("#get").addClass("alert");
|
||||
setTimeout(function() {
|
||||
$("#get").removeClass("alert");
|
||||
}, 2000);
|
||||
log("-> " + JSON.stringify(error), "alert label");
|
||||
},
|
||||
});
|
||||
});
|
||||
$("#nan").click(function() {
|
||||
req = {
|
||||
method : "Counter.Nan",
|
||||
params : {},
|
||||
};
|
||||
log("<- " + JSON.stringify(req), "label");
|
||||
$.jsonrpc(req, {
|
||||
success : function(result) {
|
||||
$("#nan").addClass("success");
|
||||
setTimeout(function() {
|
||||
$("#nan").removeClass("success");
|
||||
}, 2000);
|
||||
log("-> " + JSON.stringify(result), "success label");
|
||||
},
|
||||
error : function(error) {
|
||||
$("#nan").addClass("alert");
|
||||
setTimeout(function() {
|
||||
$("#nan").removeClass("alert");
|
||||
}, 2000);
|
||||
log("-> " + JSON.stringify(error), "alert label");
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
32
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/index.html
generated
vendored
32
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/index.html
generated
vendored
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
|
||||
<link href="//cdn.jsdelivr.net/foundation/4.1.2/css/foundation.min.css" rel='stylesheet' type='text/css'>
|
||||
<link href="//fonts.googleapis.com/css?family=Inconsolata" rel='stylesheet' type='text/css'>
|
||||
<script src="jquery.jsonrpc.js"></script>
|
||||
<script src="counter.js"></script>
|
||||
<title>Counter</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Inconsolata', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="padding:20px">
|
||||
<div class="row">
|
||||
<div class="large-1 columns"><a id="incr" href="#" class="small secondary button">Incr</a></div>
|
||||
<div class="large-1 columns"><a id="get" href="#" class="small button">Get </a></div>
|
||||
<div class="large-1 columns"><a id="nan" href="#" class="small button">Nan </a></div>
|
||||
<div class="large-9 columns"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns panel">
|
||||
<ul id="output" style="height:600px;overflow:scroll;list-style-type:none;">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
158
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/jquery.jsonrpc.js
generated
vendored
158
Godeps/_workspace/src/github.com/gorilla/rpc/v2/json2/testapp/jquery.jsonrpc.js
generated
vendored
@ -1,158 +0,0 @@
|
||||
/*
|
||||
* jQuery JSON-RPC Plugin
|
||||
*
|
||||
* @version: 0.3(2012-05-17)
|
||||
* @author hagino3000 <http://twitter.com/hagino3000> (Takashi Nishibayashi)
|
||||
* @author alanjds <http://twitter.com/alanjds> (Alan Justino da Silva)
|
||||
*
|
||||
* A JSON-RPC 2.0 implementation for jQuery.
|
||||
* JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol.
|
||||
* Read more in the <http://groups.google.com/group/json-rpc/web/json-rpc-2-0>
|
||||
*
|
||||
* Requires json2.js<http://www.json.org/json2.js> if browser has not window.JSON.
|
||||
*
|
||||
* Usage:
|
||||
* $.jsonrpc(data [, callbacks [, debug]]);
|
||||
*
|
||||
* where data = {url: '/rpc/', method:'simplefunc', params:['posi', 'tional']}
|
||||
* or data = {url: '/rpc/', method:'complexfunc', params:{nam:'ed', par:'ams'}}
|
||||
* and callbacks = {success: successFunc, error: errorFunc}
|
||||
*
|
||||
* Setting no callback produces a JSON-RPC Notification.
|
||||
* 'data' accepts 'timeout' keyword too, who sets the $.ajax request timeout.
|
||||
* Setting 'debug' to true prints responses to Firebug's console.info
|
||||
*
|
||||
* Examples:
|
||||
* // A RPC call with named parameters
|
||||
* $.jsonrpc({
|
||||
* url : '/rpc',
|
||||
* method : 'createUser',
|
||||
* params : {name : 'John Smith', userId : '1000'}
|
||||
* }, {
|
||||
* success : function(result) {
|
||||
* //doSomething
|
||||
* },
|
||||
* error : function(error) {
|
||||
* //doSomething
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Once set defaultUrl, url option is no need
|
||||
* $.jsonrpc.defaultUrl = '/rpc';
|
||||
*
|
||||
* // A Notification
|
||||
* $.jsonrpc({
|
||||
* method : 'notify',
|
||||
* params : {action : 'logout', userId : '1000'}
|
||||
* });
|
||||
*
|
||||
* // A Notification using console to debug and with timeout set
|
||||
* $.jsonrpc({
|
||||
* method : 'notify',
|
||||
* params : {action : 'logout', userId : '1000'},
|
||||
* debug : true,
|
||||
* timeout : 500,
|
||||
* });
|
||||
*
|
||||
* // Set DataFilter. It is useful for buggy API that returns sometimes not json but html (when 500, 403..).
|
||||
* $.jsonrpc({
|
||||
* method : 'getUser',
|
||||
* dataFilter : function(data, type) {
|
||||
* try {
|
||||
* return JSON.parse(data);
|
||||
* } catch(e) {
|
||||
* return {error : {message : 'Cannot parse response', data : data}};
|
||||
* }
|
||||
* }, function(result){ doSomething... }
|
||||
* }, {
|
||||
* success : handleSuccess
|
||||
* error : handleFailure
|
||||
* });
|
||||
*
|
||||
* This document is licensed as free software under the terms of the
|
||||
* MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
var rpcid = 1,
|
||||
emptyFn = function() {};
|
||||
|
||||
$.jsonrpc = $.jsonrpc || function(data, callbacks, debug) {
|
||||
debug = debug || false;
|
||||
|
||||
var postdata = {
|
||||
jsonrpc: '2.0',
|
||||
method: data.method || '',
|
||||
params: data.params || {}
|
||||
};
|
||||
if (callbacks) {
|
||||
postdata.id = data.id || rpcid++;
|
||||
} else {
|
||||
callbacks = emptyFn;
|
||||
}
|
||||
|
||||
if (typeof(callbacks) === 'function') {
|
||||
callbacks = {
|
||||
success: callbacks,
|
||||
error: callbacks
|
||||
};
|
||||
}
|
||||
|
||||
var dataFilter = data.dataFilter;
|
||||
|
||||
var ajaxopts = {
|
||||
url: data.url || $.jsonrpc.defaultUrl,
|
||||
contentType: 'application/json',
|
||||
dataType: 'text',
|
||||
dataFilter: function(data, type) {
|
||||
if (dataFilter) {
|
||||
return dataFilter(data);
|
||||
} else {
|
||||
if (data != "") return JSON.parse(data);
|
||||
}
|
||||
},
|
||||
type: 'POST',
|
||||
processData: false,
|
||||
data: JSON.stringify(postdata),
|
||||
success: function(resp) {
|
||||
if (resp && !resp.error) {
|
||||
return callbacks.success && callbacks.success(resp.result);
|
||||
} else if (resp && resp.error) {
|
||||
return callbacks.error && callbacks.error(resp.error);
|
||||
} else {
|
||||
return callbacks.error && callbacks.error(resp);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
if (error === 'timeout') {
|
||||
callbacks.error({
|
||||
status: status,
|
||||
code: 0,
|
||||
message: 'Request Timeout'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// If response code is 404, 400, 500, server returns error object
|
||||
try {
|
||||
var res = JSON.parse(xhr.responseText);
|
||||
callbacks.error(res.error);
|
||||
} catch (e) {
|
||||
callbacks.error({
|
||||
status: status,
|
||||
code: 0,
|
||||
message: error
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
if (data.timeout) {
|
||||
ajaxopts['timeout'] = data.timeout;
|
||||
}
|
||||
|
||||
$.ajax(ajaxopts);
|
||||
|
||||
return $;
|
||||
}
|
||||
$.jsonrpc.defaultUrl = $.jsonrpc.defaultUrl || '/jsonrpc/';
|
||||
|
||||
})(jQuery);
|
48
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/doc.go
generated
vendored
48
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/doc.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package gorilla/rpc/protorpc provides a codec for ProtoRPC over HTTP services.
|
||||
|
||||
To register the codec in a RPC server:
|
||||
|
||||
import (
|
||||
"http"
|
||||
"github.com/gorilla/rpc/v2"
|
||||
"github.com/gorilla/rpc/v2/protorpc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
s := rpc.NewServer()
|
||||
s.RegisterCodec(protorpc.NewCodec(), "application/json")
|
||||
// [...]
|
||||
http.Handle("/rpc", s)
|
||||
}
|
||||
|
||||
A codec is tied to a content type. In the example above, the server
|
||||
will use the ProtoRPC codec for requests with "application/json" as
|
||||
the value for the "Content-Type" header.
|
||||
|
||||
This package implement ProtoRPC, based on the JSON-RPC transport, it
|
||||
differs in that it uses HTTP as its envelope.
|
||||
|
||||
Example:
|
||||
POST /Service.Method
|
||||
Request:
|
||||
{
|
||||
"requestField1": "value1",
|
||||
"requestField2": "value2",
|
||||
}
|
||||
Response:
|
||||
{
|
||||
"responseField1": "value1",
|
||||
"responseField2": "value2",
|
||||
}
|
||||
|
||||
Check the gorilla/rpc documentation for more details:
|
||||
|
||||
http://gorilla-web.appspot.com/pkg/rpc
|
||||
*/
|
||||
package protorpc
|
87
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/protorpc_test.go
generated
vendored
87
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/protorpc_test.go
generated
vendored
@ -1,87 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package protorpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
var ErrResponseError = errors.New("response error")
|
||||
|
||||
type Service1Request struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type Service1BadRequest struct {
|
||||
}
|
||||
|
||||
type Service1Response struct {
|
||||
Result int
|
||||
ErrorMessage string `json:"error_message"`
|
||||
}
|
||||
|
||||
type Service1 struct {
|
||||
}
|
||||
|
||||
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
res.Result = req.A * req.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Service1) ResponseError(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
return ErrResponseError
|
||||
}
|
||||
|
||||
func execute(t *testing.T, s *rpc.Server, method string, req, res interface{}) (int, error) {
|
||||
if !s.HasMethod(method) {
|
||||
t.Fatal("Expected to be registered:", method)
|
||||
}
|
||||
|
||||
buf, _ := json.Marshal(req)
|
||||
body := bytes.NewBuffer(buf)
|
||||
r, _ := http.NewRequest("POST", "http://localhost:8080/"+method, body)
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
s.ServeHTTP(w, r)
|
||||
|
||||
err := json.NewDecoder(w.Body).Decode(res)
|
||||
return w.Code, err
|
||||
}
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
s := rpc.NewServer()
|
||||
s.RegisterCodec(NewCodec(), "application/json")
|
||||
s.RegisterService(new(Service1), "")
|
||||
|
||||
var res Service1Response
|
||||
if _, err := execute(t, s, "Service1.Multiply", &Service1Request{4, 2}, &res); err != nil {
|
||||
t.Error("Expected err to be nil, but got:", err)
|
||||
}
|
||||
if res.Result != 8 {
|
||||
t.Error("Expected res.Result to be 8, but got:", res.Result)
|
||||
}
|
||||
if res.ErrorMessage != "" {
|
||||
t.Error("Expected error_message to be empty, but got:", res.ErrorMessage)
|
||||
}
|
||||
if code, err := execute(t, s, "Service1.ResponseError", &Service1Request{4, 2}, &res); err != nil || code != 400 {
|
||||
t.Errorf("Expected code to be 400 and error to be nil, but got %v (%v)", code, err)
|
||||
}
|
||||
if res.ErrorMessage == "" {
|
||||
t.Errorf("Expected error_message to be %q, but got %q", ErrResponseError, res.ErrorMessage)
|
||||
}
|
||||
if code, _ := execute(t, s, "Service1.Multiply", nil, &res); code != 400 {
|
||||
t.Error("Expected http response code 400, but got", code)
|
||||
}
|
||||
}
|
147
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/server.go
generated
vendored
147
Godeps/_workspace/src/github.com/gorilla/rpc/v2/protorpc/server.go
generated
vendored
@ -1,147 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package protorpc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
var null = json.RawMessage([]byte("null"))
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Request and Response
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// serverRequest represents a ProtoRPC request received by the server.
|
||||
type serverRequest struct {
|
||||
// A String containing the name of the method to be invoked.
|
||||
Method string `json:"method"`
|
||||
// An Array of objects to pass as arguments to the method.
|
||||
Params *json.RawMessage `json:"params"`
|
||||
// The request id. This can be of any type. It is used to match the
|
||||
// response with the request that it is replying to.
|
||||
Id *json.RawMessage `json:"id"`
|
||||
}
|
||||
|
||||
// serverResponse represents a ProtoRPC response returned by the server.
|
||||
type serverResponse struct {
|
||||
// The Object that was returned by the invoked method. This must be null
|
||||
// in case there was an error invoking the method.
|
||||
Result interface{} `json:"result"`
|
||||
// An Error object if there was an error invoking the method. It must be
|
||||
// null if there was no error.
|
||||
Error interface{} `json:"error"`
|
||||
// This must be the same id as the request it is responding to.
|
||||
Id *json.RawMessage `json:"id"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Codec
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// NewCodec returns a new ProtoRPC Codec.
|
||||
func NewCodec() *Codec {
|
||||
return &Codec{}
|
||||
}
|
||||
|
||||
// Codec creates a CodecRequest to process each request.
|
||||
type Codec struct {
|
||||
}
|
||||
|
||||
// NewRequest returns a CodecRequest.
|
||||
func (c *Codec) NewRequest(r *http.Request) rpc.CodecRequest {
|
||||
return newCodecRequest(r)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CodecRequest
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// newCodecRequest returns a new CodecRequest.
|
||||
func newCodecRequest(r *http.Request) rpc.CodecRequest {
|
||||
// Decode the request body and check if RPC method is valid.
|
||||
req := new(serverRequest)
|
||||
path := r.URL.Path
|
||||
index := strings.LastIndex(path, "/")
|
||||
if index < 0 {
|
||||
return &CodecRequest{request: req, err: fmt.Errorf("rpc: no method: %s", path)}
|
||||
}
|
||||
req.Method = path[index+1:]
|
||||
err := json.NewDecoder(r.Body).Decode(&req.Params)
|
||||
r.Body.Close()
|
||||
var errr error
|
||||
if err != io.EOF {
|
||||
errr = err
|
||||
}
|
||||
return &CodecRequest{request: req, err: errr}
|
||||
}
|
||||
|
||||
// CodecRequest decodes and encodes a single request.
|
||||
type CodecRequest struct {
|
||||
request *serverRequest
|
||||
err error
|
||||
}
|
||||
|
||||
// Method returns the RPC method for the current request.
|
||||
//
|
||||
// The method uses a dotted notation as in "Service.Method".
|
||||
func (c *CodecRequest) Method() (string, error) {
|
||||
if c.err == nil {
|
||||
return c.request.Method, nil
|
||||
}
|
||||
return "", c.err
|
||||
}
|
||||
|
||||
// ReadRequest fills the request object for the RPC method.
|
||||
func (c *CodecRequest) ReadRequest(args interface{}) error {
|
||||
if c.err == nil {
|
||||
if c.request.Params != nil {
|
||||
c.err = json.Unmarshal(*c.request.Params, args)
|
||||
} else {
|
||||
c.err = errors.New("rpc: method request ill-formed: missing params field")
|
||||
}
|
||||
}
|
||||
return c.err
|
||||
}
|
||||
|
||||
// WriteResponse encodes the response and writes it to the ResponseWriter.
|
||||
func (c *CodecRequest) WriteResponse(w http.ResponseWriter, reply interface{}) {
|
||||
res := &serverResponse{
|
||||
Result: reply,
|
||||
Error: &null,
|
||||
Id: c.request.Id,
|
||||
}
|
||||
c.writeServerResponse(w, 200, res)
|
||||
}
|
||||
|
||||
func (c *CodecRequest) WriteError(w http.ResponseWriter, status int, err error) {
|
||||
res := &serverResponse{
|
||||
Result: &struct {
|
||||
ErrorMessage interface{} `json:"error_message"`
|
||||
}{err.Error()},
|
||||
Id: c.request.Id,
|
||||
}
|
||||
c.writeServerResponse(w, status, res)
|
||||
}
|
||||
|
||||
func (c *CodecRequest) writeServerResponse(w http.ResponseWriter, status int, res *serverResponse) {
|
||||
b, err := json.Marshal(res.Result)
|
||||
if err == nil {
|
||||
w.WriteHeader(status)
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.Write(b)
|
||||
} else {
|
||||
// Not sure in which case will this happen. But seems harmless.
|
||||
rpc.WriteError(w, 400, err.Error())
|
||||
}
|
||||
}
|
54
Godeps/_workspace/src/github.com/gorilla/rpc/v2/server_test.go
generated
vendored
54
Godeps/_workspace/src/github.com/gorilla/rpc/v2/server_test.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Gorilla Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Service1Request struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type Service1Response struct {
|
||||
Result int
|
||||
}
|
||||
|
||||
type Service1 struct {
|
||||
}
|
||||
|
||||
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
|
||||
res.Result = req.A * req.B
|
||||
return nil
|
||||
}
|
||||
|
||||
type Service2 struct {
|
||||
}
|
||||
|
||||
func TestRegisterService(t *testing.T) {
|
||||
var err error
|
||||
s := NewServer()
|
||||
service1 := new(Service1)
|
||||
service2 := new(Service2)
|
||||
|
||||
// Inferred name.
|
||||
err = s.RegisterService(service1, "")
|
||||
if err != nil || !s.HasMethod("Service1.Multiply") {
|
||||
t.Errorf("Expected to be registered: Service1.Multiply")
|
||||
}
|
||||
// Provided name.
|
||||
err = s.RegisterService(service1, "Foo")
|
||||
if err != nil || !s.HasMethod("Foo.Multiply") {
|
||||
t.Errorf("Expected to be registered: Foo.Multiply")
|
||||
}
|
||||
// No methods.
|
||||
err = s.RegisterService(service2, "")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on service2")
|
||||
}
|
||||
}
|
6
Godeps/_workspace/src/github.com/minio/cli/.travis.yml
generated
vendored
6
Godeps/_workspace/src/github.com/minio/cli/.travis.yml
generated
vendored
@ -1,6 +0,0 @@
|
||||
language: go
|
||||
go: 1.1
|
||||
|
||||
script:
|
||||
- go vet ./...
|
||||
- go test -v ./...
|
587
Godeps/_workspace/src/github.com/minio/cli/app_test.go
generated
vendored
587
Godeps/_workspace/src/github.com/minio/cli/app_test.go
generated
vendored
@ -1,587 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
func ExampleApp() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "--name", "Jeremy"}
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Name = "greet"
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
||||
}
|
||||
app.Action = func(c *cli.Context) {
|
||||
fmt.Printf("Hello %v\n", c.String("name"))
|
||||
}
|
||||
app.Author = "Harrison"
|
||||
app.Email = "harrison@lolwut.com"
|
||||
app.Authors = []cli.Author{{Name: "Oliver Allen", Email: "oliver@toyshop.com"}}
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// Hello Jeremy
|
||||
}
|
||||
|
||||
func ExampleAppSubcommand() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
|
||||
app := cli.NewApp()
|
||||
app.Name = "say"
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "hello",
|
||||
Aliases: []string{"hi"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe hello the function",
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "english",
|
||||
Aliases: []string{"en"},
|
||||
Usage: "sends a greeting in english",
|
||||
Description: "greets someone in english",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "Bob",
|
||||
Usage: "Name of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
fmt.Println("Hello,", c.String("name"))
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// Hello, Jeremy
|
||||
}
|
||||
|
||||
func ExampleAppHelp() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "h", "describeit"}
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Name = "greet"
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
||||
}
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "describeit",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe describeit the function",
|
||||
Action: func(c *cli.Context) {
|
||||
fmt.Printf("i like to describe things")
|
||||
},
|
||||
},
|
||||
}
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// NAME:
|
||||
// describeit - use it to see a description
|
||||
//
|
||||
// USAGE:
|
||||
// command describeit [arguments...]
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This is how we describe describeit the function
|
||||
}
|
||||
|
||||
func TestApp_Run(t *testing.T) {
|
||||
s := ""
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Action = func(c *cli.Context) {
|
||||
s = s + c.Args().First()
|
||||
}
|
||||
|
||||
err := app.Run([]string{"command", "foo"})
|
||||
expect(t, err, nil)
|
||||
err = app.Run([]string{"command", "bar"})
|
||||
expect(t, err, nil)
|
||||
expect(t, s, "foobar")
|
||||
}
|
||||
|
||||
var commandAppTests = []struct {
|
||||
name string
|
||||
expected bool
|
||||
}{
|
||||
{"foobar", true},
|
||||
{"batbaz", true},
|
||||
{"b", true},
|
||||
{"f", true},
|
||||
{"bat", false},
|
||||
{"nothing", false},
|
||||
}
|
||||
|
||||
func TestApp_Command(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
fooCommand := cli.Command{Name: "foobar", Aliases: []string{"f"}}
|
||||
batCommand := cli.Command{Name: "batbaz", Aliases: []string{"b"}}
|
||||
app.Commands = []cli.Command{
|
||||
fooCommand,
|
||||
batCommand,
|
||||
}
|
||||
|
||||
for _, test := range commandAppTests {
|
||||
expect(t, app.Command(test.name) != nil, test.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
|
||||
var parsedOption, firstArg string
|
||||
|
||||
app := cli.NewApp()
|
||||
command := cli.Command{
|
||||
Name: "cmd",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
parsedOption = c.String("option")
|
||||
firstArg = c.Args().First()
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
|
||||
|
||||
expect(t, parsedOption, "my-option")
|
||||
expect(t, firstArg, "my-arg")
|
||||
}
|
||||
|
||||
func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
|
||||
var context *cli.Context
|
||||
|
||||
a := cli.NewApp()
|
||||
a.Commands = []cli.Command{
|
||||
{
|
||||
Name: "foo",
|
||||
Action: func(c *cli.Context) {
|
||||
context = c
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "lang",
|
||||
Value: "english",
|
||||
Usage: "language for the greeting",
|
||||
},
|
||||
},
|
||||
Before: func(_ *cli.Context) error { return nil },
|
||||
},
|
||||
}
|
||||
a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})
|
||||
|
||||
expect(t, context.Args().Get(0), "abcd")
|
||||
expect(t, context.String("lang"), "spanish")
|
||||
}
|
||||
|
||||
func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
|
||||
var parsedOption string
|
||||
var args []string
|
||||
|
||||
app := cli.NewApp()
|
||||
command := cli.Command{
|
||||
Name: "cmd",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
parsedOption = c.String("option")
|
||||
args = c.Args()
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"})
|
||||
|
||||
expect(t, parsedOption, "my-option")
|
||||
expect(t, args[0], "my-arg")
|
||||
expect(t, args[1], "--")
|
||||
expect(t, args[2], "--notARealFlag")
|
||||
}
|
||||
|
||||
func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
|
||||
var args []string
|
||||
|
||||
app := cli.NewApp()
|
||||
command := cli.Command{
|
||||
Name: "cmd",
|
||||
Action: func(c *cli.Context) {
|
||||
args = c.Args()
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})
|
||||
|
||||
expect(t, args[0], "my-arg")
|
||||
expect(t, args[1], "--")
|
||||
expect(t, args[2], "notAFlagAtAll")
|
||||
}
|
||||
|
||||
func TestApp_Float64Flag(t *testing.T) {
|
||||
var meters float64
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Flags = []cli.Flag{
|
||||
cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
|
||||
}
|
||||
app.Action = func(c *cli.Context) {
|
||||
meters = c.Float64("height")
|
||||
}
|
||||
|
||||
app.Run([]string{"", "--height", "1.93"})
|
||||
expect(t, meters, 1.93)
|
||||
}
|
||||
|
||||
func TestApp_ParseSliceFlags(t *testing.T) {
|
||||
var parsedOption, firstArg string
|
||||
var parsedIntSlice []int
|
||||
var parsedStringSlice []string
|
||||
|
||||
app := cli.NewApp()
|
||||
command := cli.Command{
|
||||
Name: "cmd",
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
|
||||
cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
parsedIntSlice = c.IntSlice("p")
|
||||
parsedStringSlice = c.StringSlice("ip")
|
||||
parsedOption = c.String("option")
|
||||
firstArg = c.Args().First()
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
|
||||
|
||||
IntsEquals := func(a, b []int) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
StrsEquals := func(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
var expectedIntSlice = []int{22, 80}
|
||||
var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
|
||||
|
||||
if !IntsEquals(parsedIntSlice, expectedIntSlice) {
|
||||
t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
|
||||
}
|
||||
|
||||
if !StrsEquals(parsedStringSlice, expectedStringSlice) {
|
||||
t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_DefaultStdout(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
|
||||
if app.Writer != os.Stdout {
|
||||
t.Error("Default output writer not set.")
|
||||
}
|
||||
}
|
||||
|
||||
type mockWriter struct {
|
||||
written []byte
|
||||
}
|
||||
|
||||
func (fw *mockWriter) Write(p []byte) (n int, err error) {
|
||||
if fw.written == nil {
|
||||
fw.written = p
|
||||
} else {
|
||||
fw.written = append(fw.written, p...)
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (fw *mockWriter) GetWritten() (b []byte) {
|
||||
return fw.written
|
||||
}
|
||||
|
||||
func TestApp_SetStdout(t *testing.T) {
|
||||
w := &mockWriter{}
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Name = "test"
|
||||
app.Writer = w
|
||||
|
||||
err := app.Run([]string{"help"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if len(w.written) == 0 {
|
||||
t.Error("App did not write output to desired writer.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_BeforeFunc(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
beforeError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Before = func(c *cli.Context) error {
|
||||
beforeRun = true
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return beforeError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "sub",
|
||||
Action: func(c *cli.Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{Name: "opt"},
|
||||
}
|
||||
|
||||
// run with the Before() func succeeding
|
||||
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
beforeRun, subcommandRun = false, false
|
||||
|
||||
// run with the Before() func failing
|
||||
err = app.Run([]string{"command", "--opt", "fail", "sub"})
|
||||
|
||||
// should be the same error produced by the Before func
|
||||
if err != beforeError {
|
||||
t.Errorf("Run error expected, but not received")
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == true {
|
||||
t.Errorf("Subcommand executed when NOT expected")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestApp_AfterFunc(t *testing.T) {
|
||||
afterRun, subcommandRun := false, false
|
||||
afterError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := cli.NewApp()
|
||||
|
||||
app.After = func(c *cli.Context) error {
|
||||
afterRun = true
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return afterError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "sub",
|
||||
Action: func(c *cli.Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{Name: "opt"},
|
||||
}
|
||||
|
||||
// run with the After() func succeeding
|
||||
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
afterRun, subcommandRun = false, false
|
||||
|
||||
// run with the Before() func failing
|
||||
err = app.Run([]string{"command", "--opt", "fail", "sub"})
|
||||
|
||||
// should be the same error produced by the Before func
|
||||
if err != afterError {
|
||||
t.Errorf("Run error expected, but not received")
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppNoHelpFlag(t *testing.T) {
|
||||
oldFlag := cli.HelpFlag
|
||||
defer func() {
|
||||
cli.HelpFlag = oldFlag
|
||||
}()
|
||||
|
||||
cli.HelpFlag = cli.BoolFlag{}
|
||||
|
||||
app := cli.NewApp()
|
||||
err := app.Run([]string{"test", "-h"})
|
||||
|
||||
if err != flag.ErrHelp {
|
||||
t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppHelpPrinter(t *testing.T) {
|
||||
oldPrinter := cli.HelpPrinter
|
||||
defer func() {
|
||||
cli.HelpPrinter = oldPrinter
|
||||
}()
|
||||
|
||||
var wasCalled = false
|
||||
cli.HelpPrinter = func(template string, data interface{}) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Run([]string{"-h"})
|
||||
|
||||
if wasCalled == false {
|
||||
t.Errorf("Help printer expected to be called, but was not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppVersionPrinter(t *testing.T) {
|
||||
oldPrinter := cli.VersionPrinter
|
||||
defer func() {
|
||||
cli.VersionPrinter = oldPrinter
|
||||
}()
|
||||
|
||||
var wasCalled = false
|
||||
cli.VersionPrinter = func(c *cli.Context) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
app := cli.NewApp()
|
||||
ctx := cli.NewContext(app, nil, nil)
|
||||
cli.ShowVersion(ctx)
|
||||
|
||||
if wasCalled == false {
|
||||
t.Errorf("Version printer expected to be called, but was not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppCommandNotFound(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
app := cli.NewApp()
|
||||
|
||||
app.CommandNotFound = func(c *cli.Context, command string) {
|
||||
beforeRun = true
|
||||
}
|
||||
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "bar",
|
||||
Action: func(c *cli.Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "foo"})
|
||||
|
||||
expect(t, beforeRun, true)
|
||||
expect(t, subcommandRun, false)
|
||||
}
|
||||
|
||||
func TestGlobalFlagsInSubcommands(t *testing.T) {
|
||||
subcommandRun := false
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
|
||||
}
|
||||
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "foo",
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "bar",
|
||||
Action: func(c *cli.Context) {
|
||||
if c.GlobalBool("debug") {
|
||||
subcommandRun = true
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "-d", "foo", "bar"})
|
||||
|
||||
expect(t, subcommandRun, true)
|
||||
}
|
13
Godeps/_workspace/src/github.com/minio/cli/autocomplete/bash_autocomplete
generated
vendored
13
Godeps/_workspace/src/github.com/minio/cli/autocomplete/bash_autocomplete
generated
vendored
@ -1,13 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
_cli_bash_autocomplete() {
|
||||
local cur prev opts base
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _cli_bash_autocomplete $PROG
|
5
Godeps/_workspace/src/github.com/minio/cli/autocomplete/zsh_autocomplete
generated
vendored
5
Godeps/_workspace/src/github.com/minio/cli/autocomplete/zsh_autocomplete
generated
vendored
@ -1,5 +0,0 @@
|
||||
autoload -U compinit && compinit
|
||||
autoload -U bashcompinit && bashcompinit
|
||||
|
||||
script_dir=$(dirname $0)
|
||||
source ${script_dir}/bash_autocomplete
|
100
Godeps/_workspace/src/github.com/minio/cli/cli_test.go
generated
vendored
100
Godeps/_workspace/src/github.com/minio/cli/cli_test.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "todo"
|
||||
app.Usage = "task list on the command line"
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "add a task to the list",
|
||||
Action: func(c *cli.Context) {
|
||||
println("added task: ", c.Args().First())
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "complete",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "complete a task on the list",
|
||||
Action: func(c *cli.Context) {
|
||||
println("completed task: ", c.Args().First())
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
func ExampleSubcommand() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "say"
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "hello",
|
||||
Aliases: []string{"hi"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe hello the function",
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "english",
|
||||
Aliases: []string{"en"},
|
||||
Usage: "sends a greeting in english",
|
||||
Description: "greets someone in english",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "Bob",
|
||||
Usage: "Name of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
println("Hello, ", c.String("name"))
|
||||
},
|
||||
}, {
|
||||
Name: "spanish",
|
||||
Aliases: []string{"sp"},
|
||||
Usage: "sends a greeting in spanish",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "surname",
|
||||
Value: "Jones",
|
||||
Usage: "Surname of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
println("Hola, ", c.String("surname"))
|
||||
},
|
||||
}, {
|
||||
Name: "french",
|
||||
Aliases: []string{"fr"},
|
||||
Usage: "sends a greeting in french",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "nickname",
|
||||
Value: "Stevie",
|
||||
Usage: "Nickname of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
println("Bonjour, ", c.String("nickname"))
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Name: "bye",
|
||||
Usage: "says goodbye",
|
||||
Action: func(c *cli.Context) {
|
||||
println("bye")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
}
|
49
Godeps/_workspace/src/github.com/minio/cli/command_test.go
generated
vendored
49
Godeps/_workspace/src/github.com/minio/cli/command_test.go
generated
vendored
@ -1,49 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
func TestCommandDoNotIgnoreFlags(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
test := []string{"blah", "blah", "-break"}
|
||||
set.Parse(test)
|
||||
|
||||
c := cli.NewContext(app, set, set)
|
||||
|
||||
command := cli.Command{
|
||||
Name: "test-cmd",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "this is for testing",
|
||||
Description: "testing",
|
||||
Action: func(_ *cli.Context) {},
|
||||
}
|
||||
err := command.Run(c)
|
||||
|
||||
expect(t, err.Error(), "flag provided but not defined: -break")
|
||||
}
|
||||
|
||||
func TestCommandIgnoreFlags(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
test := []string{"blah", "blah"}
|
||||
set.Parse(test)
|
||||
|
||||
c := cli.NewContext(app, set, set)
|
||||
|
||||
command := cli.Command{
|
||||
Name: "test-cmd",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "this is for testing",
|
||||
Description: "testing",
|
||||
Action: func(_ *cli.Context) {},
|
||||
SkipFlagParsing: true,
|
||||
}
|
||||
err := command.Run(c)
|
||||
|
||||
expect(t, err, nil)
|
||||
}
|
111
Godeps/_workspace/src/github.com/minio/cli/context_test.go
generated
vendored
111
Godeps/_workspace/src/github.com/minio/cli/context_test.go
generated
vendored
@ -1,111 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
func TestNewContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Int("myflag", 42, "doc")
|
||||
command := cli.Command{Name: "mycommand"}
|
||||
c := cli.NewContext(nil, set, globalSet)
|
||||
c.Command = command
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
expect(t, c.GlobalInt("myflag"), 42)
|
||||
expect(t, c.Command.Name, "mycommand")
|
||||
}
|
||||
|
||||
func TestContext_Int(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
}
|
||||
|
||||
func TestContext_Duration(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Duration("myflag", time.Duration(12*time.Second), "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
|
||||
}
|
||||
|
||||
func TestContext_String(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("myflag", "hello world", "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
expect(t, c.String("myflag"), "hello world")
|
||||
}
|
||||
|
||||
func TestContext_Bool(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
expect(t, c.Bool("myflag"), false)
|
||||
}
|
||||
|
||||
func TestContext_BoolT(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", true, "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
expect(t, c.BoolT("myflag"), true)
|
||||
}
|
||||
|
||||
func TestContext_Args(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
c := cli.NewContext(nil, set, set)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
expect(t, len(c.Args()), 2)
|
||||
expect(t, c.Bool("myflag"), true)
|
||||
}
|
||||
|
||||
func TestContext_IsSet(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
c := cli.NewContext(nil, set, globalSet)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
||||
expect(t, c.IsSet("myflag"), true)
|
||||
expect(t, c.IsSet("otherflag"), false)
|
||||
expect(t, c.IsSet("bogusflag"), false)
|
||||
expect(t, c.IsSet("myflagGlobal"), false)
|
||||
}
|
||||
|
||||
func TestContext_GlobalIsSet(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
globalSet.Bool("myflagGlobalUnset", true, "doc")
|
||||
c := cli.NewContext(nil, set, globalSet)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
||||
expect(t, c.GlobalIsSet("myflag"), false)
|
||||
expect(t, c.GlobalIsSet("otherflag"), false)
|
||||
expect(t, c.GlobalIsSet("bogusflag"), false)
|
||||
expect(t, c.GlobalIsSet("myflagGlobal"), true)
|
||||
expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
|
||||
expect(t, c.GlobalIsSet("bogusGlobal"), false)
|
||||
}
|
||||
|
||||
func TestContext_NumFlags(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
c := cli.NewContext(nil, set, globalSet)
|
||||
set.Parse([]string{"--myflag", "--otherflag=foo"})
|
||||
globalSet.Parse([]string{"--myflagGlobal"})
|
||||
expect(t, c.NumFlags(), 2)
|
||||
}
|
742
Godeps/_workspace/src/github.com/minio/cli/flag_test.go
generated
vendored
742
Godeps/_workspace/src/github.com/minio/cli/flag_test.go
generated
vendored
@ -1,742 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
var boolFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help\t"},
|
||||
{"h", "-h\t"},
|
||||
}
|
||||
|
||||
func TestBoolFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range boolFlagTests {
|
||||
flag := cli.BoolFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stringFlagTests = []struct {
|
||||
name string
|
||||
value string
|
||||
expected string
|
||||
}{
|
||||
{"help", "", "--help \t"},
|
||||
{"h", "", "-h \t"},
|
||||
{"h", "", "-h \t"},
|
||||
{"test", "Something", "--test \"Something\"\t"},
|
||||
}
|
||||
|
||||
func TestStringFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range stringFlagTests {
|
||||
flag := cli.StringFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_FOO", "derp")
|
||||
for _, test := range stringFlagTests {
|
||||
flag := cli.StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_FOO]") {
|
||||
t.Errorf("%s does not end with [$APP_FOO]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stringSliceFlagTests = []struct {
|
||||
name string
|
||||
value *cli.StringSlice
|
||||
expected string
|
||||
}{
|
||||
{"help", func() *cli.StringSlice {
|
||||
s := &cli.StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "--help [--help option --help option]\t"},
|
||||
{"h", func() *cli.StringSlice {
|
||||
s := &cli.StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "-h [-h option -h option]\t"},
|
||||
{"h", func() *cli.StringSlice {
|
||||
s := &cli.StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "-h [-h option -h option]\t"},
|
||||
{"test", func() *cli.StringSlice {
|
||||
s := &cli.StringSlice{}
|
||||
s.Set("Something")
|
||||
return s
|
||||
}(), "--test [--test option --test option]\t"},
|
||||
}
|
||||
|
||||
func TestStringSliceFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range stringSliceFlagTests {
|
||||
flag := cli.StringSliceFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_QWWX", "11,4")
|
||||
for _, test := range stringSliceFlagTests {
|
||||
flag := cli.StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_QWWX]") {
|
||||
t.Errorf("%q does not end with [$APP_QWWX]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var intFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestIntFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range intFlagTests {
|
||||
flag := cli.IntFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAR", "2")
|
||||
for _, test := range intFlagTests {
|
||||
flag := cli.IntFlag{Name: test.name, EnvVar: "APP_BAR"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAR]") {
|
||||
t.Errorf("%s does not end with [$APP_BAR]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var durationFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestDurationFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range durationFlagTests {
|
||||
flag := cli.DurationFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAR", "2h3m6s")
|
||||
for _, test := range durationFlagTests {
|
||||
flag := cli.DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAR]") {
|
||||
t.Errorf("%s does not end with [$APP_BAR]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var intSliceFlagTests = []struct {
|
||||
name string
|
||||
value *cli.IntSlice
|
||||
expected string
|
||||
}{
|
||||
{"help", &cli.IntSlice{}, "--help [--help option --help option]\t"},
|
||||
{"h", &cli.IntSlice{}, "-h [-h option -h option]\t"},
|
||||
{"h", &cli.IntSlice{}, "-h [-h option -h option]\t"},
|
||||
{"test", func() *cli.IntSlice {
|
||||
i := &cli.IntSlice{}
|
||||
i.Set("9")
|
||||
return i
|
||||
}(), "--test [--test option --test option]\t"},
|
||||
}
|
||||
|
||||
func TestIntSliceFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range intSliceFlagTests {
|
||||
flag := cli.IntSliceFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_SMURF", "42,3")
|
||||
for _, test := range intSliceFlagTests {
|
||||
flag := cli.IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_SMURF]") {
|
||||
t.Errorf("%q does not end with [$APP_SMURF]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var float64FlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestFloat64FlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range float64FlagTests {
|
||||
flag := cli.Float64Flag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAZ", "99.4")
|
||||
for _, test := range float64FlagTests {
|
||||
flag := cli.Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAZ]") {
|
||||
t.Errorf("%s does not end with [$APP_BAZ]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var genericFlagTests = []struct {
|
||||
name string
|
||||
value cli.Generic
|
||||
expected string
|
||||
}{
|
||||
{"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
|
||||
{"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
|
||||
}
|
||||
|
||||
func TestGenericFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range genericFlagTests {
|
||||
flag := cli.GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_ZAP", "3")
|
||||
for _, test := range genericFlagTests {
|
||||
flag := cli.GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_ZAP]") {
|
||||
t.Errorf("%s does not end with [$APP_ZAP]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMultiString(t *testing.T) {
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.String("serve") != "10" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("s") != "10" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_COUNT", "20")
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.String("count") != "20" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("c") != "20" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_COUNT", "20")
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.String("count") != "20" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("c") != "20" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSlice(t *testing.T) {
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10", "-s", "20"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSliceFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiInt(t *testing.T) {
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Int("serve") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("s") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "10")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Int("timeout") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("t") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "10")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Int("timeout") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("t") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSlice(t *testing.T) {
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{Name: "serve, s", Value: &cli.IntSlice{}},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10", "-s", "20"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSliceFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64(t *testing.T) {
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.Float64Flag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Float64("serve") != 10.2 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("s") != 10.2 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10.2"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64FromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Float64("timeout") != 15.5 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("t") != 15.5 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Float64("timeout") != 15.5 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("t") != 15.5 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBool(t *testing.T) {
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Bool("serve") != true {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Bool("s") != true {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "--serve"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "1")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Bool("debug") != true {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.Bool("d") != true {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "1")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.Bool("debug") != true {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.Bool("d") != true {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolT(t *testing.T) {
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolTFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.BoolT("serve") != true {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.BoolT("s") != true {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "--serve"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolTFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "0")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.BoolT("debug") != false {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.BoolT("d") != false {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "0")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if ctx.BoolT("debug") != false {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.BoolT("d") != false {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
type Parser [2]string
|
||||
|
||||
func (p *Parser) Set(value string) error {
|
||||
parts := strings.Split(value, ",")
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid format")
|
||||
}
|
||||
|
||||
(*p)[0] = parts[0]
|
||||
(*p)[1] = parts[1]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) String() string {
|
||||
return fmt.Sprintf("%s,%s", p[0], p[1])
|
||||
}
|
||||
|
||||
func TestParseGeneric(t *testing.T) {
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.GenericFlag{Name: "serve, s", Value: &Parser{}},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10,20"})
|
||||
}
|
||||
|
||||
func TestParseGenericFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_SERVE", "20,30")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseGenericFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_FOO", "99,2000")
|
||||
a := cli.App{
|
||||
Flags: []cli.Flag{
|
||||
cli.GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
|
||||
},
|
||||
Action: func(ctx *cli.Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
|
||||
t.Errorf("value not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
19
Godeps/_workspace/src/github.com/minio/cli/helpers_test.go
generated
vendored
19
Godeps/_workspace/src/github.com/minio/cli/helpers_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/* Test Helpers */
|
||||
func expect(t *testing.T, a interface{}, b interface{}) {
|
||||
if a != b {
|
||||
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func refute(t *testing.T, a interface{}, b interface{}) {
|
||||
if a == b {
|
||||
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
4
Godeps/_workspace/src/gopkg.in/check.v1/.gitignore
generated
vendored
4
Godeps/_workspace/src/gopkg.in/check.v1/.gitignore
generated
vendored
@ -1,4 +0,0 @@
|
||||
_*
|
||||
*.swp
|
||||
*.[568]
|
||||
[568].out
|
91
Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go
generated
vendored
91
Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
// These tests verify the test running logic.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var benchmarkS = Suite(&BenchmarkS{})
|
||||
|
||||
type BenchmarkS struct{}
|
||||
|
||||
func (s *BenchmarkS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBasicTestTiming(c *C) {
|
||||
helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" +
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestStreamTestTiming(c *C) {
|
||||
helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmark(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark1",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Benchmark1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Benchmark1")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
// ... and more.
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmarkBytes(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark2",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *BenchmarkS) TestBenchmarkMem(c *C) {
|
||||
helper := FixtureHelper{sleep: 100000}
|
||||
output := String{}
|
||||
runConf := RunConf{
|
||||
Output: &output,
|
||||
Benchmark: true,
|
||||
BenchmarkMem: true,
|
||||
BenchmarkTime: 10000000,
|
||||
Filter: "Benchmark3",
|
||||
}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n"
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
82
Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go
generated
vendored
82
Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go
generated
vendored
@ -1,82 +0,0 @@
|
||||
// These initial tests are for bootstrapping. They verify that we can
|
||||
// basically use the testing infrastructure itself to check if the test
|
||||
// system is working.
|
||||
//
|
||||
// These tests use will break down the test runner badly in case of
|
||||
// errors because if they simply fail, we can't be sure the developer
|
||||
// will ever see anything (because failing means the failing system
|
||||
// somehow isn't working! :-)
|
||||
//
|
||||
// Do not assume *any* internal functionality works as expected besides
|
||||
// what's actually tested here.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/check.v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BootstrapS struct{}
|
||||
|
||||
var boostrapS = check.Suite(&BootstrapS{})
|
||||
|
||||
func (s *BootstrapS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestFailedAndFail(c *check.C) {
|
||||
if c.Failed() {
|
||||
critical("c.Failed() must be false first!")
|
||||
}
|
||||
c.Fail()
|
||||
if !c.Failed() {
|
||||
critical("c.Fail() didn't put the test in a failed state!")
|
||||
}
|
||||
c.Succeed()
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestFailedAndSucceed(c *check.C) {
|
||||
c.Fail()
|
||||
c.Succeed()
|
||||
if c.Failed() {
|
||||
critical("c.Succeed() didn't put the test back in a non-failed state")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) {
|
||||
c.Log("Hello there!")
|
||||
log := c.GetTestLog()
|
||||
if log != "Hello there!\n" {
|
||||
critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) {
|
||||
c.Logf("Hello %v", "there!")
|
||||
log := c.GetTestLog()
|
||||
if log != "Hello there!\n" {
|
||||
critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestRunShowsErrors(c *check.C) {
|
||||
output := String{}
|
||||
check.Run(&FailHelper{}, &check.RunConf{Output: &output})
|
||||
if strings.Index(output.value, "Expected failure!") == -1 {
|
||||
critical(fmt.Sprintf("RunWithWriter() output did not contain the "+
|
||||
"expected failure! Got: %#v",
|
||||
output.value))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) {
|
||||
output := String{}
|
||||
check.Run(&SuccessHelper{}, &check.RunConf{Output: &output})
|
||||
if strings.Index(output.value, "Expected success!") != -1 {
|
||||
critical(fmt.Sprintf("RunWithWriter() output contained a successful "+
|
||||
"test! Got: %#v",
|
||||
output.value))
|
||||
}
|
||||
}
|
207
Godeps/_workspace/src/gopkg.in/check.v1/check_test.go
generated
vendored
207
Godeps/_workspace/src/gopkg.in/check.v1/check_test.go
generated
vendored
@ -1,207 +0,0 @@
|
||||
// This file contains just a few generic helpers which are used by the
|
||||
// other test files.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
// We count the number of suites run at least to get a vague hint that the
|
||||
// test suite is behaving as it should. Otherwise a bug introduced at the
|
||||
// very core of the system could go unperceived.
|
||||
const suitesRunExpected = 8
|
||||
|
||||
var suitesRun int = 0
|
||||
|
||||
func Test(t *testing.T) {
|
||||
check.TestingT(t)
|
||||
if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" {
|
||||
critical(fmt.Sprintf("Expected %d suites to run rather than %d",
|
||||
suitesRunExpected, suitesRun))
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper functions.
|
||||
|
||||
// Break down badly. This is used in test cases which can't yet assume
|
||||
// that the fundamental bits are working.
|
||||
func critical(error string) {
|
||||
fmt.Fprintln(os.Stderr, "CRITICAL: "+error)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Return the file line where it's called.
|
||||
func getMyLine() int {
|
||||
if _, _, line, ok := runtime.Caller(1); ok {
|
||||
return line
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper type implementing a basic io.Writer for testing output.
|
||||
|
||||
// Type implementing the io.Writer interface for analyzing output.
|
||||
type String struct {
|
||||
value string
|
||||
}
|
||||
|
||||
// The only function required by the io.Writer interface. Will append
|
||||
// written data to the String.value string.
|
||||
func (s *String) Write(p []byte) (n int, err error) {
|
||||
s.value += string(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Trivial wrapper to test errors happening on a different file
|
||||
// than the test itself.
|
||||
func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) {
|
||||
return c.Check(obtained, check.Equals, expected), getMyLine()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing basic fail behavior.
|
||||
|
||||
type FailHelper struct {
|
||||
testLine int
|
||||
}
|
||||
|
||||
func (s *FailHelper) TestLogAndFail(c *check.C) {
|
||||
s.testLine = getMyLine() - 1
|
||||
c.Log("Expected failure!")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing basic success behavior.
|
||||
|
||||
type SuccessHelper struct{}
|
||||
|
||||
func (s *SuccessHelper) TestLogAndSucceed(c *check.C) {
|
||||
c.Log("Expected success!")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper suite for testing ordering and behavior of fixture.
|
||||
|
||||
type FixtureHelper struct {
|
||||
calls []string
|
||||
panicOn string
|
||||
skip bool
|
||||
skipOnN int
|
||||
sleepOn string
|
||||
sleep time.Duration
|
||||
bytes int64
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) trace(name string, c *check.C) {
|
||||
s.calls = append(s.calls, name)
|
||||
if name == s.panicOn {
|
||||
panic(name)
|
||||
}
|
||||
if s.sleep > 0 && s.sleepOn == name {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
if s.skip && s.skipOnN == len(s.calls)-1 {
|
||||
c.Skip("skipOnN == n")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) SetUpSuite(c *check.C) {
|
||||
s.trace("SetUpSuite", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) TearDownSuite(c *check.C) {
|
||||
s.trace("TearDownSuite", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) SetUpTest(c *check.C) {
|
||||
s.trace("SetUpTest", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) TearDownTest(c *check.C) {
|
||||
s.trace("TearDownTest", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Test1(c *check.C) {
|
||||
s.trace("Test1", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Test2(c *check.C) {
|
||||
s.trace("Test2", c)
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark1(c *check.C) {
|
||||
s.trace("Benchmark1", c)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark2(c *check.C) {
|
||||
s.trace("Benchmark2", c)
|
||||
c.SetBytes(1024)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FixtureHelper) Benchmark3(c *check.C) {
|
||||
var x []int64
|
||||
s.trace("Benchmark3", c)
|
||||
for i := 0; i < c.N; i++ {
|
||||
time.Sleep(s.sleep)
|
||||
x = make([]int64, 5)
|
||||
_ = x
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper which checks the state of the test and ensures that it matches
|
||||
// the given expectations. Depends on c.Errorf() working, so shouldn't
|
||||
// be used to test this one function.
|
||||
|
||||
type expectedState struct {
|
||||
name string
|
||||
result interface{}
|
||||
failed bool
|
||||
log string
|
||||
}
|
||||
|
||||
// Verify the state of the test. Note that since this also verifies if
|
||||
// the test is supposed to be in a failed state, no other checks should
|
||||
// be done in addition to what is being tested.
|
||||
func checkState(c *check.C, result interface{}, expected *expectedState) {
|
||||
failed := c.Failed()
|
||||
c.Succeed()
|
||||
log := c.GetTestLog()
|
||||
matched, matchError := regexp.MatchString("^"+expected.log+"$", log)
|
||||
if matchError != nil {
|
||||
c.Errorf("Error in matching expression used in testing %s",
|
||||
expected.name)
|
||||
} else if !matched {
|
||||
c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------",
|
||||
expected.name, log, expected.log)
|
||||
}
|
||||
if result != expected.result {
|
||||
c.Errorf("%s returned %#v rather than %#v",
|
||||
expected.name, result, expected.result)
|
||||
}
|
||||
if failed != expected.failed {
|
||||
if failed {
|
||||
c.Errorf("%s has failed when it shouldn't", expected.name)
|
||||
} else {
|
||||
c.Errorf("%s has not failed when it should", expected.name)
|
||||
}
|
||||
}
|
||||
}
|
272
Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go
generated
vendored
272
Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go
generated
vendored
@ -1,272 +0,0 @@
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gopkg.in/check.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type CheckersS struct{}
|
||||
|
||||
var _ = check.Suite(&CheckersS{})
|
||||
|
||||
func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) {
|
||||
info := checker.Info()
|
||||
if info.Name != name {
|
||||
c.Fatalf("Got name %s, expected %s", info.Name, name)
|
||||
}
|
||||
if !reflect.DeepEqual(info.Params, paramNames) {
|
||||
c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) {
|
||||
info := checker.Info()
|
||||
if len(params) != len(info.Params) {
|
||||
c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params))
|
||||
}
|
||||
names := append([]string{}, info.Params...)
|
||||
result_, error_ := checker.Check(params, names)
|
||||
if result_ != result || error_ != error {
|
||||
c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)",
|
||||
info.Name, params, result_, error_, result, error)
|
||||
}
|
||||
return params, names
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestComment(c *check.C) {
|
||||
bug := check.Commentf("a %d bc", 42)
|
||||
comment := bug.CheckCommentString()
|
||||
if comment != "a 42 bc" {
|
||||
c.Fatalf("Commentf returned %#v", comment)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestIsNil(c *check.C) {
|
||||
testInfo(c, check.IsNil, "IsNil", []string{"value"})
|
||||
|
||||
testCheck(c, check.IsNil, true, "", nil)
|
||||
testCheck(c, check.IsNil, false, "", "a")
|
||||
|
||||
testCheck(c, check.IsNil, true, "", (chan int)(nil))
|
||||
testCheck(c, check.IsNil, false, "", make(chan int))
|
||||
testCheck(c, check.IsNil, true, "", (error)(nil))
|
||||
testCheck(c, check.IsNil, false, "", errors.New(""))
|
||||
testCheck(c, check.IsNil, true, "", ([]int)(nil))
|
||||
testCheck(c, check.IsNil, false, "", make([]int, 1))
|
||||
testCheck(c, check.IsNil, false, "", int(0))
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestNotNil(c *check.C) {
|
||||
testInfo(c, check.NotNil, "NotNil", []string{"value"})
|
||||
|
||||
testCheck(c, check.NotNil, false, "", nil)
|
||||
testCheck(c, check.NotNil, true, "", "a")
|
||||
|
||||
testCheck(c, check.NotNil, false, "", (chan int)(nil))
|
||||
testCheck(c, check.NotNil, true, "", make(chan int))
|
||||
testCheck(c, check.NotNil, false, "", (error)(nil))
|
||||
testCheck(c, check.NotNil, true, "", errors.New(""))
|
||||
testCheck(c, check.NotNil, false, "", ([]int)(nil))
|
||||
testCheck(c, check.NotNil, true, "", make([]int, 1))
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestNot(c *check.C) {
|
||||
testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"})
|
||||
|
||||
testCheck(c, check.Not(check.IsNil), false, "", nil)
|
||||
testCheck(c, check.Not(check.IsNil), true, "", "a")
|
||||
}
|
||||
|
||||
type simpleStruct struct {
|
||||
i int
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestEquals(c *check.C) {
|
||||
testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"})
|
||||
|
||||
// The simplest.
|
||||
testCheck(c, check.Equals, true, "", 42, 42)
|
||||
testCheck(c, check.Equals, false, "", 42, 43)
|
||||
|
||||
// Different native types.
|
||||
testCheck(c, check.Equals, false, "", int32(42), int64(42))
|
||||
|
||||
// With nil.
|
||||
testCheck(c, check.Equals, false, "", 42, nil)
|
||||
|
||||
// Slices
|
||||
testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2})
|
||||
|
||||
// Struct values
|
||||
testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1})
|
||||
testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2})
|
||||
|
||||
// Struct pointers
|
||||
testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1})
|
||||
testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2})
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestDeepEquals(c *check.C) {
|
||||
testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"})
|
||||
|
||||
// The simplest.
|
||||
testCheck(c, check.DeepEquals, true, "", 42, 42)
|
||||
testCheck(c, check.DeepEquals, false, "", 42, 43)
|
||||
|
||||
// Different native types.
|
||||
testCheck(c, check.DeepEquals, false, "", int32(42), int64(42))
|
||||
|
||||
// With nil.
|
||||
testCheck(c, check.DeepEquals, false, "", 42, nil)
|
||||
|
||||
// Slices
|
||||
testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2})
|
||||
testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3})
|
||||
|
||||
// Struct values
|
||||
testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1})
|
||||
testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2})
|
||||
|
||||
// Struct pointers
|
||||
testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1})
|
||||
testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2})
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestHasLen(c *check.C) {
|
||||
testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"})
|
||||
|
||||
testCheck(c, check.HasLen, true, "", "abcd", 4)
|
||||
testCheck(c, check.HasLen, true, "", []int{1, 2}, 2)
|
||||
testCheck(c, check.HasLen, false, "", []int{1, 2}, 3)
|
||||
|
||||
testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2")
|
||||
testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2)
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestErrorMatches(c *check.C) {
|
||||
testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"})
|
||||
|
||||
testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error")
|
||||
testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error")
|
||||
testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error")
|
||||
testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or")
|
||||
|
||||
// Verify params mutation
|
||||
params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error")
|
||||
c.Assert(params[0], check.Equals, "some error")
|
||||
c.Assert(names[0], check.Equals, "error")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestMatches(c *check.C) {
|
||||
testInfo(c, check.Matches, "Matches", []string{"value", "regex"})
|
||||
|
||||
// Simple matching
|
||||
testCheck(c, check.Matches, true, "", "abc", "abc")
|
||||
testCheck(c, check.Matches, true, "", "abc", "a.c")
|
||||
|
||||
// Must match fully
|
||||
testCheck(c, check.Matches, false, "", "abc", "ab")
|
||||
testCheck(c, check.Matches, false, "", "abc", "bc")
|
||||
|
||||
// String()-enabled values accepted
|
||||
testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c")
|
||||
testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d")
|
||||
|
||||
// Some error conditions.
|
||||
testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c")
|
||||
testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestPanics(c *check.C) {
|
||||
testInfo(c, check.Panics, "Panics", []string{"function", "expected"})
|
||||
|
||||
// Some errors.
|
||||
testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM")
|
||||
testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM")
|
||||
|
||||
// Plain strings.
|
||||
testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM")
|
||||
testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM")
|
||||
testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM")
|
||||
|
||||
// Error values.
|
||||
testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM"))
|
||||
testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
|
||||
|
||||
type deep struct{ i int }
|
||||
// Deep value
|
||||
testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99})
|
||||
|
||||
// Verify params/names mutation
|
||||
params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
|
||||
c.Assert(params[0], check.ErrorMatches, "KABOOM")
|
||||
c.Assert(names[0], check.Equals, "panic")
|
||||
|
||||
// Verify a nil panic
|
||||
testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil)
|
||||
testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestPanicMatches(c *check.C) {
|
||||
testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"})
|
||||
|
||||
// Error matching.
|
||||
testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M")
|
||||
testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M")
|
||||
|
||||
// Some errors.
|
||||
testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM")
|
||||
testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM")
|
||||
|
||||
// Plain strings.
|
||||
testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M")
|
||||
testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM")
|
||||
testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M")
|
||||
|
||||
// Verify params/names mutation
|
||||
params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM")
|
||||
c.Assert(params[0], check.Equals, "KABOOM")
|
||||
c.Assert(names[0], check.Equals, "panic")
|
||||
|
||||
// Verify a nil panic
|
||||
testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "")
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestFitsTypeOf(c *check.C) {
|
||||
testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"})
|
||||
|
||||
// Basic types
|
||||
testCheck(c, check.FitsTypeOf, true, "", 1, 0)
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, int64(0))
|
||||
|
||||
// Aliases
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, errors.New(""))
|
||||
testCheck(c, check.FitsTypeOf, false, "", "error", errors.New(""))
|
||||
testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New(""))
|
||||
|
||||
// Structures
|
||||
testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{})
|
||||
testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{})
|
||||
|
||||
// Some bad values
|
||||
testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil))
|
||||
testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0)
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestImplements(c *check.C) {
|
||||
testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"})
|
||||
|
||||
var e error
|
||||
var re runtime.Error
|
||||
testCheck(c, check.Implements, true, "", errors.New(""), &e)
|
||||
testCheck(c, check.Implements, false, "", errors.New(""), &re)
|
||||
|
||||
// Some bad values
|
||||
testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New(""))
|
||||
testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil))
|
||||
testCheck(c, check.Implements, false, "", interface{}(nil), &e)
|
||||
}
|
9
Godeps/_workspace/src/gopkg.in/check.v1/export_test.go
generated
vendored
9
Godeps/_workspace/src/gopkg.in/check.v1/export_test.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
package check
|
||||
|
||||
func PrintLine(filename string, line int) (string, error) {
|
||||
return printLine(filename, line)
|
||||
}
|
||||
|
||||
func Indent(s, with string) string {
|
||||
return indent(s, with)
|
||||
}
|
484
Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go
generated
vendored
484
Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go
generated
vendored
@ -1,484 +0,0 @@
|
||||
// Tests for the behavior of the test fixture system.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Fixture test suite.
|
||||
|
||||
type FixtureS struct{}
|
||||
|
||||
var fixtureS = Suite(&FixtureS{})
|
||||
|
||||
func (s *FixtureS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Basic fixture ordering verification.
|
||||
|
||||
func (s *FixtureS) TestOrder(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
Run(&helper, nil)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check the behavior when panics occur within tests and fixtures.
|
||||
|
||||
func (s *FixtureS) TestPanicOnTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "Test1"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.Test1\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnSetUpTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "SetUpTest"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 4)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.SetUpTest\n" +
|
||||
"(.|\n)*" +
|
||||
"\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Fixture has panicked " +
|
||||
"\\(see related PANIC\\)\n$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnTearDownTest(c *C) {
|
||||
helper := FixtureHelper{panicOn: "TearDownTest"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.TearDownTest\n\n" +
|
||||
"\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.TearDownTest\n" +
|
||||
"(.|\n)*" +
|
||||
"\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: Fixture has panicked " +
|
||||
"\\(see related PANIC\\)\n$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnSetUpSuite(c *C) {
|
||||
helper := FixtureHelper{panicOn: "SetUpSuite"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 2)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.SetUpSuite\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnTearDownSuite(c *C) {
|
||||
helper := FixtureHelper{panicOn: "TearDownSuite"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: check_test\\.go:[0-9]+: " +
|
||||
"FixtureHelper.TearDownSuite\n\n" +
|
||||
"\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" +
|
||||
".+:[0-9]+\n" +
|
||||
" in (go)?panic\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.trace\n" +
|
||||
".*check_test.go:[0-9]+\n" +
|
||||
" in FixtureHelper.TearDownSuite\n" +
|
||||
"(.|\n)*$"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// A wrong argument on a test or fixture will produce a nice error.
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongTestArg(c *C) {
|
||||
helper := WrongTestArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[4], Equals, "Test2")
|
||||
c.Check(helper.calls[5], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[6], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 7)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongTestArgHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) {
|
||||
helper := WrongSetUpTestArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpTestArgHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) {
|
||||
helper := WrongSetUpSuiteArgHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Nice errors also when tests or fixture have wrong arg count.
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) {
|
||||
helper := WrongTestArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[3], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[4], Equals, "Test2")
|
||||
c.Check(helper.calls[5], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[6], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 7)
|
||||
|
||||
expected := "^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongTestArgCountHelper\\.Test1\n\n" +
|
||||
"\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) {
|
||||
helper := WrongSetUpTestArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " +
|
||||
"should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) {
|
||||
helper := WrongSetUpSuiteArgCountHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
|
||||
expected :=
|
||||
"^\n-+\n" +
|
||||
"PANIC: fixture_test\\.go:[0-9]+: " +
|
||||
"WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" +
|
||||
"\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" +
|
||||
"\\.SetUpSuite argument should be \\*check\\.C\n"
|
||||
|
||||
c.Check(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helper test suites with wrong function arguments.
|
||||
|
||||
type WrongTestArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongTestArgHelper) Test1(t int) {
|
||||
}
|
||||
|
||||
type WrongSetUpTestArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpTestArgHelper) SetUpTest(t int) {
|
||||
}
|
||||
|
||||
type WrongSetUpSuiteArgHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) {
|
||||
}
|
||||
|
||||
type WrongTestArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongTestArgCountHelper) Test1(c *C, i int) {
|
||||
}
|
||||
|
||||
type WrongSetUpTestArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) {
|
||||
}
|
||||
|
||||
type WrongSetUpSuiteArgCountHelper struct {
|
||||
FixtureHelper
|
||||
}
|
||||
|
||||
func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure fixture doesn't run without tests.
|
||||
|
||||
type NoTestsHelper struct {
|
||||
hasRun bool
|
||||
}
|
||||
|
||||
func (s *NoTestsHelper) SetUpSuite(c *C) {
|
||||
s.hasRun = true
|
||||
}
|
||||
|
||||
func (s *NoTestsHelper) TearDownSuite(c *C) {
|
||||
s.hasRun = true
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) {
|
||||
helper := NoTestsHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Check(helper.hasRun, Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that checks and assertions work correctly inside the fixture.
|
||||
|
||||
type FixtureCheckHelper struct {
|
||||
fail string
|
||||
completed bool
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) SetUpSuite(c *C) {
|
||||
switch s.fail {
|
||||
case "SetUpSuiteAssert":
|
||||
c.Assert(false, Equals, true)
|
||||
case "SetUpSuiteCheck":
|
||||
c.Check(false, Equals, true)
|
||||
}
|
||||
s.completed = true
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) SetUpTest(c *C) {
|
||||
switch s.fail {
|
||||
case "SetUpTestAssert":
|
||||
c.Assert(false, Equals, true)
|
||||
case "SetUpTestCheck":
|
||||
c.Check(false, Equals, true)
|
||||
}
|
||||
s.completed = true
|
||||
}
|
||||
|
||||
func (s *FixtureCheckHelper) Test(c *C) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSetUpSuiteCheck(c *C) {
|
||||
helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureCheckHelper\\.SetUpSuite\n\n"+
|
||||
"fixture_test\\.go:[0-9]+:\n"+
|
||||
" c\\.Check\\(false, Equals, true\\)\n"+
|
||||
"\\.+ obtained bool = false\n"+
|
||||
"\\.+ expected bool = true\n\n")
|
||||
c.Assert(helper.completed, Equals, true)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSetUpSuiteAssert(c *C) {
|
||||
helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureCheckHelper\\.SetUpSuite\n\n"+
|
||||
"fixture_test\\.go:[0-9]+:\n"+
|
||||
" c\\.Assert\\(false, Equals, true\\)\n"+
|
||||
"\\.+ obtained bool = false\n"+
|
||||
"\\.+ expected bool = true\n\n")
|
||||
c.Assert(helper.completed, Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that logging within SetUpTest() persists within the test log itself.
|
||||
|
||||
type FixtureLogHelper struct {
|
||||
c *C
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) SetUpTest(c *C) {
|
||||
s.c = c
|
||||
c.Log("1")
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) Test(c *C) {
|
||||
c.Log("2")
|
||||
s.c.Log("3")
|
||||
c.Log("4")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
func (s *FixtureLogHelper) TearDownTest(c *C) {
|
||||
s.c.Log("5")
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestFixtureLogging(c *C) {
|
||||
helper := FixtureLogHelper{}
|
||||
output := String{}
|
||||
Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Matches,
|
||||
"\n---+\n"+
|
||||
"FAIL: fixture_test\\.go:[0-9]+: "+
|
||||
"FixtureLogHelper\\.Test\n\n"+
|
||||
"1\n2\n3\n4\n5\n")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Skip() within fixture methods.
|
||||
|
||||
func (s *FixtureS) TestSkipSuite(c *C) {
|
||||
helper := FixtureHelper{skip: true, skipOnN: 0}
|
||||
output := String{}
|
||||
result := Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(output.value, Equals, "")
|
||||
c.Assert(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Assert(helper.calls[1], Equals, "TearDownSuite")
|
||||
c.Assert(len(helper.calls), Equals, 2)
|
||||
c.Assert(result.Skipped, Equals, 2)
|
||||
}
|
||||
|
||||
func (s *FixtureS) TestSkipTest(c *C) {
|
||||
helper := FixtureHelper{skip: true, skipOnN: 1}
|
||||
output := String{}
|
||||
result := Run(&helper, &RunConf{Output: &output})
|
||||
c.Assert(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Assert(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Assert(helper.calls[2], Equals, "SetUpTest")
|
||||
c.Assert(helper.calls[3], Equals, "Test2")
|
||||
c.Assert(helper.calls[4], Equals, "TearDownTest")
|
||||
c.Assert(helper.calls[5], Equals, "TearDownSuite")
|
||||
c.Assert(len(helper.calls), Equals, 6)
|
||||
c.Assert(result.Skipped, Equals, 1)
|
||||
}
|
335
Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go
generated
vendored
335
Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go
generated
vendored
@ -1,335 +0,0 @@
|
||||
// These tests check that the foundations of gocheck are working properly.
|
||||
// They already assume that fundamental failing is working already, though,
|
||||
// since this was tested in bootstrap_test.go. Even then, some care may
|
||||
// still have to be taken when using external functions, since they should
|
||||
// of course not rely on functionality tested here.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/check.v1"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Foundation test suite.
|
||||
|
||||
type FoundationS struct{}
|
||||
|
||||
var foundationS = check.Suite(&FoundationS{})
|
||||
|
||||
func (s *FoundationS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestErrorf(c *check.C) {
|
||||
// Do not use checkState() here. It depends on Errorf() working.
|
||||
expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Errorf(\"Error %%v!\", \"message\")\n"+
|
||||
"... Error: Error message!\n\n",
|
||||
getMyLine()+1)
|
||||
c.Errorf("Error %v!", "message")
|
||||
failed := c.Failed()
|
||||
c.Succeed()
|
||||
if log := c.GetTestLog(); log != expectedLog {
|
||||
c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog)
|
||||
c.Fail()
|
||||
}
|
||||
if !failed {
|
||||
c.Logf("Errorf() didn't put the test in a failed state")
|
||||
c.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestError(c *check.C) {
|
||||
expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c\\.Error\\(\"Error \", \"message!\"\\)\n"+
|
||||
"\\.\\.\\. Error: Error message!\n\n",
|
||||
getMyLine()+1)
|
||||
c.Error("Error ", "message!")
|
||||
checkState(c, nil,
|
||||
&expectedState{
|
||||
name: "Error(`Error `, `message!`)",
|
||||
failed: true,
|
||||
log: expectedLog,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFailNow(c *check.C) {
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("FailNow() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
if c.GetTestLog() != "" {
|
||||
c.Error("Something got logged:\n" + c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
c.FailNow()
|
||||
c.Log("FailNow() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSucceedNow(c *check.C) {
|
||||
defer (func() {
|
||||
if c.Failed() {
|
||||
c.Error("SucceedNow() didn't succeed the test")
|
||||
}
|
||||
if c.GetTestLog() != "" {
|
||||
c.Error("Something got logged:\n" + c.GetTestLog())
|
||||
}
|
||||
})()
|
||||
|
||||
c.Fail()
|
||||
c.SucceedNow()
|
||||
c.Log("SucceedNow() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFailureHeader(c *check.C) {
|
||||
output := String{}
|
||||
failHelper := FailHelper{}
|
||||
check.Run(&failHelper, &check.RunConf{Output: &output})
|
||||
header := fmt.Sprintf(""+
|
||||
"\n-----------------------------------"+
|
||||
"-----------------------------------\n"+
|
||||
"FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n",
|
||||
failHelper.testLine)
|
||||
if strings.Index(output.value, header) == -1 {
|
||||
c.Errorf(""+
|
||||
"Failure didn't print a proper header.\n"+
|
||||
"... Got:\n%s... Expected something with:\n%s",
|
||||
output.value, header)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFatal(c *check.C) {
|
||||
var line int
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("Fatal() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
expected := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Fatal(\"Die \", \"now!\")\n"+
|
||||
"... Error: Die now!\n\n",
|
||||
line)
|
||||
if c.GetTestLog() != expected {
|
||||
c.Error("Incorrect log:", c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
line = getMyLine() + 1
|
||||
c.Fatal("Die ", "now!")
|
||||
c.Log("Fatal() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestFatalf(c *check.C) {
|
||||
var line int
|
||||
defer (func() {
|
||||
if !c.Failed() {
|
||||
c.Error("Fatalf() didn't fail the test")
|
||||
} else {
|
||||
c.Succeed()
|
||||
expected := fmt.Sprintf("foundation_test.go:%d:\n"+
|
||||
" c.Fatalf(\"Die %%s!\", \"now\")\n"+
|
||||
"... Error: Die now!\n\n",
|
||||
line)
|
||||
if c.GetTestLog() != expected {
|
||||
c.Error("Incorrect log:", c.GetTestLog())
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
line = getMyLine() + 1
|
||||
c.Fatalf("Die %s!", "now")
|
||||
c.Log("Fatalf() didn't stop the test")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) {
|
||||
log := fmt.Sprintf(""+
|
||||
"foundation_test.go:%d:\n"+
|
||||
" result := c.Check\\(10, check.Equals, 20\\)\n"+
|
||||
"\\.\\.\\. obtained int = 10\n"+
|
||||
"\\.\\.\\. expected int = 20\n\n",
|
||||
getMyLine()+1)
|
||||
result := c.Check(10, check.Equals, 20)
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: "Check(10, Equals, 20)",
|
||||
result: false,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) {
|
||||
result, line := checkEqualWrapper(c, 10, 20)
|
||||
testLine := getMyLine() - 1
|
||||
log := fmt.Sprintf(""+
|
||||
"foundation_test.go:%d:\n"+
|
||||
" result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+
|
||||
"check_test.go:%d:\n"+
|
||||
" return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+
|
||||
"\\.\\.\\. obtained int = 10\n"+
|
||||
"\\.\\.\\. expected int = 20\n\n",
|
||||
testLine, line)
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: "Check(10, Equals, 20)",
|
||||
result: false,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// ExpectFailure() inverts the logic of failure.
|
||||
|
||||
type ExpectFailureSucceedHelper struct{}
|
||||
|
||||
func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) {
|
||||
c.ExpectFailure("It booms!")
|
||||
c.Error("Boom!")
|
||||
}
|
||||
|
||||
type ExpectFailureFailHelper struct{}
|
||||
|
||||
func (s *ExpectFailureFailHelper) TestFail(c *check.C) {
|
||||
c.ExpectFailure("Bug #XYZ")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureFail(c *check.C) {
|
||||
helper := ExpectFailureFailHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
expected := "" +
|
||||
"^\n-+\n" +
|
||||
"FAIL: foundation_test\\.go:[0-9]+:" +
|
||||
" ExpectFailureFailHelper\\.TestFail\n\n" +
|
||||
"\\.\\.\\. Error: Test succeeded, but was expected to fail\n" +
|
||||
"\\.\\.\\. Reason: Bug #XYZ\n$"
|
||||
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("ExpectFailure() didn't log properly:\n", output.value)
|
||||
}
|
||||
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 0)
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureSucceed(c *check.C) {
|
||||
helper := ExpectFailureSucceedHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
c.Assert(output.value, check.Equals, "")
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) {
|
||||
helper := ExpectFailureSucceedHelper{}
|
||||
output := String{}
|
||||
result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
|
||||
|
||||
expected := "" +
|
||||
"FAIL EXPECTED: foundation_test\\.go:[0-9]+:" +
|
||||
" ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n"
|
||||
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("ExpectFailure() didn't log properly:\n", output.value)
|
||||
}
|
||||
|
||||
c.Assert(result.ExpectedFailures, check.Equals, 1)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Skip() allows stopping a test without positive/negative results.
|
||||
|
||||
type SkipTestHelper struct{}
|
||||
|
||||
func (s *SkipTestHelper) TestFail(c *check.C) {
|
||||
c.Skip("Wrong platform or whatever")
|
||||
c.Error("Boom!")
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSkip(c *check.C) {
|
||||
helper := SkipTestHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
|
||||
if output.value != "" {
|
||||
c.Error("Skip() logged something:\n", output.value)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FoundationS) TestSkipVerbose(c *check.C) {
|
||||
helper := SkipTestHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
|
||||
|
||||
expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" +
|
||||
" \\(Wrong platform or whatever\\)"
|
||||
matched, err := regexp.MatchString(expected, output.value)
|
||||
if err != nil {
|
||||
c.Error("Bad expression: ", expected)
|
||||
} else if !matched {
|
||||
c.Error("Skip() didn't log properly:\n", output.value)
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check minimum *log.Logger interface provided by *check.C.
|
||||
|
||||
type minLogger interface {
|
||||
Output(calldepth int, s string) error
|
||||
}
|
||||
|
||||
func (s *BootstrapS) TestMinLogger(c *check.C) {
|
||||
var logger minLogger
|
||||
logger = log.New(os.Stderr, "", 0)
|
||||
logger = c
|
||||
logger.Output(0, "Hello there")
|
||||
expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n`
|
||||
output := c.GetTestLog()
|
||||
c.Assert(output, check.Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure that suites with embedded types are working fine, including the
|
||||
// the workaround for issue 906.
|
||||
|
||||
type EmbeddedInternalS struct {
|
||||
called bool
|
||||
}
|
||||
|
||||
type EmbeddedS struct {
|
||||
EmbeddedInternalS
|
||||
}
|
||||
|
||||
var embeddedS = check.Suite(&EmbeddedS{})
|
||||
|
||||
func (s *EmbeddedS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
func (s *EmbeddedInternalS) TestMethod(c *check.C) {
|
||||
c.Error("TestMethod() of the embedded type was called!?")
|
||||
}
|
||||
|
||||
func (s *EmbeddedS) TestMethod(c *check.C) {
|
||||
// http://code.google.com/p/go/issues/detail?id=906
|
||||
c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner?
|
||||
s.called = true
|
||||
}
|
519
Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go
generated
vendored
519
Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go
generated
vendored
@ -1,519 +0,0 @@
|
||||
// These tests verify the inner workings of the helper methods associated
|
||||
// with check.T.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"gopkg.in/check.v1"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var helpersS = check.Suite(&HelpersS{})
|
||||
|
||||
type HelpersS struct{}
|
||||
|
||||
func (s *HelpersS) TestCountSuite(c *check.C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Fake checker and bug info to verify the behavior of Assert() and Check().
|
||||
|
||||
type MyChecker struct {
|
||||
info *check.CheckerInfo
|
||||
params []interface{}
|
||||
names []string
|
||||
result bool
|
||||
error string
|
||||
}
|
||||
|
||||
func (checker *MyChecker) Info() *check.CheckerInfo {
|
||||
if checker.info == nil {
|
||||
return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}}
|
||||
}
|
||||
return checker.info
|
||||
}
|
||||
|
||||
func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
rparams := checker.params
|
||||
rnames := checker.names
|
||||
checker.params = append([]interface{}{}, params...)
|
||||
checker.names = append([]string{}, names...)
|
||||
if rparams != nil {
|
||||
copy(params, rparams)
|
||||
}
|
||||
if rnames != nil {
|
||||
copy(names, rnames)
|
||||
}
|
||||
return checker.result, checker.error
|
||||
}
|
||||
|
||||
type myCommentType string
|
||||
|
||||
func (c myCommentType) CheckCommentString() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func myComment(s string) myCommentType {
|
||||
return myCommentType(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure a real checker actually works fine.
|
||||
|
||||
func (s *HelpersS) TestCheckerInterface(c *check.C) {
|
||||
testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} {
|
||||
return c.Check(1, check.Equals, 1)
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests for Check(), mostly the same as for Assert() following these.
|
||||
|
||||
func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
testHelperSuccess(c, "Check(1, checker)", true, func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2, myComment("Hello world!"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" // Nice leading comment\\.\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\) // Hello there\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
// Nice leading comment.
|
||||
return c.Check(1, checker, 2) // Hello there
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker\\)\n" +
|
||||
"\\.+ myvalue int = 1\n\n"
|
||||
testHelperFailure(c, "Check(1, checker)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myvalue int = 1\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, msg)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, myComment("Hello world!"))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker\\)\n" +
|
||||
"\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 2\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, !?)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2, 3\\)\n" +
|
||||
"\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 4\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithError(c *check.C) {
|
||||
checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Some not so cool data provided!\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithNilChecker(c *check.C) {
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, nil\\)\n" +
|
||||
"\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
|
||||
"\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
|
||||
testHelperFailure(c, "Check(obtained, nil)", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) {
|
||||
checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(1, checker, 2\\)\n" +
|
||||
"\\.+ newobtained int = 3\n" +
|
||||
"\\.+ newexpected int = 4\n\n"
|
||||
testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check(1, checker, 2)
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests for Assert(), mostly the same as for Check() above.
|
||||
|
||||
func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
if !reflect.DeepEqual(checker.params, []interface{}{1}) {
|
||||
c.Fatalf("Bad params for check: %#v", checker.params)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2, myComment("Hello world!"))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker\\)\n" +
|
||||
"\\.+ myvalue int = 1\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) {
|
||||
checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
|
||||
"\\.+ myvalue int = 1\n" +
|
||||
"\\.+ Hello world!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, myComment("Hello world!"))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) {
|
||||
checker := &MyChecker{result: true}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker\\)\n" +
|
||||
"\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" +
|
||||
"\\.+ Wrong number of parameters for MyChecker: " +
|
||||
"want 3, got 2\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithError(c *check.C) {
|
||||
checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, checker, 2\\)\n" +
|
||||
"\\.+ myobtained int = 1\n" +
|
||||
"\\.+ myexpected int = 2\n" +
|
||||
"\\.+ Some not so cool data provided!\n\n"
|
||||
testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, checker, 2)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestAssertWithNilChecker(c *check.C) {
|
||||
log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
|
||||
" c\\.Assert\\(1, nil\\)\n" +
|
||||
"\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
|
||||
"\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
|
||||
testHelperFailure(c, "Assert(obtained, nil)", nil, true, log,
|
||||
func() interface{} {
|
||||
c.Assert(1, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Ensure that values logged work properly in some interesting cases.
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" +
|
||||
"\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" +
|
||||
"\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n"
|
||||
testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check([]byte{1, 2}, checker, []byte{1, 3})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) {
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" +
|
||||
"\\.+ myobtained string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\\\\n\"\n" +
|
||||
"\\.+ myexpected string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\\\\n\" \\+\n" +
|
||||
"\\.+ \"c\"\n\n"
|
||||
testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check("a\nb\n", checker, "a\nb\nc")
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) {
|
||||
// If the newline is at the end of the string, don't log as multi-line.
|
||||
checker := &MyChecker{result: false}
|
||||
log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
|
||||
" return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" +
|
||||
"\\.+ myobtained string = \"a b\\\\n\"\n" +
|
||||
"\\.+ myexpected string = \"\" \\+\n" +
|
||||
"\\.+ \"a\\\\n\" \\+\n" +
|
||||
"\\.+ \"b\"\n\n"
|
||||
testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log,
|
||||
func() interface{} {
|
||||
return c.Check("a b\n", checker, "a\nb")
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// MakeDir() tests.
|
||||
|
||||
type MkDirHelper struct {
|
||||
path1 string
|
||||
path2 string
|
||||
isDir1 bool
|
||||
isDir2 bool
|
||||
isDir3 bool
|
||||
isDir4 bool
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) SetUpSuite(c *check.C) {
|
||||
s.path1 = c.MkDir()
|
||||
s.isDir1 = isDir(s.path1)
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) Test(c *check.C) {
|
||||
s.path2 = c.MkDir()
|
||||
s.isDir2 = isDir(s.path2)
|
||||
}
|
||||
|
||||
func (s *MkDirHelper) TearDownSuite(c *check.C) {
|
||||
s.isDir3 = isDir(s.path1)
|
||||
s.isDir4 = isDir(s.path2)
|
||||
}
|
||||
|
||||
func (s *HelpersS) TestMkDir(c *check.C) {
|
||||
helper := MkDirHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
c.Assert(output.value, check.Equals, "")
|
||||
c.Check(helper.isDir1, check.Equals, true)
|
||||
c.Check(helper.isDir2, check.Equals, true)
|
||||
c.Check(helper.isDir3, check.Equals, true)
|
||||
c.Check(helper.isDir4, check.Equals, true)
|
||||
c.Check(helper.path1, check.Not(check.Equals),
|
||||
helper.path2)
|
||||
c.Check(isDir(helper.path1), check.Equals, false)
|
||||
c.Check(isDir(helper.path2), check.Equals, false)
|
||||
}
|
||||
|
||||
func isDir(path string) bool {
|
||||
if stat, err := os.Stat(path); err == nil {
|
||||
return stat.IsDir()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Concurrent logging should not corrupt the underling buffer.
|
||||
// Use go test -race to detect the race in this test.
|
||||
func (s *HelpersS) TestConcurrentLogging(c *check.C) {
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU()))
|
||||
var start, stop sync.WaitGroup
|
||||
start.Add(1)
|
||||
for i, n := 0, runtime.NumCPU()*2; i < n; i++ {
|
||||
stop.Add(1)
|
||||
go func(i int) {
|
||||
start.Wait()
|
||||
for j := 0; j < 30; j++ {
|
||||
c.Logf("Worker %d: line %d", i, j)
|
||||
}
|
||||
stop.Done()
|
||||
}(i)
|
||||
}
|
||||
start.Done()
|
||||
stop.Wait()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test the TestName function
|
||||
|
||||
type TestNameHelper struct {
|
||||
name1 string
|
||||
name2 string
|
||||
name3 string
|
||||
name4 string
|
||||
name5 string
|
||||
}
|
||||
|
||||
func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() }
|
||||
func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() }
|
||||
func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() }
|
||||
func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() }
|
||||
func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() }
|
||||
|
||||
func (s *HelpersS) TestTestName(c *check.C) {
|
||||
helper := TestNameHelper{}
|
||||
output := String{}
|
||||
check.Run(&helper, &check.RunConf{Output: &output})
|
||||
c.Check(helper.name1, check.Equals, "")
|
||||
c.Check(helper.name2, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name3, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name4, check.Equals, "TestNameHelper.Test")
|
||||
c.Check(helper.name5, check.Equals, "")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// A couple of helper functions to test helper functions. :-)
|
||||
|
||||
func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) {
|
||||
var result interface{}
|
||||
defer (func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: name,
|
||||
result: expectedResult,
|
||||
failed: false,
|
||||
log: "",
|
||||
})
|
||||
})()
|
||||
result = closure()
|
||||
}
|
||||
|
||||
func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) {
|
||||
var result interface{}
|
||||
defer (func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
checkState(c, result,
|
||||
&expectedState{
|
||||
name: name,
|
||||
result: expectedResult,
|
||||
failed: true,
|
||||
log: log,
|
||||
})
|
||||
})()
|
||||
result = closure()
|
||||
if shouldStop {
|
||||
c.Logf("%s didn't stop when it should", name)
|
||||
}
|
||||
}
|
104
Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go
generated
vendored
104
Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
package check_test
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var _ = Suite(&PrinterS{})
|
||||
|
||||
type PrinterS struct{}
|
||||
|
||||
func (s *PrinterS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
var printTestFuncLine int
|
||||
|
||||
func init() {
|
||||
printTestFuncLine = getMyLine() + 3
|
||||
}
|
||||
|
||||
func printTestFunc() {
|
||||
println(1) // Comment1
|
||||
if 2 == 2 { // Comment2
|
||||
println(3) // Comment3
|
||||
}
|
||||
switch 5 {
|
||||
case 6: println(6) // Comment6
|
||||
println(7)
|
||||
}
|
||||
switch interface{}(9).(type) {// Comment9
|
||||
case int: println(10)
|
||||
println(11)
|
||||
}
|
||||
select {
|
||||
case <-(chan bool)(nil): println(14)
|
||||
println(15)
|
||||
default: println(16)
|
||||
println(17)
|
||||
}
|
||||
println(19,
|
||||
20)
|
||||
_ = func() { println(21)
|
||||
println(22)
|
||||
}
|
||||
println(24, func() {
|
||||
println(25)
|
||||
})
|
||||
// Leading comment
|
||||
// with multiple lines.
|
||||
println(29) // Comment29
|
||||
}
|
||||
|
||||
var printLineTests = []struct {
|
||||
line int
|
||||
output string
|
||||
}{
|
||||
{1, "println(1) // Comment1"},
|
||||
{2, "if 2 == 2 { // Comment2\n ...\n}"},
|
||||
{3, "println(3) // Comment3"},
|
||||
{5, "switch 5 {\n...\n}"},
|
||||
{6, "case 6:\n println(6) // Comment6\n ..."},
|
||||
{7, "println(7)"},
|
||||
{9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
|
||||
{10, "case int:\n println(10)\n ..."},
|
||||
{14, "case <-(chan bool)(nil):\n println(14)\n ..."},
|
||||
{15, "println(15)"},
|
||||
{16, "default:\n println(16)\n ..."},
|
||||
{17, "println(17)"},
|
||||
{19, "println(19,\n 20)"},
|
||||
{20, "println(19,\n 20)"},
|
||||
{21, "_ = func() {\n println(21)\n println(22)\n}"},
|
||||
{22, "println(22)"},
|
||||
{24, "println(24, func() {\n println(25)\n})"},
|
||||
{25, "println(25)"},
|
||||
{26, "println(24, func() {\n println(25)\n})"},
|
||||
{29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
|
||||
}
|
||||
|
||||
func (s *PrinterS) TestPrintLine(c *C) {
|
||||
for _, test := range printLineTests {
|
||||
output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(output, Equals, test.output)
|
||||
}
|
||||
}
|
||||
|
||||
var indentTests = []struct {
|
||||
in, out string
|
||||
}{
|
||||
{"", ""},
|
||||
{"\n", "\n"},
|
||||
{"a", ">>>a"},
|
||||
{"a\n", ">>>a\n"},
|
||||
{"a\nb", ">>>a\n>>>b"},
|
||||
{" ", ">>> "},
|
||||
}
|
||||
|
||||
func (s *PrinterS) TestIndent(c *C) {
|
||||
for _, test := range indentTests {
|
||||
out := Indent(test.in, ">>>")
|
||||
c.Assert(out, Equals, test.out)
|
||||
}
|
||||
|
||||
}
|
419
Godeps/_workspace/src/gopkg.in/check.v1/run_test.go
generated
vendored
419
Godeps/_workspace/src/gopkg.in/check.v1/run_test.go
generated
vendored
@ -1,419 +0,0 @@
|
||||
// These tests verify the test running logic.
|
||||
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
. "gopkg.in/check.v1"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var runnerS = Suite(&RunS{})
|
||||
|
||||
type RunS struct{}
|
||||
|
||||
func (s *RunS) TestCountSuite(c *C) {
|
||||
suitesRun += 1
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tests ensuring result counting works properly.
|
||||
|
||||
func (s *RunS) TestSuccess(c *C) {
|
||||
output := String{}
|
||||
result := Run(&SuccessHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 1)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFailure(c *C) {
|
||||
output := String{}
|
||||
result := Run(&FailHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 1)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFixture(c *C) {
|
||||
output := String{}
|
||||
result := Run(&FixtureHelper{}, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 2)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnTest(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "Test1"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 1)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 1)
|
||||
c.Check(result.FixturePanicked, Equals, 0)
|
||||
c.Check(result.Missed, Equals, 0)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnSetUpTest(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "SetUpTest"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 1)
|
||||
c.Check(result.Missed, Equals, 2)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
func (s *RunS) TestPanicOnSetUpSuite(c *C) {
|
||||
output := String{}
|
||||
helper := &FixtureHelper{panicOn: "SetUpSuite"}
|
||||
result := Run(helper, &RunConf{Output: &output})
|
||||
c.Check(result.Succeeded, Equals, 0)
|
||||
c.Check(result.Failed, Equals, 0)
|
||||
c.Check(result.Skipped, Equals, 0)
|
||||
c.Check(result.Panicked, Equals, 0)
|
||||
c.Check(result.FixturePanicked, Equals, 1)
|
||||
c.Check(result.Missed, Equals, 2)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check result aggregation.
|
||||
|
||||
func (s *RunS) TestAdd(c *C) {
|
||||
result := &Result{
|
||||
Succeeded: 1,
|
||||
Skipped: 2,
|
||||
Failed: 3,
|
||||
Panicked: 4,
|
||||
FixturePanicked: 5,
|
||||
Missed: 6,
|
||||
ExpectedFailures: 7,
|
||||
}
|
||||
result.Add(&Result{
|
||||
Succeeded: 10,
|
||||
Skipped: 20,
|
||||
Failed: 30,
|
||||
Panicked: 40,
|
||||
FixturePanicked: 50,
|
||||
Missed: 60,
|
||||
ExpectedFailures: 70,
|
||||
})
|
||||
c.Check(result.Succeeded, Equals, 11)
|
||||
c.Check(result.Skipped, Equals, 22)
|
||||
c.Check(result.Failed, Equals, 33)
|
||||
c.Check(result.Panicked, Equals, 44)
|
||||
c.Check(result.FixturePanicked, Equals, 55)
|
||||
c.Check(result.Missed, Equals, 66)
|
||||
c.Check(result.ExpectedFailures, Equals, 77)
|
||||
c.Check(result.RunError, IsNil)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check the Passed() method.
|
||||
|
||||
func (s *RunS) TestPassed(c *C) {
|
||||
c.Assert((&Result{}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Skipped: 1}).Passed(), Equals, true)
|
||||
c.Assert((&Result{Failed: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{Panicked: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{Missed: 1}).Passed(), Equals, false)
|
||||
c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Check that result printing is working correctly.
|
||||
|
||||
func (s *RunS) TestPrintSuccess(c *C) {
|
||||
result := &Result{Succeeded: 5}
|
||||
c.Check(result.String(), Equals, "OK: 5 passed")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintFailure(c *C) {
|
||||
result := &Result{Failed: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintSkipped(c *C) {
|
||||
result := &Result{Skipped: 5}
|
||||
c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintExpectedFailures(c *C) {
|
||||
result := &Result{ExpectedFailures: 5}
|
||||
c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintPanicked(c *C) {
|
||||
result := &Result{Panicked: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintFixturePanicked(c *C) {
|
||||
result := &Result{FixturePanicked: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintMissed(c *C) {
|
||||
result := &Result{Missed: 5}
|
||||
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintAll(c *C) {
|
||||
result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3,
|
||||
Panicked: 4, FixturePanicked: 5, Missed: 6}
|
||||
c.Check(result.String(), Equals,
|
||||
"OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+
|
||||
"5 FIXTURE-PANICKED, 6 MISSED")
|
||||
}
|
||||
|
||||
func (s *RunS) TestPrintRunError(c *C) {
|
||||
result := &Result{Succeeded: 1, Failed: 1,
|
||||
RunError: errors.New("Kaboom!")}
|
||||
c.Check(result.String(), Equals, "ERROR: Kaboom!")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that the method pattern flag works correctly.
|
||||
|
||||
func (s *RunS) TestFilterTestName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "Test[91]"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterTestNameWithAll(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: ".*"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterSuiteName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "FixtureHelper"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test1")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[5], Equals, "Test2")
|
||||
c.Check(helper.calls[6], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[7], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterSuiteNameAndTestName(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(helper.calls[0], Equals, "SetUpSuite")
|
||||
c.Check(helper.calls[1], Equals, "SetUpTest")
|
||||
c.Check(helper.calls[2], Equals, "Test2")
|
||||
c.Check(helper.calls[3], Equals, "TearDownTest")
|
||||
c.Check(helper.calls[4], Equals, "TearDownSuite")
|
||||
c.Check(len(helper.calls), Equals, 5)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterAllOut(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "NotFound"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
}
|
||||
|
||||
func (s *RunS) TestRequirePartialMatch(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "est"}
|
||||
Run(&helper, &runConf)
|
||||
c.Check(len(helper.calls), Equals, 8)
|
||||
}
|
||||
|
||||
func (s *RunS) TestFilterError(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Filter: "]["}
|
||||
result := Run(&helper, &runConf)
|
||||
c.Check(result.String(), Equals,
|
||||
"ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`")
|
||||
c.Check(len(helper.calls), Equals, 0)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that List works correctly.
|
||||
|
||||
func (s *RunS) TestListFiltered(c *C) {
|
||||
names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
|
||||
c.Assert(names, DeepEquals, []string{
|
||||
"FixtureHelper.Test1",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RunS) TestList(c *C) {
|
||||
names := List(&FixtureHelper{}, &RunConf{})
|
||||
c.Assert(names, DeepEquals, []string{
|
||||
"FixtureHelper.Test1",
|
||||
"FixtureHelper.Test2",
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that verbose mode prints tests which pass as well.
|
||||
|
||||
func (s *RunS) TestVerboseMode(c *C) {
|
||||
helper := FixtureHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" +
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) {
|
||||
helper := FixtureHelper{panicOn: "Test1"}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true}
|
||||
Run(&helper, &runConf)
|
||||
|
||||
expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line.
|
||||
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify the stream output mode. In this mode there's no output caching.
|
||||
|
||||
type StreamHelper struct {
|
||||
l2 sync.Mutex
|
||||
l3 sync.Mutex
|
||||
}
|
||||
|
||||
func (s *StreamHelper) SetUpSuite(c *C) {
|
||||
c.Log("0")
|
||||
}
|
||||
|
||||
func (s *StreamHelper) Test1(c *C) {
|
||||
c.Log("1")
|
||||
s.l2.Lock()
|
||||
s.l3.Lock()
|
||||
go func() {
|
||||
s.l2.Lock() // Wait for "2".
|
||||
c.Log("3")
|
||||
s.l3.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *StreamHelper) Test2(c *C) {
|
||||
c.Log("2")
|
||||
s.l2.Unlock()
|
||||
s.l3.Lock() // Wait for "3".
|
||||
c.Fail()
|
||||
c.Log("4")
|
||||
}
|
||||
|
||||
func (s *RunS) TestStreamMode(c *C) {
|
||||
helper := &StreamHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(helper, &runConf)
|
||||
|
||||
expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" +
|
||||
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" +
|
||||
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" +
|
||||
"FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
type StreamMissHelper struct{}
|
||||
|
||||
func (s *StreamMissHelper) SetUpSuite(c *C) {
|
||||
c.Log("0")
|
||||
c.Fail()
|
||||
}
|
||||
|
||||
func (s *StreamMissHelper) Test1(c *C) {
|
||||
c.Log("1")
|
||||
}
|
||||
|
||||
func (s *RunS) TestStreamModeWithMiss(c *C) {
|
||||
helper := &StreamMissHelper{}
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Stream: true}
|
||||
Run(helper, &runConf)
|
||||
|
||||
expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" +
|
||||
"FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" +
|
||||
"START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" +
|
||||
"MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n"
|
||||
|
||||
c.Assert(output.value, Matches, expected)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Verify that that the keep work dir request indeed does so.
|
||||
|
||||
type WorkDirSuite struct {}
|
||||
|
||||
func (s *WorkDirSuite) Test(c *C) {
|
||||
c.MkDir()
|
||||
}
|
||||
|
||||
func (s *RunS) TestKeepWorkDir(c *C) {
|
||||
output := String{}
|
||||
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
|
||||
result := Run(&WorkDirSuite{}, &runConf)
|
||||
|
||||
c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir)
|
||||
|
||||
stat, err := os.Stat(result.WorkDir)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(stat.IsDir(), Equals, true)
|
||||
}
|
40
Makefile
40
Makefile
@ -6,10 +6,9 @@ checkdeps:
|
||||
|
||||
checkgopath:
|
||||
@echo "Checking if project is at ${GOPATH}"
|
||||
@for mcpath in $(echo ${GOPATH} | sed 's/:/\n/g' | grep -v Godeps); do if [ ! -d ${mcpath}/src/github.com/minio/minio ]; then echo "Project not found in ${mcpath}, please follow instructions provided at https://github.com/minio/minio/blob/master/CONTRIBUTING.md#setup-your-minio-github-repository" && exit 1; fi done
|
||||
@for mcpath in $(echo ${GOPATH} | sed 's/:/\n/g'); do if [ ! -d ${mcpath}/src/github.com/minio/minio ]; then echo "Project not found in ${mcpath}, please follow instructions provided at https://github.com/minio/minio/blob/master/CONTRIBUTING.md#setup-your-minio-github-repository" && exit 1; fi done
|
||||
|
||||
getdeps: checkdeps checkgopath
|
||||
@go get github.com/tools/godep && echo "Installed godep:"
|
||||
@go get github.com/golang/lint/golint && echo "Installed golint:"
|
||||
@go get golang.org/x/tools/cmd/vet && echo "Installed vet:"
|
||||
@go get github.com/fzipp/gocyclo && echo "Installed gocyclo:"
|
||||
@ -18,53 +17,42 @@ verifiers: getdeps vet fmt lint cyclo
|
||||
|
||||
vet:
|
||||
@echo "Running $@:"
|
||||
@go vet ./...
|
||||
@go vet .
|
||||
@go vet github.com/minio/minio/pkg...
|
||||
fmt:
|
||||
@echo "Running $@:"
|
||||
@test -z "$$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)" || \
|
||||
echo "+ please format Go code with 'gofmt -s'"
|
||||
@gofmt -s -l *.go
|
||||
@gofmt -s -l pkg
|
||||
|
||||
lint:
|
||||
@echo "Running $@:"
|
||||
@test -z "$$(golint ./... | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
|
||||
@golint .
|
||||
@golint pkg
|
||||
|
||||
cyclo:
|
||||
@echo "Running $@:"
|
||||
@test -z "$$(gocyclo -over 25 . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
|
||||
@gocyclo -over 25 .
|
||||
|
||||
build: getdeps verifiers
|
||||
@echo "Installing minio:"
|
||||
@godep go generate ./...
|
||||
@godep go test -race ./...
|
||||
@go generate ./...
|
||||
@go test -race github.com/minio/minio/pkg...
|
||||
|
||||
gomake-all: build
|
||||
@godep go install github.com/minio/minio
|
||||
@go install github.com/minio/minio
|
||||
|
||||
release: genversion
|
||||
@echo "Installing minio for new version.go:"
|
||||
@godep go install github.com/minio/minio
|
||||
@go install github.com/minio/minio
|
||||
|
||||
genversion:
|
||||
@echo "Generating new minio version.go"
|
||||
@godep go run genversion.go
|
||||
|
||||
godepupdate:
|
||||
@(env bash $(PWD)/buildscripts/updatedeps.sh)
|
||||
@go run genversion.go
|
||||
|
||||
install: gomake-all
|
||||
|
||||
save:
|
||||
@godep save ./...
|
||||
|
||||
restore:
|
||||
@godep restore
|
||||
|
||||
env:
|
||||
@godep go env
|
||||
|
||||
clean:
|
||||
@echo "Cleaning up all the generated files:"
|
||||
@rm -fv cover.out
|
||||
@rm -fv pkg/utils/split/TESTPREFIX.*
|
||||
@rm -fv minio
|
||||
@godep go clean
|
||||
@find Godeps -name "*.a" -type f -exec rm -vf {} \+
|
||||
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Minio Client (C) 2015 Minio, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
_init() {
|
||||
godeps="Godeps/Godeps.json"
|
||||
filter="minio/minio"
|
||||
}
|
||||
|
||||
update() {
|
||||
for dep in $1; do
|
||||
godep update $dep;
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
deps=$(env grep ImportPath ${godeps} | grep -v ${filter} | cut -f2 -d: | sed -e 's/,//' -e 's/^[ \t]*//' -e 's/[ \t]*$//' -e 's/\"//g' | tr '\n' ' ')
|
||||
update ${deps}
|
||||
}
|
||||
|
||||
_init && main "$@"
|
@ -20,7 +20,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/minio/internal/github.com/minio/cli"
|
||||
"github.com/minio/minio/pkg/controller"
|
||||
"github.com/minio/minio/pkg/donut"
|
||||
"github.com/minio/minio/pkg/server"
|
||||
|
@ -5,6 +5,9 @@ Just a few functions for helping humanize times and sizes.
|
||||
`go get` it as `github.com/dustin/go-humanize`, import it as
|
||||
`"github.com/dustin/go-humanize"`, use it as `humanize`
|
||||
|
||||
See [godoc](https://godoc.org/github.com/dustin/go-humanize) for
|
||||
complete documentation.
|
||||
|
||||
## Sizes
|
||||
|
||||
This lets you take numbers like `82854982` and convert them to useful
|
@ -115,7 +115,7 @@ func humanateBigBytes(s, base *big.Int, sizes []string) string {
|
||||
//
|
||||
// BigBytes(82854982) -> 83MB
|
||||
func BigBytes(s *big.Int) string {
|
||||
sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||
sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||
return humanateBigBytes(s, bigSIExp, sizes)
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func humanateBytes(s uint64, base float64, sizes []string) string {
|
||||
//
|
||||
// Bytes(82854982) -> 83MB
|
||||
func Bytes(s uint64) string {
|
||||
sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}
|
||||
sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
|
||||
return humanateBytes(s, 1000, sizes)
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ func Comma(v int64) string {
|
||||
v = 0 - v
|
||||
}
|
||||
|
||||
parts := []string{"", "", "", "", "", "", "", ""}
|
||||
parts := []string{"", "", "", "", "", "", ""}
|
||||
j := len(parts) - 1
|
||||
|
||||
for v > 999 {
|
192
internal/github.com/dustin/go-humanize/number.go
Normal file
192
internal/github.com/dustin/go-humanize/number.go
Normal file
@ -0,0 +1,192 @@
|
||||
package humanize
|
||||
|
||||
/*
|
||||
Slightly adapted from the source to fit go-humanize.
|
||||
|
||||
Author: https://github.com/gorhill
|
||||
Source: https://gist.github.com/gorhill/5285193
|
||||
|
||||
*/
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
renderFloatPrecisionMultipliers = [...]float64{
|
||||
1,
|
||||
10,
|
||||
100,
|
||||
1000,
|
||||
10000,
|
||||
100000,
|
||||
1000000,
|
||||
10000000,
|
||||
100000000,
|
||||
1000000000,
|
||||
}
|
||||
|
||||
renderFloatPrecisionRounders = [...]float64{
|
||||
0.5,
|
||||
0.05,
|
||||
0.005,
|
||||
0.0005,
|
||||
0.00005,
|
||||
0.000005,
|
||||
0.0000005,
|
||||
0.00000005,
|
||||
0.000000005,
|
||||
0.0000000005,
|
||||
}
|
||||
)
|
||||
|
||||
// FormatFloat produces a formatted number as string based on the following user-specified criteria:
|
||||
// * thousands separator
|
||||
// * decimal separator
|
||||
// * decimal precision
|
||||
//
|
||||
// Usage: s := RenderFloat(format, n)
|
||||
// The format parameter tells how to render the number n.
|
||||
//
|
||||
// See examples: http://play.golang.org/p/LXc1Ddm1lJ
|
||||
//
|
||||
// Examples of format strings, given n = 12345.6789:
|
||||
// "#,###.##" => "12,345.67"
|
||||
// "#,###." => "12,345"
|
||||
// "#,###" => "12345,678"
|
||||
// "#\u202F###,##" => "12 345,68"
|
||||
// "#.###,###### => 12.345,678900
|
||||
// "" (aka default format) => 12,345.67
|
||||
//
|
||||
// The highest precision allowed is 9 digits after the decimal symbol.
|
||||
// There is also a version for integer number, FormatInteger(),
|
||||
// which is convenient for calls within template.
|
||||
func FormatFloat(format string, n float64) string {
|
||||
// Special cases:
|
||||
// NaN = "NaN"
|
||||
// +Inf = "+Infinity"
|
||||
// -Inf = "-Infinity"
|
||||
if math.IsNaN(n) {
|
||||
return "NaN"
|
||||
}
|
||||
if n > math.MaxFloat64 {
|
||||
return "Infinity"
|
||||
}
|
||||
if n < -math.MaxFloat64 {
|
||||
return "-Infinity"
|
||||
}
|
||||
|
||||
// default format
|
||||
precision := 2
|
||||
decimalStr := "."
|
||||
thousandStr := ","
|
||||
positiveStr := ""
|
||||
negativeStr := "-"
|
||||
|
||||
if len(format) > 0 {
|
||||
format := []rune(format)
|
||||
|
||||
// If there is an explicit format directive,
|
||||
// then default values are these:
|
||||
precision = 9
|
||||
thousandStr = ""
|
||||
|
||||
// collect indices of meaningful formatting directives
|
||||
formatIndx := []int{}
|
||||
for i, char := range format {
|
||||
if char != '#' && char != '0' {
|
||||
formatIndx = append(formatIndx, i)
|
||||
}
|
||||
}
|
||||
|
||||
if len(formatIndx) > 0 {
|
||||
// Directive at index 0:
|
||||
// Must be a '+'
|
||||
// Raise an error if not the case
|
||||
// index: 0123456789
|
||||
// +0.000,000
|
||||
// +000,000.0
|
||||
// +0000.00
|
||||
// +0000
|
||||
if formatIndx[0] == 0 {
|
||||
if format[formatIndx[0]] != '+' {
|
||||
panic("RenderFloat(): invalid positive sign directive")
|
||||
}
|
||||
positiveStr = "+"
|
||||
formatIndx = formatIndx[1:]
|
||||
}
|
||||
|
||||
// Two directives:
|
||||
// First is thousands separator
|
||||
// Raise an error if not followed by 3-digit
|
||||
// 0123456789
|
||||
// 0.000,000
|
||||
// 000,000.00
|
||||
if len(formatIndx) == 2 {
|
||||
if (formatIndx[1] - formatIndx[0]) != 4 {
|
||||
panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers")
|
||||
}
|
||||
thousandStr = string(format[formatIndx[0]])
|
||||
formatIndx = formatIndx[1:]
|
||||
}
|
||||
|
||||
// One directive:
|
||||
// Directive is decimal separator
|
||||
// The number of digit-specifier following the separator indicates wanted precision
|
||||
// 0123456789
|
||||
// 0.00
|
||||
// 000,0000
|
||||
if len(formatIndx) == 1 {
|
||||
decimalStr = string(format[formatIndx[0]])
|
||||
precision = len(format) - formatIndx[0] - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate sign part
|
||||
var signStr string
|
||||
if n >= 0.000000001 {
|
||||
signStr = positiveStr
|
||||
} else if n <= -0.000000001 {
|
||||
signStr = negativeStr
|
||||
n = -n
|
||||
} else {
|
||||
signStr = ""
|
||||
n = 0.0
|
||||
}
|
||||
|
||||
// split number into integer and fractional parts
|
||||
intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])
|
||||
|
||||
// generate integer part string
|
||||
intStr := strconv.Itoa(int(intf))
|
||||
|
||||
// add thousand separator if required
|
||||
if len(thousandStr) > 0 {
|
||||
for i := len(intStr); i > 3; {
|
||||
i -= 3
|
||||
intStr = intStr[:i] + thousandStr + intStr[i:]
|
||||
}
|
||||
}
|
||||
|
||||
// no fractional part, we can leave now
|
||||
if precision == 0 {
|
||||
return signStr + intStr
|
||||
}
|
||||
|
||||
// generate fractional part
|
||||
fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision]))
|
||||
// may need padding
|
||||
if len(fracStr) < precision {
|
||||
fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr
|
||||
}
|
||||
|
||||
return signStr + intStr + decimalStr + fracStr
|
||||
}
|
||||
|
||||
// FormatInteger produces a formatted number as string.
|
||||
// See FormatFloat.
|
||||
func FormatInteger(format string, n int) string {
|
||||
return FormatFloat(format, float64(n))
|
||||
}
|
@ -14,8 +14,8 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/facebookgo/clock"
|
||||
"github.com/facebookgo/stats"
|
||||
"github.com/minio/minio/internal/github.com/facebookgo/clock"
|
||||
"github.com/minio/minio/internal/github.com/facebookgo/stats"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -100,7 +100,7 @@ func (h HTTP) Serve(s *http.Server, l net.Listener) Server {
|
||||
}
|
||||
|
||||
// ListenAndServe returns a Server for the given http.Server. It is equivalent
|
||||
// to ListendAndServe from the standard library, but returns immediately.
|
||||
// to ListenAndServe from the standard library, but returns immediately.
|
||||
// Requests will be accepted in a background goroutine. If the http.Server has
|
||||
// a non-nil TLSConfig, a TLS enabled listener will be setup.
|
||||
func (h HTTP) ListenAndServe(s *http.Server) (Server, error) {
|
@ -43,6 +43,10 @@ m := structs.Map(server)
|
||||
// => ["gopher", 123456, true]
|
||||
v := structs.Values(server)
|
||||
|
||||
// Convert the names of a struct to a []string
|
||||
// (see "Names methods" for more info about fields)
|
||||
n := structs.Names(server)
|
||||
|
||||
// Convert the values of a struct to a []*Field
|
||||
// (see "Field methods" for more info about fields)
|
||||
f := structs.Fields(server)
|
||||
@ -73,8 +77,9 @@ s := structs.New(server)
|
||||
m := s.Map() // Get a map[string]interface{}
|
||||
v := s.Values() // Get a []interface{}
|
||||
f := s.Fields() // Get a []*Field
|
||||
n := s.Names() // Get a []string
|
||||
f := s.Field(name) // Get a *Field based on the given field name
|
||||
f, ok := s.FieldsOk(name) // Get a *Field based on the given field name
|
||||
f, ok := s.FieldOk(name) // Get a *Field based on the given field name
|
||||
n := s.Name() // Get the struct name
|
||||
h := s.HasZero() // Check if any field is initialized
|
||||
z := s.IsZero() // Check if all fields are initialized
|
@ -92,7 +92,9 @@ func (s *Struct) Map() map[string]interface{} {
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// map[string]interface{} too
|
||||
finalVal = Map(val.Interface())
|
||||
n := New(val.Interface())
|
||||
n.TagName = s.TagName
|
||||
finalVal = n.Map()
|
||||
} else {
|
||||
finalVal = val.Interface()
|
||||
}
|
||||
@ -171,6 +173,25 @@ func (s *Struct) Fields() []*Field {
|
||||
return getFields(s.value, s.TagName)
|
||||
}
|
||||
|
||||
// Names returns a slice of field names. A struct tag with the content of "-"
|
||||
// ignores the checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// It panics if s's kind is not struct.
|
||||
func (s *Struct) Names() []string {
|
||||
fields := getFields(s.value, s.TagName)
|
||||
|
||||
names := make([]string, len(fields))
|
||||
|
||||
for i, field := range fields {
|
||||
names[i] = field.Name()
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func getFields(v reflect.Value, tagName string) []*Field {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
@ -387,6 +408,12 @@ func Fields(s interface{}) []*Field {
|
||||
return New(s).Fields()
|
||||
}
|
||||
|
||||
// Names returns a slice of field names. For more info refer to Struct types
|
||||
// Names() method. It panics if s's kind is not struct.
|
||||
func Names(s interface{}) []string {
|
||||
return New(s).Names()
|
||||
}
|
||||
|
||||
// IsZero returns true if all fields is equal to a zero value. For more info
|
||||
// refer to Struct types IsZero() method. It panics if s's kind is not struct.
|
||||
func IsZero(s interface{}) bool {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user