mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-14 01:14:25 +00:00
Update dependencies
This commit is contained in:
parent
6a6d0e1350
commit
ca66b46fa2
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -35,7 +35,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/yudai/hcl",
|
"ImportPath": "github.com/yudai/hcl",
|
||||||
"Rev": "7227a719113b77a78318a43dba44951556ff9e3d"
|
"Rev": "5fa2393b3552119bf33a69adb1402a1160cba23d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/yudai/umutex",
|
"ImportPath": "github.com/yudai/umutex",
|
||||||
|
118
Godeps/_workspace/src/github.com/braintree/manners/helpers_test.go
generated
vendored
118
Godeps/_workspace/src/github.com/braintree/manners/helpers_test.go
generated
vendored
@ -1,118 +0,0 @@
|
|||||||
package manners
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"crypto/tls"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newServer() *GracefulServer {
|
|
||||||
return NewWithServer(new(http.Server))
|
|
||||||
}
|
|
||||||
|
|
||||||
// a simple step-controllable http client
|
|
||||||
type client struct {
|
|
||||||
tls bool
|
|
||||||
addr net.Addr
|
|
||||||
connected chan error
|
|
||||||
sendrequest chan bool
|
|
||||||
idle chan error
|
|
||||||
idlerelease chan bool
|
|
||||||
closed chan bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) Run() {
|
|
||||||
go func() {
|
|
||||||
var err error
|
|
||||||
conn, err := net.Dial(c.addr.Network(), c.addr.String())
|
|
||||||
if err != nil {
|
|
||||||
c.connected <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if c.tls {
|
|
||||||
conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
|
|
||||||
}
|
|
||||||
c.connected <- nil
|
|
||||||
for <-c.sendrequest {
|
|
||||||
_, err = conn.Write([]byte("GET / HTTP/1.1\nHost: localhost:8000\n\n"))
|
|
||||||
if err != nil {
|
|
||||||
c.idle <- err
|
|
||||||
}
|
|
||||||
// Read response; no content
|
|
||||||
scanner := bufio.NewScanner(conn)
|
|
||||||
for scanner.Scan() {
|
|
||||||
// our null handler doesn't send a body, so we know the request is
|
|
||||||
// done when we reach the blank line after the headers
|
|
||||||
if scanner.Text() == "" {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.idle <- scanner.Err()
|
|
||||||
<-c.idlerelease
|
|
||||||
}
|
|
||||||
conn.Close()
|
|
||||||
ioutil.ReadAll(conn)
|
|
||||||
c.closed <- true
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClient(addr net.Addr, tls bool) *client {
|
|
||||||
return &client{
|
|
||||||
addr: addr,
|
|
||||||
tls: tls,
|
|
||||||
connected: make(chan error),
|
|
||||||
sendrequest: make(chan bool),
|
|
||||||
idle: make(chan error),
|
|
||||||
idlerelease: make(chan bool),
|
|
||||||
closed: make(chan bool),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// a handler that returns 200 ok with no body
|
|
||||||
var nullHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
|
||||||
|
|
||||||
func startGenericServer(t *testing.T, server *GracefulServer, statechanged chan http.ConnState, runner func() error) (l net.Listener, errc chan error) {
|
|
||||||
server.Addr = "localhost:0"
|
|
||||||
server.Handler = nullHandler
|
|
||||||
if statechanged != nil {
|
|
||||||
// Wrap the ConnState handler with something that will notify
|
|
||||||
// the statechanged channel when a state change happens
|
|
||||||
server.ConnState = func(conn net.Conn, newState http.ConnState) {
|
|
||||||
statechanged <- newState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server.up = make(chan net.Listener)
|
|
||||||
exitchan := make(chan error)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
exitchan <- runner()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// wait for server socket to be bound
|
|
||||||
select {
|
|
||||||
case l = <-server.up:
|
|
||||||
// all good
|
|
||||||
|
|
||||||
case err := <-exitchan:
|
|
||||||
// all bad
|
|
||||||
t.Fatal("Server failed to start", err)
|
|
||||||
}
|
|
||||||
return l, exitchan
|
|
||||||
}
|
|
||||||
|
|
||||||
func startServer(t *testing.T, server *GracefulServer, statechanged chan http.ConnState) (
|
|
||||||
l net.Listener, errc chan error) {
|
|
||||||
return startGenericServer(t, server, statechanged, server.ListenAndServe)
|
|
||||||
}
|
|
||||||
|
|
||||||
func startTLSServer(t *testing.T, server *GracefulServer, certFile, keyFile string, statechanged chan http.ConnState) (l net.Listener, errc chan error) {
|
|
||||||
runner := func() error {
|
|
||||||
return server.ListenAndServeTLS(certFile, keyFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return startGenericServer(t, server, statechanged, runner)
|
|
||||||
}
|
|
243
Godeps/_workspace/src/github.com/braintree/manners/server_test.go
generated
vendored
243
Godeps/_workspace/src/github.com/braintree/manners/server_test.go
generated
vendored
@ -1,243 +0,0 @@
|
|||||||
package manners
|
|
||||||
|
|
||||||
import (
|
|
||||||
helpers "github.com/braintree/manners/test_helpers"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Tests that the server allows in-flight requests to complete
|
|
||||||
// before shutting down.
|
|
||||||
func TestGracefulness(t *testing.T) {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
server.wg = wg
|
|
||||||
statechanged := make(chan http.ConnState)
|
|
||||||
listener, exitchan := startServer(t, server, statechanged)
|
|
||||||
|
|
||||||
client := newClient(listener.Addr(), false)
|
|
||||||
client.Run()
|
|
||||||
|
|
||||||
// wait for client to connect, but don't let it send the request yet
|
|
||||||
if err := <-client.connected; err != nil {
|
|
||||||
t.Fatal("Client failed to connect to server", err)
|
|
||||||
}
|
|
||||||
// avoid a race between the client connection and the server accept
|
|
||||||
if state := <-statechanged; state != http.StateNew {
|
|
||||||
t.Fatal("Unexpected state", state)
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Close()
|
|
||||||
|
|
||||||
waiting := <-wg.WaitCalled
|
|
||||||
if waiting < 1 {
|
|
||||||
t.Errorf("Expected the waitgroup to equal 1 at shutdown; actually %d", waiting)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow the client to finish sending the request and make sure the server exits after
|
|
||||||
// (client will be in connected but idle state at that point)
|
|
||||||
client.sendrequest <- true
|
|
||||||
close(client.sendrequest)
|
|
||||||
if err := <-exitchan; err != nil {
|
|
||||||
t.Error("Unexpected error during shutdown", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests that the server begins to shut down when told to and does not accept
|
|
||||||
// new requests once shutdown has begun
|
|
||||||
func TestShutdown(t *testing.T) {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
server.wg = wg
|
|
||||||
statechanged := make(chan http.ConnState)
|
|
||||||
listener, exitchan := startServer(t, server, statechanged)
|
|
||||||
|
|
||||||
client1 := newClient(listener.Addr(), false)
|
|
||||||
client1.Run()
|
|
||||||
|
|
||||||
// wait for client1 to connect
|
|
||||||
if err := <-client1.connected; err != nil {
|
|
||||||
t.Fatal("Client failed to connect to server", err)
|
|
||||||
}
|
|
||||||
// avoid a race between the client connection and the server accept
|
|
||||||
if state := <-statechanged; state != http.StateNew {
|
|
||||||
t.Fatal("Unexpected state", state)
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the shutdown; once it hits waitgroup.Wait()
|
|
||||||
// the listener should of been closed, though client1 is still connected
|
|
||||||
if server.Close() != true {
|
|
||||||
t.Fatal("first call to Close returned false")
|
|
||||||
}
|
|
||||||
if server.Close() != false {
|
|
||||||
t.Fatal("second call to Close returned true")
|
|
||||||
}
|
|
||||||
|
|
||||||
waiting := <-wg.WaitCalled
|
|
||||||
if waiting != 1 {
|
|
||||||
t.Errorf("Waitcount should be one, got %d", waiting)
|
|
||||||
}
|
|
||||||
|
|
||||||
// should get connection refused at this point
|
|
||||||
client2 := newClient(listener.Addr(), false)
|
|
||||||
client2.Run()
|
|
||||||
|
|
||||||
if err := <-client2.connected; err == nil {
|
|
||||||
t.Fatal("client2 connected when it should of received connection refused")
|
|
||||||
}
|
|
||||||
|
|
||||||
// let client1 finish so the server can exit
|
|
||||||
close(client1.sendrequest) // don't bother sending an actual request
|
|
||||||
|
|
||||||
<-exitchan
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that a connection is closed upon reaching an idle state if and only if the server
|
|
||||||
// is shutting down.
|
|
||||||
func TestCloseOnIdle(t *testing.T) {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
server.wg = wg
|
|
||||||
fl := helpers.NewListener()
|
|
||||||
runner := func() error {
|
|
||||||
return server.Serve(fl)
|
|
||||||
}
|
|
||||||
|
|
||||||
startGenericServer(t, server, nil, runner)
|
|
||||||
|
|
||||||
// Change to idle state while server is not closing; Close should not be called
|
|
||||||
conn := &helpers.Conn{}
|
|
||||||
server.ConnState(conn, http.StateIdle)
|
|
||||||
if conn.CloseCalled {
|
|
||||||
t.Error("Close was called unexpected")
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Close()
|
|
||||||
|
|
||||||
// wait until the server calls Close() on the listener
|
|
||||||
// by that point the atomic closing variable will have been updated, avoiding a race.
|
|
||||||
<-fl.CloseCalled
|
|
||||||
|
|
||||||
conn = &helpers.Conn{}
|
|
||||||
server.ConnState(conn, http.StateIdle)
|
|
||||||
if !conn.CloseCalled {
|
|
||||||
t.Error("Close was not called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForState(t *testing.T, waiter chan http.ConnState, state http.ConnState, errmsg string) {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case ns := <-waiter:
|
|
||||||
if ns == state {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Fatal(errmsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that a request moving from active->idle->active using an actual
|
|
||||||
// network connection still results in a corect shutdown
|
|
||||||
func TestStateTransitionActiveIdleActive(t *testing.T) {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
statechanged := make(chan http.ConnState)
|
|
||||||
server.wg = wg
|
|
||||||
listener, exitchan := startServer(t, server, statechanged)
|
|
||||||
|
|
||||||
client := newClient(listener.Addr(), false)
|
|
||||||
client.Run()
|
|
||||||
|
|
||||||
// wait for client to connect, but don't let it send the request
|
|
||||||
if err := <-client.connected; err != nil {
|
|
||||||
t.Fatal("Client failed to connect to server", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
client.sendrequest <- true
|
|
||||||
waitForState(t, statechanged, http.StateActive, "Client failed to reach active state")
|
|
||||||
<-client.idle
|
|
||||||
client.idlerelease <- true
|
|
||||||
waitForState(t, statechanged, http.StateIdle, "Client failed to reach idle state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// client is now in an idle state
|
|
||||||
|
|
||||||
server.Close()
|
|
||||||
waiting := <-wg.WaitCalled
|
|
||||||
if waiting != 0 {
|
|
||||||
t.Errorf("Waitcount should be zero, got %d", waiting)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := <-exitchan; err != nil {
|
|
||||||
t.Error("Unexpected error during shutdown", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test state transitions from new->active->-idle->closed using an actual
|
|
||||||
// network connection and make sure the waitgroup count is correct at the end.
|
|
||||||
func TestStateTransitionActiveIdleClosed(t *testing.T) {
|
|
||||||
var (
|
|
||||||
listener net.Listener
|
|
||||||
exitchan chan error
|
|
||||||
)
|
|
||||||
|
|
||||||
keyFile, err1 := helpers.NewTempFile(helpers.Key)
|
|
||||||
certFile, err2 := helpers.NewTempFile(helpers.Cert)
|
|
||||||
defer keyFile.Unlink()
|
|
||||||
defer certFile.Unlink()
|
|
||||||
|
|
||||||
if err1 != nil || err2 != nil {
|
|
||||||
t.Fatal("Failed to create temporary files", err1, err2)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, withTLS := range []bool{false, true} {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
statechanged := make(chan http.ConnState)
|
|
||||||
server.wg = wg
|
|
||||||
if withTLS {
|
|
||||||
listener, exitchan = startTLSServer(t, server, certFile.Name(), keyFile.Name(), statechanged)
|
|
||||||
} else {
|
|
||||||
listener, exitchan = startServer(t, server, statechanged)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := newClient(listener.Addr(), withTLS)
|
|
||||||
client.Run()
|
|
||||||
|
|
||||||
// wait for client to connect, but don't let it send the request
|
|
||||||
if err := <-client.connected; err != nil {
|
|
||||||
t.Fatal("Client failed to connect to server", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client.sendrequest <- true
|
|
||||||
waitForState(t, statechanged, http.StateActive, "Client failed to reach active state")
|
|
||||||
|
|
||||||
err := <-client.idle
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("tls=%t unexpected error from client %s", withTLS, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client.idlerelease <- true
|
|
||||||
waitForState(t, statechanged, http.StateIdle, "Client failed to reach idle state")
|
|
||||||
|
|
||||||
// client is now in an idle state
|
|
||||||
close(client.sendrequest)
|
|
||||||
<-client.closed
|
|
||||||
waitForState(t, statechanged, http.StateClosed, "Client failed to reach closed state")
|
|
||||||
|
|
||||||
server.Close()
|
|
||||||
waiting := <-wg.WaitCalled
|
|
||||||
if waiting != 0 {
|
|
||||||
t.Errorf("Waitcount should be zero, got %d", waiting)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := <-exitchan; err != nil {
|
|
||||||
t.Error("Unexpected error during shutdown", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
54
Godeps/_workspace/src/github.com/braintree/manners/transition_test.go
generated
vendored
54
Godeps/_workspace/src/github.com/braintree/manners/transition_test.go
generated
vendored
@ -1,54 +0,0 @@
|
|||||||
package manners
|
|
||||||
|
|
||||||
import (
|
|
||||||
helpers "github.com/braintree/manners/test_helpers"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStateTransitions(t *testing.T) {
|
|
||||||
tests := []transitionTest{
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive}, 1},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateClosed}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateClosed}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateHijacked}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateIdle}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateIdle, http.StateActive}, 1},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateIdle, http.StateActive, http.StateIdle}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateIdle, http.StateActive, http.StateClosed}, 0},
|
|
||||||
transitionTest{[]http.ConnState{http.StateNew, http.StateActive, http.StateIdle, http.StateActive, http.StateIdle, http.StateClosed}, 0},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
testStateTransition(t, test)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type transitionTest struct {
|
|
||||||
states []http.ConnState
|
|
||||||
expectedWgCount int
|
|
||||||
}
|
|
||||||
|
|
||||||
func testStateTransition(t *testing.T, test transitionTest) {
|
|
||||||
server := newServer()
|
|
||||||
wg := helpers.NewWaitGroup()
|
|
||||||
server.wg = wg
|
|
||||||
startServer(t, server, nil)
|
|
||||||
|
|
||||||
conn := &helpers.Conn{}
|
|
||||||
for _, newState := range test.states {
|
|
||||||
server.ConnState(conn, newState)
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Close()
|
|
||||||
waiting := <-wg.WaitCalled
|
|
||||||
if waiting != test.expectedWgCount {
|
|
||||||
names := make([]string, len(test.states))
|
|
||||||
for i, s := range test.states {
|
|
||||||
names[i] = s.String()
|
|
||||||
}
|
|
||||||
transitions := strings.Join(names, " -> ")
|
|
||||||
t.Errorf("%s - Waitcount should be %d, got %d", transitions, test.expectedWgCount, waiting)
|
|
||||||
}
|
|
||||||
}
|
|
867
Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go
generated
vendored
867
Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go
generated
vendored
@ -1,867 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleApp() {
|
|
||||||
// set args for examples sake
|
|
||||||
os.Args = []string{"greet", "--name", "Jeremy"}
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "greet"
|
|
||||||
app.Flags = []Flag{
|
|
||||||
StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
|
||||||
}
|
|
||||||
app.Action = func(c *Context) {
|
|
||||||
fmt.Printf("Hello %v\n", c.String("name"))
|
|
||||||
}
|
|
||||||
app.Author = "Harrison"
|
|
||||||
app.Email = "harrison@lolwut.com"
|
|
||||||
app.Authors = []Author{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 := NewApp()
|
|
||||||
app.Name = "say"
|
|
||||||
app.Commands = []Command{
|
|
||||||
{
|
|
||||||
Name: "hello",
|
|
||||||
Aliases: []string{"hi"},
|
|
||||||
Usage: "use it to see a description",
|
|
||||||
Description: "This is how we describe hello the function",
|
|
||||||
Subcommands: []Command{
|
|
||||||
{
|
|
||||||
Name: "english",
|
|
||||||
Aliases: []string{"en"},
|
|
||||||
Usage: "sends a greeting in english",
|
|
||||||
Description: "greets someone in english",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "Bob",
|
|
||||||
Usage: "Name of the person to greet",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(c *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 := NewApp()
|
|
||||||
app.Name = "greet"
|
|
||||||
app.Flags = []Flag{
|
|
||||||
StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
|
||||||
}
|
|
||||||
app.Commands = []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 *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 ExampleAppBashComplete() {
|
|
||||||
// set args for examples sake
|
|
||||||
os.Args = []string{"greet", "--generate-bash-completion"}
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "greet"
|
|
||||||
app.EnableBashCompletion = true
|
|
||||||
app.Commands = []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 *Context) {
|
|
||||||
fmt.Printf("i like to describe things")
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "next",
|
|
||||||
Usage: "next example",
|
|
||||||
Description: "more stuff to see when generating bash completion",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
fmt.Printf("the next example")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run(os.Args)
|
|
||||||
// Output:
|
|
||||||
// describeit
|
|
||||||
// d
|
|
||||||
// next
|
|
||||||
// help
|
|
||||||
// h
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run(t *testing.T) {
|
|
||||||
s := ""
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
app.Action = func(c *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 := NewApp()
|
|
||||||
fooCommand := Command{Name: "foobar", Aliases: []string{"f"}}
|
|
||||||
batCommand := Command{Name: "batbaz", Aliases: []string{"b"}}
|
|
||||||
app.Commands = []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 := NewApp()
|
|
||||||
command := Command{
|
|
||||||
Name: "cmd",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{Name: "option", Value: "", Usage: "some option"},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
parsedOption = c.String("option")
|
|
||||||
firstArg = c.Args().First()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Commands = []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 *Context
|
|
||||||
|
|
||||||
a := NewApp()
|
|
||||||
a.Commands = []Command{
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
context = c
|
|
||||||
},
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{
|
|
||||||
Name: "lang",
|
|
||||||
Value: "english",
|
|
||||||
Usage: "language for the greeting",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Before: func(_ *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 := NewApp()
|
|
||||||
command := Command{
|
|
||||||
Name: "cmd",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{Name: "option", Value: "", Usage: "some option"},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
parsedOption = c.String("option")
|
|
||||||
args = c.Args()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Commands = []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 := NewApp()
|
|
||||||
command := Command{
|
|
||||||
Name: "cmd",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
args = c.Args()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Commands = []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 := NewApp()
|
|
||||||
app.Flags = []Flag{
|
|
||||||
Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
|
|
||||||
}
|
|
||||||
app.Action = func(c *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 := NewApp()
|
|
||||||
command := Command{
|
|
||||||
Name: "cmd",
|
|
||||||
Flags: []Flag{
|
|
||||||
IntSliceFlag{Name: "p", Value: &IntSlice{}, Usage: "set one or more ip addr"},
|
|
||||||
StringSliceFlag{Name: "ip", Value: &StringSlice{}, Usage: "set one or more ports to open"},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
parsedIntSlice = c.IntSlice("p")
|
|
||||||
parsedStringSlice = c.StringSlice("ip")
|
|
||||||
parsedOption = c.String("option")
|
|
||||||
firstArg = c.Args().First()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Commands = []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_ParseSliceFlagsWithMissingValue(t *testing.T) {
|
|
||||||
var parsedIntSlice []int
|
|
||||||
var parsedStringSlice []string
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
command := Command{
|
|
||||||
Name: "cmd",
|
|
||||||
Flags: []Flag{
|
|
||||||
IntSliceFlag{Name: "a", Usage: "set numbers"},
|
|
||||||
StringSliceFlag{Name: "str", Usage: "set strings"},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
parsedIntSlice = c.IntSlice("a")
|
|
||||||
parsedStringSlice = c.StringSlice("str")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Commands = []Command{command}
|
|
||||||
|
|
||||||
app.Run([]string{"", "cmd", "my-arg", "-a", "2", "-str", "A"})
|
|
||||||
|
|
||||||
var expectedIntSlice = []int{2}
|
|
||||||
var expectedStringSlice = []string{"A"}
|
|
||||||
|
|
||||||
if parsedIntSlice[0] != expectedIntSlice[0] {
|
|
||||||
t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
if parsedStringSlice[0] != expectedStringSlice[0] {
|
|
||||||
t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_DefaultStdout(t *testing.T) {
|
|
||||||
app := 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 := 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 := NewApp()
|
|
||||||
|
|
||||||
app.Before = func(c *Context) error {
|
|
||||||
beforeRun = true
|
|
||||||
s := c.String("opt")
|
|
||||||
if s == "fail" {
|
|
||||||
return beforeError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{
|
|
||||||
Command{
|
|
||||||
Name: "sub",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
subcommandRun = true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Flags = []Flag{
|
|
||||||
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 := NewApp()
|
|
||||||
|
|
||||||
app.After = func(c *Context) error {
|
|
||||||
afterRun = true
|
|
||||||
s := c.String("opt")
|
|
||||||
if s == "fail" {
|
|
||||||
return afterError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{
|
|
||||||
Command{
|
|
||||||
Name: "sub",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
subcommandRun = true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Flags = []Flag{
|
|
||||||
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 := HelpFlag
|
|
||||||
defer func() {
|
|
||||||
HelpFlag = oldFlag
|
|
||||||
}()
|
|
||||||
|
|
||||||
HelpFlag = BoolFlag{}
|
|
||||||
|
|
||||||
app := 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 := HelpPrinter
|
|
||||||
defer func() {
|
|
||||||
HelpPrinter = oldPrinter
|
|
||||||
}()
|
|
||||||
|
|
||||||
var wasCalled = false
|
|
||||||
HelpPrinter = func(w io.Writer, template string, data interface{}) {
|
|
||||||
wasCalled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
app := 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 := VersionPrinter
|
|
||||||
defer func() {
|
|
||||||
VersionPrinter = oldPrinter
|
|
||||||
}()
|
|
||||||
|
|
||||||
var wasCalled = false
|
|
||||||
VersionPrinter = func(c *Context) {
|
|
||||||
wasCalled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
ctx := NewContext(app, nil, nil)
|
|
||||||
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 := NewApp()
|
|
||||||
|
|
||||||
app.CommandNotFound = func(c *Context, command string) {
|
|
||||||
beforeRun = true
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{
|
|
||||||
Command{
|
|
||||||
Name: "bar",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
subcommandRun = true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run([]string{"command", "foo"})
|
|
||||||
|
|
||||||
expect(t, beforeRun, true)
|
|
||||||
expect(t, subcommandRun, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalFlag(t *testing.T) {
|
|
||||||
var globalFlag string
|
|
||||||
var globalFlagSet bool
|
|
||||||
app := NewApp()
|
|
||||||
app.Flags = []Flag{
|
|
||||||
StringFlag{Name: "global, g", Usage: "global"},
|
|
||||||
}
|
|
||||||
app.Action = func(c *Context) {
|
|
||||||
globalFlag = c.GlobalString("global")
|
|
||||||
globalFlagSet = c.GlobalIsSet("global")
|
|
||||||
}
|
|
||||||
app.Run([]string{"command", "-g", "foo"})
|
|
||||||
expect(t, globalFlag, "foo")
|
|
||||||
expect(t, globalFlagSet, true)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalFlagsInSubcommands(t *testing.T) {
|
|
||||||
subcommandRun := false
|
|
||||||
parentFlag := false
|
|
||||||
app := NewApp()
|
|
||||||
|
|
||||||
app.Flags = []Flag{
|
|
||||||
BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{
|
|
||||||
Command{
|
|
||||||
Name: "foo",
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolFlag{Name: "parent, p", Usage: "Parent flag"},
|
|
||||||
},
|
|
||||||
Subcommands: []Command{
|
|
||||||
{
|
|
||||||
Name: "bar",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
if c.GlobalBool("debug") {
|
|
||||||
subcommandRun = true
|
|
||||||
}
|
|
||||||
if c.GlobalBool("parent") {
|
|
||||||
parentFlag = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run([]string{"command", "-d", "foo", "-p", "bar"})
|
|
||||||
|
|
||||||
expect(t, subcommandRun, true)
|
|
||||||
expect(t, parentFlag, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
|
|
||||||
var subcommandHelpTopics = [][]string{
|
|
||||||
{"command", "foo", "--help"},
|
|
||||||
{"command", "foo", "-h"},
|
|
||||||
{"command", "foo", "help"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, flagSet := range subcommandHelpTopics {
|
|
||||||
t.Logf("==> checking with flags %v", flagSet)
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
app.Writer = buf
|
|
||||||
|
|
||||||
subCmdBar := Command{
|
|
||||||
Name: "bar",
|
|
||||||
Usage: "does bar things",
|
|
||||||
}
|
|
||||||
subCmdBaz := Command{
|
|
||||||
Name: "baz",
|
|
||||||
Usage: "does baz things",
|
|
||||||
}
|
|
||||||
cmd := Command{
|
|
||||||
Name: "foo",
|
|
||||||
Description: "descriptive wall of text about how it does foo things",
|
|
||||||
Subcommands: []Command{subCmdBar, subCmdBaz},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{cmd}
|
|
||||||
err := app.Run(flagSet)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output := buf.String()
|
|
||||||
t.Logf("output: %q\n", buf.Bytes())
|
|
||||||
|
|
||||||
if strings.Contains(output, "No help topic for") {
|
|
||||||
t.Errorf("expect a help topic, got none: \n%q", output)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, shouldContain := range []string{
|
|
||||||
cmd.Name, cmd.Description,
|
|
||||||
subCmdBar.Name, subCmdBar.Usage,
|
|
||||||
subCmdBaz.Name, subCmdBaz.Usage,
|
|
||||||
} {
|
|
||||||
if !strings.Contains(output, shouldContain) {
|
|
||||||
t.Errorf("want help to contain %q, did not: \n%q", shouldContain, output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_SubcommandFullPath(t *testing.T) {
|
|
||||||
app := NewApp()
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
app.Writer = buf
|
|
||||||
|
|
||||||
subCmd := Command{
|
|
||||||
Name: "bar",
|
|
||||||
Usage: "does bar things",
|
|
||||||
}
|
|
||||||
cmd := Command{
|
|
||||||
Name: "foo",
|
|
||||||
Description: "foo commands",
|
|
||||||
Subcommands: []Command{subCmd},
|
|
||||||
}
|
|
||||||
app.Commands = []Command{cmd}
|
|
||||||
|
|
||||||
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output := buf.String()
|
|
||||||
if !strings.Contains(output, "foo bar - does bar things") {
|
|
||||||
t.Errorf("expected full path to subcommand: %s", output)
|
|
||||||
}
|
|
||||||
if !strings.Contains(output, "command foo bar [arguments...]") {
|
|
||||||
t.Errorf("expected full path to subcommand: %s", output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_Help(t *testing.T) {
|
|
||||||
var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}
|
|
||||||
|
|
||||||
for _, args := range helpArguments {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
|
|
||||||
t.Logf("==> checking with arguments %v", args)
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "boom"
|
|
||||||
app.Usage = "make an explosive entrance"
|
|
||||||
app.Writer = buf
|
|
||||||
app.Action = func(c *Context) {
|
|
||||||
buf.WriteString("boom I say!")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := app.Run(args)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output := buf.String()
|
|
||||||
t.Logf("output: %q\n", buf.Bytes())
|
|
||||||
|
|
||||||
if !strings.Contains(output, "boom - make an explosive entrance") {
|
|
||||||
t.Errorf("want help to contain %q, did not: \n%q", "boom - make an explosive entrance", output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_Version(t *testing.T) {
|
|
||||||
var versionArguments = [][]string{{"boom", "--version"}, {"boom", "-v"}}
|
|
||||||
|
|
||||||
for _, args := range versionArguments {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
|
|
||||||
t.Logf("==> checking with arguments %v", args)
|
|
||||||
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "boom"
|
|
||||||
app.Usage = "make an explosive entrance"
|
|
||||||
app.Version = "0.1.0"
|
|
||||||
app.Writer = buf
|
|
||||||
app.Action = func(c *Context) {
|
|
||||||
buf.WriteString("boom I say!")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := app.Run(args)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output := buf.String()
|
|
||||||
t.Logf("output: %q\n", buf.Bytes())
|
|
||||||
|
|
||||||
if !strings.Contains(output, "0.1.0") {
|
|
||||||
t.Errorf("want version to contain %q, did not: \n%q", "0.1.0", output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
|
|
||||||
app := NewApp()
|
|
||||||
app.Action = func(c *Context) {}
|
|
||||||
app.Before = func(c *Context) error { return fmt.Errorf("before error") }
|
|
||||||
app.After = func(c *Context) error { return fmt.Errorf("after error") }
|
|
||||||
|
|
||||||
err := app.Run([]string{"foo"})
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected to recieve error from Run, got none")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), "before error") {
|
|
||||||
t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
|
|
||||||
}
|
|
||||||
if !strings.Contains(err.Error(), "after error") {
|
|
||||||
t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) {
|
|
||||||
app := NewApp()
|
|
||||||
app.Commands = []Command{
|
|
||||||
Command{
|
|
||||||
Name: "bar",
|
|
||||||
Before: func(c *Context) error { return fmt.Errorf("before error") },
|
|
||||||
After: func(c *Context) error { return fmt.Errorf("after error") },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := app.Run([]string{"foo", "bar"})
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected to recieve error from Run, got none")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), "before error") {
|
|
||||||
t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
|
|
||||||
}
|
|
||||||
if !strings.Contains(err.Error(), "after error") {
|
|
||||||
t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
|
|
||||||
}
|
|
||||||
}
|
|
98
Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go
generated
vendored
98
Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go
generated
vendored
@ -1,98 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Example() {
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "todo"
|
|
||||||
app.Usage = "task list on the command line"
|
|
||||||
app.Commands = []Command{
|
|
||||||
{
|
|
||||||
Name: "add",
|
|
||||||
Aliases: []string{"a"},
|
|
||||||
Usage: "add a task to the list",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("added task: ", c.Args().First())
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "complete",
|
|
||||||
Aliases: []string{"c"},
|
|
||||||
Usage: "complete a task on the list",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("completed task: ", c.Args().First())
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run(os.Args)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleSubcommand() {
|
|
||||||
app := NewApp()
|
|
||||||
app.Name = "say"
|
|
||||||
app.Commands = []Command{
|
|
||||||
{
|
|
||||||
Name: "hello",
|
|
||||||
Aliases: []string{"hi"},
|
|
||||||
Usage: "use it to see a description",
|
|
||||||
Description: "This is how we describe hello the function",
|
|
||||||
Subcommands: []Command{
|
|
||||||
{
|
|
||||||
Name: "english",
|
|
||||||
Aliases: []string{"en"},
|
|
||||||
Usage: "sends a greeting in english",
|
|
||||||
Description: "greets someone in english",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "Bob",
|
|
||||||
Usage: "Name of the person to greet",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("Hello, ", c.String("name"))
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "spanish",
|
|
||||||
Aliases: []string{"sp"},
|
|
||||||
Usage: "sends a greeting in spanish",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{
|
|
||||||
Name: "surname",
|
|
||||||
Value: "Jones",
|
|
||||||
Usage: "Surname of the person to greet",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("Hola, ", c.String("surname"))
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "french",
|
|
||||||
Aliases: []string{"fr"},
|
|
||||||
Usage: "sends a greeting in french",
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{
|
|
||||||
Name: "nickname",
|
|
||||||
Value: "Stevie",
|
|
||||||
Usage: "Nickname of the person to greet",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("Bonjour, ", c.String("nickname"))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "bye",
|
|
||||||
Usage: "says goodbye",
|
|
||||||
Action: func(c *Context) {
|
|
||||||
println("bye")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run(os.Args)
|
|
||||||
}
|
|
47
Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go
generated
vendored
47
Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCommandDoNotIgnoreFlags(t *testing.T) {
|
|
||||||
app := NewApp()
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
test := []string{"blah", "blah", "-break"}
|
|
||||||
set.Parse(test)
|
|
||||||
|
|
||||||
c := NewContext(app, set, nil)
|
|
||||||
|
|
||||||
command := Command{
|
|
||||||
Name: "test-cmd",
|
|
||||||
Aliases: []string{"tc"},
|
|
||||||
Usage: "this is for testing",
|
|
||||||
Description: "testing",
|
|
||||||
Action: func(_ *Context) {},
|
|
||||||
}
|
|
||||||
err := command.Run(c)
|
|
||||||
|
|
||||||
expect(t, err.Error(), "flag provided but not defined: -break")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCommandIgnoreFlags(t *testing.T) {
|
|
||||||
app := NewApp()
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
test := []string{"blah", "blah"}
|
|
||||||
set.Parse(test)
|
|
||||||
|
|
||||||
c := NewContext(app, set, nil)
|
|
||||||
|
|
||||||
command := Command{
|
|
||||||
Name: "test-cmd",
|
|
||||||
Aliases: []string{"tc"},
|
|
||||||
Usage: "this is for testing",
|
|
||||||
Description: "testing",
|
|
||||||
Action: func(_ *Context) {},
|
|
||||||
SkipFlagParsing: true,
|
|
||||||
}
|
|
||||||
err := command.Run(c)
|
|
||||||
|
|
||||||
expect(t, err, nil)
|
|
||||||
}
|
|
113
Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go
generated
vendored
113
Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go
generated
vendored
@ -1,113 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
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")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
command := Command{Name: "mycommand"}
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
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 := NewContext(nil, set, nil)
|
|
||||||
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 := NewContext(nil, set, nil)
|
|
||||||
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 := NewContext(nil, set, nil)
|
|
||||||
expect(t, c.String("myflag"), "hello world")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Bool(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
set.Bool("myflag", false, "doc")
|
|
||||||
c := NewContext(nil, set, nil)
|
|
||||||
expect(t, c.Bool("myflag"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_BoolT(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
set.Bool("myflag", true, "doc")
|
|
||||||
c := NewContext(nil, set, nil)
|
|
||||||
expect(t, c.BoolT("myflag"), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Args(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
set.Bool("myflag", false, "doc")
|
|
||||||
c := NewContext(nil, set, nil)
|
|
||||||
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")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
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")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
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")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
set.Parse([]string{"--myflag", "--otherflag=foo"})
|
|
||||||
globalSet.Parse([]string{"--myflagGlobal"})
|
|
||||||
expect(t, c.NumFlags(), 2)
|
|
||||||
}
|
|
740
Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go
generated
vendored
740
Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go
generated
vendored
@ -1,740 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var boolFlagTests = []struct {
|
|
||||||
name string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"help", "--help\t"},
|
|
||||||
{"h", "-h\t"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBoolFlagHelpOutput(t *testing.T) {
|
|
||||||
|
|
||||||
for _, test := range boolFlagTests {
|
|
||||||
flag := 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 := 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 := 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 *StringSlice
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"help", func() *StringSlice {
|
|
||||||
s := &StringSlice{}
|
|
||||||
s.Set("")
|
|
||||||
return s
|
|
||||||
}(), "--help [--help option --help option]\t"},
|
|
||||||
{"h", func() *StringSlice {
|
|
||||||
s := &StringSlice{}
|
|
||||||
s.Set("")
|
|
||||||
return s
|
|
||||||
}(), "-h [-h option -h option]\t"},
|
|
||||||
{"h", func() *StringSlice {
|
|
||||||
s := &StringSlice{}
|
|
||||||
s.Set("")
|
|
||||||
return s
|
|
||||||
}(), "-h [-h option -h option]\t"},
|
|
||||||
{"test", func() *StringSlice {
|
|
||||||
s := &StringSlice{}
|
|
||||||
s.Set("Something")
|
|
||||||
return s
|
|
||||||
}(), "--test [--test option --test option]\t"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStringSliceFlagHelpOutput(t *testing.T) {
|
|
||||||
|
|
||||||
for _, test := range stringSliceFlagTests {
|
|
||||||
flag := 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 := 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 := 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 := 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 := 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 := 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 *IntSlice
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{"help", &IntSlice{}, "--help [--help option --help option]\t"},
|
|
||||||
{"h", &IntSlice{}, "-h [-h option -h option]\t"},
|
|
||||||
{"h", &IntSlice{}, "-h [-h option -h option]\t"},
|
|
||||||
{"test", func() *IntSlice {
|
|
||||||
i := &IntSlice{}
|
|
||||||
i.Set("9")
|
|
||||||
return i
|
|
||||||
}(), "--test [--test option --test option]\t"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIntSliceFlagHelpOutput(t *testing.T) {
|
|
||||||
|
|
||||||
for _, test := range intSliceFlagTests {
|
|
||||||
flag := 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 := 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 := 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 := 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 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 := 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 := 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) {
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{Name: "serve, s"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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) {
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringSliceFlag{Name: "serve, s", Value: &StringSlice{}},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntFlag{Name: "serve, s"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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) {
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntSliceFlag{Name: "serve, s", Value: &IntSlice{}},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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")
|
|
||||||
|
|
||||||
(&App{
|
|
||||||
Flags: []Flag{
|
|
||||||
IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
Float64Flag{Name: "serve, s"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolFlag{Name: "serve, s"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolTFlag{Name: "serve, s"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
GenericFlag{Name: "serve, s", Value: &Parser{}},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *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 := App{
|
|
||||||
Flags: []Flag{
|
|
||||||
GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
|
|
||||||
},
|
|
||||||
Action: func(ctx *Context) {
|
|
||||||
if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
|
|
||||||
t.Errorf("value not set from env")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
a.Run([]string{"run"})
|
|
||||||
}
|
|
36
Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go
generated
vendored
36
Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go
generated
vendored
@ -1,36 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_ShowAppHelp_NoAuthor(t *testing.T) {
|
|
||||||
output := new(bytes.Buffer)
|
|
||||||
app := NewApp()
|
|
||||||
app.Writer = output
|
|
||||||
|
|
||||||
c := NewContext(app, nil, nil)
|
|
||||||
|
|
||||||
ShowAppHelp(c)
|
|
||||||
|
|
||||||
if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
|
|
||||||
t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ShowAppHelp_NoVersion(t *testing.T) {
|
|
||||||
output := new(bytes.Buffer)
|
|
||||||
app := NewApp()
|
|
||||||
app.Writer = output
|
|
||||||
|
|
||||||
app.Version = ""
|
|
||||||
|
|
||||||
c := NewContext(app, nil, nil)
|
|
||||||
|
|
||||||
ShowAppHelp(c)
|
|
||||||
|
|
||||||
if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 {
|
|
||||||
t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:")
|
|
||||||
}
|
|
||||||
}
|
|
19
Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go
generated
vendored
19
Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
898
Godeps/_workspace/src/github.com/fatih/structs/structs_test.go
generated
vendored
898
Godeps/_workspace/src/github.com/fatih/structs/structs_test.go
generated
vendored
@ -1,898 +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 `json:"x"`
|
|
||||||
B int `json:"y"`
|
|
||||||
C bool `json:"z"`
|
|
||||||
D struct {
|
|
||||||
E string `json:"jkl"`
|
|
||||||
} `json:"nested"`
|
|
||||||
}{
|
|
||||||
A: "a-value",
|
|
||||||
B: 2,
|
|
||||||
C: true,
|
|
||||||
}
|
|
||||||
T.D.E = "e-value"
|
|
||||||
|
|
||||||
s := New(T)
|
|
||||||
s.TagName = "json"
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nested, ok := a["nested"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("Map should contain the D field that is tagged as 'nested'")
|
|
||||||
}
|
|
||||||
|
|
||||||
e, ok := nested["jkl"].(string)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("Map should contain the D.E field that is tagged as 'jkl'")
|
|
||||||
}
|
|
||||||
|
|
||||||
if e != "e-value" {
|
|
||||||
t.Errorf("D.E field should be equal to 'e-value', got: '%v'", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 TestNames(t *testing.T) {
|
|
||||||
var T = struct {
|
|
||||||
A string
|
|
||||||
B int
|
|
||||||
C bool
|
|
||||||
}{
|
|
||||||
A: "a-value",
|
|
||||||
B: 2,
|
|
||||||
C: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
s := Names(T)
|
|
||||||
|
|
||||||
if len(s) != 3 {
|
|
||||||
t.Errorf("Names should return a slice of len 3, got: %d", len(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
inSlice := func(val string) bool {
|
|
||||||
for _, v := range s {
|
|
||||||
if reflect.DeepEqual(v, val) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, val := range []string{"A", "B", "C"} {
|
|
||||||
if !inSlice(val) {
|
|
||||||
t.Errorf("Names 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
19
Godeps/_workspace/src/github.com/gorilla/websocket/bench_test.go
generated
vendored
19
Godeps/_workspace/src/github.com/gorilla/websocket/bench_test.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
// Copyright 2014 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BenchmarkMaskBytes(b *testing.B) {
|
|
||||||
var key [4]byte
|
|
||||||
data := make([]byte, 1024)
|
|
||||||
pos := 0
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
pos = maskBytes(key, pos, data)
|
|
||||||
}
|
|
||||||
b.SetBytes(int64(len(data)))
|
|
||||||
}
|
|
323
Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
generated
vendored
323
Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
generated
vendored
@ -1,323 +0,0 @@
|
|||||||
// Copyright 2013 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var cstUpgrader = Upgrader{
|
|
||||||
Subprotocols: []string{"p0", "p1"},
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 1024,
|
|
||||||
Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
|
|
||||||
http.Error(w, reason.Error(), status)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var cstDialer = Dialer{
|
|
||||||
Subprotocols: []string{"p1", "p2"},
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 1024,
|
|
||||||
}
|
|
||||||
|
|
||||||
type cstHandler struct{ *testing.T }
|
|
||||||
|
|
||||||
type cstServer struct {
|
|
||||||
*httptest.Server
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newServer(t *testing.T) *cstServer {
|
|
||||||
var s cstServer
|
|
||||||
s.Server = httptest.NewServer(cstHandler{t})
|
|
||||||
s.URL = makeWsProto(s.Server.URL)
|
|
||||||
return &s
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTLSServer(t *testing.T) *cstServer {
|
|
||||||
var s cstServer
|
|
||||||
s.Server = httptest.NewTLSServer(cstHandler{t})
|
|
||||||
s.URL = makeWsProto(s.Server.URL)
|
|
||||||
return &s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "GET" {
|
|
||||||
t.Logf("method %s not allowed", r.Method)
|
|
||||||
http.Error(w, "method not allowed", 405)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
subprotos := Subprotocols(r)
|
|
||||||
if !reflect.DeepEqual(subprotos, cstDialer.Subprotocols) {
|
|
||||||
t.Logf("subprotols=%v, want %v", subprotos, cstDialer.Subprotocols)
|
|
||||||
http.Error(w, "bad protocol", 400)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ws, err := cstUpgrader.Upgrade(w, r, http.Header{"Set-Cookie": {"sessionID=1234"}})
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("Upgrade: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
if ws.Subprotocol() != "p1" {
|
|
||||||
t.Logf("Subprotocol() = %s, want p1", ws.Subprotocol())
|
|
||||||
ws.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
op, rd, err := ws.NextReader()
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("NextReader: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
wr, err := ws.NextWriter(op)
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("NextWriter: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(wr, rd); err != nil {
|
|
||||||
t.Logf("NextWriter: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := wr.Close(); err != nil {
|
|
||||||
t.Logf("Close: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeWsProto(s string) string {
|
|
||||||
return "ws" + strings.TrimPrefix(s, "http")
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendRecv(t *testing.T, ws *Conn) {
|
|
||||||
const message = "Hello World!"
|
|
||||||
if err := ws.SetWriteDeadline(time.Now().Add(time.Second)); err != nil {
|
|
||||||
t.Fatalf("SetWriteDeadline: %v", err)
|
|
||||||
}
|
|
||||||
if err := ws.WriteMessage(TextMessage, []byte(message)); err != nil {
|
|
||||||
t.Fatalf("WriteMessage: %v", err)
|
|
||||||
}
|
|
||||||
if err := ws.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
|
|
||||||
t.Fatalf("SetReadDeadline: %v", err)
|
|
||||||
}
|
|
||||||
_, p, err := ws.ReadMessage()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadMessage: %v", err)
|
|
||||||
}
|
|
||||||
if string(p) != message {
|
|
||||||
t.Fatalf("message=%s, want %s", p, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDial(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, _, err := cstDialer.Dial(s.URL, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Dial: %v", err)
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
sendRecv(t, ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDialTLS(t *testing.T) {
|
|
||||||
s := newTLSServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
certs := x509.NewCertPool()
|
|
||||||
for _, c := range s.TLS.Certificates {
|
|
||||||
roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("error parsing server's root cert: %v", err)
|
|
||||||
}
|
|
||||||
for _, root := range roots {
|
|
||||||
certs.AddCert(root)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u, _ := url.Parse(s.URL)
|
|
||||||
d := cstDialer
|
|
||||||
d.NetDial = func(network, addr string) (net.Conn, error) { return net.Dial(network, u.Host) }
|
|
||||||
d.TLSClientConfig = &tls.Config{RootCAs: certs}
|
|
||||||
ws, _, err := d.Dial("wss://example.com/", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Dial: %v", err)
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
sendRecv(t, ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func xTestDialTLSBadCert(t *testing.T) {
|
|
||||||
// This test is deactivated because of noisy logging from the net/http package.
|
|
||||||
s := newTLSServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, _, err := cstDialer.Dial(s.URL, nil)
|
|
||||||
if err == nil {
|
|
||||||
ws.Close()
|
|
||||||
t.Fatalf("Dial: nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func xTestDialTLSNoVerify(t *testing.T) {
|
|
||||||
s := newTLSServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
d := cstDialer
|
|
||||||
d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
||||||
ws, _, err := d.Dial(s.URL, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Dial: %v", err)
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
sendRecv(t, ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDialTimeout(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
d := cstDialer
|
|
||||||
d.HandshakeTimeout = -1
|
|
||||||
ws, _, err := d.Dial(s.URL, nil)
|
|
||||||
if err == nil {
|
|
||||||
ws.Close()
|
|
||||||
t.Fatalf("Dial: nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDialBadScheme(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, _, err := cstDialer.Dial(s.Server.URL, nil)
|
|
||||||
if err == nil {
|
|
||||||
ws.Close()
|
|
||||||
t.Fatalf("Dial: nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDialBadOrigin(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
|
|
||||||
if err == nil {
|
|
||||||
ws.Close()
|
|
||||||
t.Fatalf("Dial: nil")
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Fatalf("resp=nil, err=%v", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusForbidden {
|
|
||||||
t.Fatalf("status=%d, want %d", resp.StatusCode, http.StatusForbidden)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandshake(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {s.URL}})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Dial: %v", err)
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
var sessionID string
|
|
||||||
for _, c := range resp.Cookies() {
|
|
||||||
if c.Name == "sessionID" {
|
|
||||||
sessionID = c.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sessionID != "1234" {
|
|
||||||
t.Error("Set-Cookie not received from the server.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ws.Subprotocol() != "p1" {
|
|
||||||
t.Errorf("ws.Subprotocol() = %s, want p1", ws.Subprotocol())
|
|
||||||
}
|
|
||||||
sendRecv(t, ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRespOnBadHandshake(t *testing.T) {
|
|
||||||
const expectedStatus = http.StatusGone
|
|
||||||
const expectedBody = "This is the response body."
|
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(expectedStatus)
|
|
||||||
io.WriteString(w, expectedBody)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
ws, resp, err := cstDialer.Dial(makeWsProto(s.URL), nil)
|
|
||||||
if err == nil {
|
|
||||||
ws.Close()
|
|
||||||
t.Fatalf("Dial: nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp == nil {
|
|
||||||
t.Fatalf("resp=nil, err=%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != expectedStatus {
|
|
||||||
t.Errorf("resp.StatusCode=%d, want %d", resp.StatusCode, expectedStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadFull(resp.Body) returned error %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(p) != expectedBody {
|
|
||||||
t.Errorf("resp.Body=%s, want %s", p, expectedBody)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the Host header is specified in `Dial()`, the server must receive it as
|
|
||||||
// the `Host:` header.
|
|
||||||
func TestHostHeader(t *testing.T) {
|
|
||||||
s := newServer(t)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
specifiedHost := make(chan string, 1)
|
|
||||||
origHandler := s.Server.Config.Handler
|
|
||||||
|
|
||||||
// Capture the request Host header.
|
|
||||||
s.Server.Config.Handler = http.HandlerFunc(
|
|
||||||
func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
specifiedHost <- r.Host
|
|
||||||
origHandler.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Host": {"testhost"}})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Dial: %v", err)
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
|
||||||
t.Fatalf("resp.StatusCode = %v, want http.StatusSwitchingProtocols", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if gotHost := <-specifiedHost; gotHost != "testhost" {
|
|
||||||
t.Fatalf("gotHost = %q, want \"testhost\"", gotHost)
|
|
||||||
}
|
|
||||||
|
|
||||||
sendRecv(t, ws)
|
|
||||||
}
|
|
64
Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
generated
vendored
64
Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
generated
vendored
@ -1,64 +0,0 @@
|
|||||||
// Copyright 2014 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var parseURLTests = []struct {
|
|
||||||
s string
|
|
||||||
u *url.URL
|
|
||||||
}{
|
|
||||||
{"ws://example.com/", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}},
|
|
||||||
{"ws://example.com", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}},
|
|
||||||
{"ws://example.com:7777/", &url.URL{Scheme: "ws", Host: "example.com:7777", Opaque: "/"}},
|
|
||||||
{"wss://example.com/", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/"}},
|
|
||||||
{"wss://example.com/a/b", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/a/b"}},
|
|
||||||
{"ss://example.com/a/b", nil},
|
|
||||||
{"ws://webmaster@example.com/", nil},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseURL(t *testing.T) {
|
|
||||||
for _, tt := range parseURLTests {
|
|
||||||
u, err := parseURL(tt.s)
|
|
||||||
if tt.u != nil && err != nil {
|
|
||||||
t.Errorf("parseURL(%q) returned error %v", tt.s, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if tt.u == nil && err == nil {
|
|
||||||
t.Errorf("parseURL(%q) did not return error", tt.s)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(u, tt.u) {
|
|
||||||
t.Errorf("parseURL(%q) returned %v, want %v", tt.s, u, tt.u)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hostPortNoPortTests = []struct {
|
|
||||||
u *url.URL
|
|
||||||
hostPort, hostNoPort string
|
|
||||||
}{
|
|
||||||
{&url.URL{Scheme: "ws", Host: "example.com"}, "example.com:80", "example.com"},
|
|
||||||
{&url.URL{Scheme: "wss", Host: "example.com"}, "example.com:443", "example.com"},
|
|
||||||
{&url.URL{Scheme: "ws", Host: "example.com:7777"}, "example.com:7777", "example.com"},
|
|
||||||
{&url.URL{Scheme: "wss", Host: "example.com:7777"}, "example.com:7777", "example.com"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHostPortNoPort(t *testing.T) {
|
|
||||||
for _, tt := range hostPortNoPortTests {
|
|
||||||
hostPort, hostNoPort := hostPortNoPort(tt.u)
|
|
||||||
if hostPort != tt.hostPort {
|
|
||||||
t.Errorf("hostPortNoPort(%v) returned hostPort %q, want %q", tt.u, hostPort, tt.hostPort)
|
|
||||||
}
|
|
||||||
if hostNoPort != tt.hostNoPort {
|
|
||||||
t.Errorf("hostPortNoPort(%v) returned hostNoPort %q, want %q", tt.u, hostNoPort, tt.hostNoPort)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
241
Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
generated
vendored
241
Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
generated
vendored
@ -1,241 +0,0 @@
|
|||||||
// Copyright 2013 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"testing/iotest"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ net.Error = errWriteTimeout
|
|
||||||
|
|
||||||
type fakeNetConn struct {
|
|
||||||
io.Reader
|
|
||||||
io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c fakeNetConn) Close() error { return nil }
|
|
||||||
func (c fakeNetConn) LocalAddr() net.Addr { return nil }
|
|
||||||
func (c fakeNetConn) RemoteAddr() net.Addr { return nil }
|
|
||||||
func (c fakeNetConn) SetDeadline(t time.Time) error { return nil }
|
|
||||||
func (c fakeNetConn) SetReadDeadline(t time.Time) error { return nil }
|
|
||||||
func (c fakeNetConn) SetWriteDeadline(t time.Time) error { return nil }
|
|
||||||
|
|
||||||
func TestFraming(t *testing.T) {
|
|
||||||
frameSizes := []int{0, 1, 2, 124, 125, 126, 127, 128, 129, 65534, 65535, 65536, 65537}
|
|
||||||
var readChunkers = []struct {
|
|
||||||
name string
|
|
||||||
f func(io.Reader) io.Reader
|
|
||||||
}{
|
|
||||||
{"half", iotest.HalfReader},
|
|
||||||
{"one", iotest.OneByteReader},
|
|
||||||
{"asis", func(r io.Reader) io.Reader { return r }},
|
|
||||||
}
|
|
||||||
|
|
||||||
writeBuf := make([]byte, 65537)
|
|
||||||
for i := range writeBuf {
|
|
||||||
writeBuf[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, isServer := range []bool{true, false} {
|
|
||||||
for _, chunker := range readChunkers {
|
|
||||||
|
|
||||||
var connBuf bytes.Buffer
|
|
||||||
wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
|
|
||||||
rc := newConn(fakeNetConn{Reader: chunker.f(&connBuf), Writer: nil}, !isServer, 1024, 1024)
|
|
||||||
|
|
||||||
for _, n := range frameSizes {
|
|
||||||
for _, iocopy := range []bool{true, false} {
|
|
||||||
name := fmt.Sprintf("s:%v, r:%s, n:%d c:%v", isServer, chunker.name, n, iocopy)
|
|
||||||
|
|
||||||
w, err := wc.NextWriter(TextMessage)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: wc.NextWriter() returned %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var nn int
|
|
||||||
if iocopy {
|
|
||||||
var n64 int64
|
|
||||||
n64, err = io.Copy(w, bytes.NewReader(writeBuf[:n]))
|
|
||||||
nn = int(n64)
|
|
||||||
} else {
|
|
||||||
nn, err = w.Write(writeBuf[:n])
|
|
||||||
}
|
|
||||||
if err != nil || nn != n {
|
|
||||||
t.Errorf("%s: w.Write(writeBuf[:n]) returned %d, %v", name, nn, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = w.Close()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: w.Close() returned %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
opCode, r, err := rc.NextReader()
|
|
||||||
if err != nil || opCode != TextMessage {
|
|
||||||
t.Errorf("%s: NextReader() returned %d, r, %v", name, opCode, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rbuf, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rbuf) != n {
|
|
||||||
t.Errorf("%s: len(rbuf) is %d, want %d", name, len(rbuf), n)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, b := range rbuf {
|
|
||||||
if byte(i) != b {
|
|
||||||
t.Errorf("%s: bad byte at offset %d", name, i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestControl(t *testing.T) {
|
|
||||||
const message = "this is a ping/pong messsage"
|
|
||||||
for _, isServer := range []bool{true, false} {
|
|
||||||
for _, isWriteControl := range []bool{true, false} {
|
|
||||||
name := fmt.Sprintf("s:%v, wc:%v", isServer, isWriteControl)
|
|
||||||
var connBuf bytes.Buffer
|
|
||||||
wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
|
|
||||||
rc := newConn(fakeNetConn{Reader: &connBuf, Writer: nil}, !isServer, 1024, 1024)
|
|
||||||
if isWriteControl {
|
|
||||||
wc.WriteControl(PongMessage, []byte(message), time.Now().Add(time.Second))
|
|
||||||
} else {
|
|
||||||
w, err := wc.NextWriter(PongMessage)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: wc.NextWriter() returned %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, err := w.Write([]byte(message)); err != nil {
|
|
||||||
t.Errorf("%s: w.Write() returned %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := w.Close(); err != nil {
|
|
||||||
t.Errorf("%s: w.Close() returned %v", name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var actualMessage string
|
|
||||||
rc.SetPongHandler(func(s string) error { actualMessage = s; return nil })
|
|
||||||
rc.NextReader()
|
|
||||||
if actualMessage != message {
|
|
||||||
t.Errorf("%s: pong=%q, want %q", name, actualMessage, message)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCloseBeforeFinalFrame(t *testing.T) {
|
|
||||||
const bufSize = 512
|
|
||||||
|
|
||||||
expectedErr := &CloseError{Code: CloseNormalClosure, Text: "hello"}
|
|
||||||
|
|
||||||
var b1, b2 bytes.Buffer
|
|
||||||
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
|
|
||||||
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
|
|
||||||
|
|
||||||
w, _ := wc.NextWriter(BinaryMessage)
|
|
||||||
w.Write(make([]byte, bufSize+bufSize/2))
|
|
||||||
wc.WriteControl(CloseMessage, FormatCloseMessage(expectedErr.Code, expectedErr.Text), time.Now().Add(10*time.Second))
|
|
||||||
w.Close()
|
|
||||||
|
|
||||||
op, r, err := rc.NextReader()
|
|
||||||
if op != BinaryMessage || err != nil {
|
|
||||||
t.Fatalf("NextReader() returned %d, %v", op, err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(ioutil.Discard, r)
|
|
||||||
if !reflect.DeepEqual(err, expectedErr) {
|
|
||||||
t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
|
|
||||||
}
|
|
||||||
_, _, err = rc.NextReader()
|
|
||||||
if !reflect.DeepEqual(err, expectedErr) {
|
|
||||||
t.Fatalf("NextReader() returned %v, want %v", err, expectedErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEOFBeforeFinalFrame(t *testing.T) {
|
|
||||||
const bufSize = 512
|
|
||||||
|
|
||||||
var b1, b2 bytes.Buffer
|
|
||||||
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
|
|
||||||
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
|
|
||||||
|
|
||||||
w, _ := wc.NextWriter(BinaryMessage)
|
|
||||||
w.Write(make([]byte, bufSize+bufSize/2))
|
|
||||||
|
|
||||||
op, r, err := rc.NextReader()
|
|
||||||
if op != BinaryMessage || err != nil {
|
|
||||||
t.Fatalf("NextReader() returned %d, %v", op, err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(ioutil.Discard, r)
|
|
||||||
if err != errUnexpectedEOF {
|
|
||||||
t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
|
|
||||||
}
|
|
||||||
_, _, err = rc.NextReader()
|
|
||||||
if err != errUnexpectedEOF {
|
|
||||||
t.Fatalf("NextReader() returned %v, want %v", err, errUnexpectedEOF)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadLimit(t *testing.T) {
|
|
||||||
|
|
||||||
const readLimit = 512
|
|
||||||
message := make([]byte, readLimit+1)
|
|
||||||
|
|
||||||
var b1, b2 bytes.Buffer
|
|
||||||
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, readLimit-2)
|
|
||||||
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
|
|
||||||
rc.SetReadLimit(readLimit)
|
|
||||||
|
|
||||||
// Send message at the limit with interleaved pong.
|
|
||||||
w, _ := wc.NextWriter(BinaryMessage)
|
|
||||||
w.Write(message[:readLimit-1])
|
|
||||||
wc.WriteControl(PongMessage, []byte("this is a pong"), time.Now().Add(10*time.Second))
|
|
||||||
w.Write(message[:1])
|
|
||||||
w.Close()
|
|
||||||
|
|
||||||
// Send message larger than the limit.
|
|
||||||
wc.WriteMessage(BinaryMessage, message[:readLimit+1])
|
|
||||||
|
|
||||||
op, _, err := rc.NextReader()
|
|
||||||
if op != BinaryMessage || err != nil {
|
|
||||||
t.Fatalf("1: NextReader() returned %d, %v", op, err)
|
|
||||||
}
|
|
||||||
op, r, err := rc.NextReader()
|
|
||||||
if op != BinaryMessage || err != nil {
|
|
||||||
t.Fatalf("2: NextReader() returned %d, %v", op, err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(ioutil.Discard, r)
|
|
||||||
if err != ErrReadLimit {
|
|
||||||
t.Fatalf("io.Copy() returned %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnderlyingConn(t *testing.T) {
|
|
||||||
var b1, b2 bytes.Buffer
|
|
||||||
fc := fakeNetConn{Reader: &b1, Writer: &b2}
|
|
||||||
c := newConn(fc, true, 1024, 1024)
|
|
||||||
ul := c.UnderlyingConn()
|
|
||||||
if ul != fc {
|
|
||||||
t.Fatalf("Underlying conn is not what it should be.")
|
|
||||||
}
|
|
||||||
}
|
|
119
Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
generated
vendored
119
Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
generated
vendored
@ -1,119 +0,0 @@
|
|||||||
// Copyright 2013 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestJSON(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
c := fakeNetConn{&buf, &buf}
|
|
||||||
wc := newConn(c, true, 1024, 1024)
|
|
||||||
rc := newConn(c, false, 1024, 1024)
|
|
||||||
|
|
||||||
var actual, expect struct {
|
|
||||||
A int
|
|
||||||
B string
|
|
||||||
}
|
|
||||||
expect.A = 1
|
|
||||||
expect.B = "hello"
|
|
||||||
|
|
||||||
if err := wc.WriteJSON(&expect); err != nil {
|
|
||||||
t.Fatal("write", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rc.ReadJSON(&actual); err != nil {
|
|
||||||
t.Fatal("read", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(&actual, &expect) {
|
|
||||||
t.Fatal("equal", actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPartialJSONRead(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
c := fakeNetConn{&buf, &buf}
|
|
||||||
wc := newConn(c, true, 1024, 1024)
|
|
||||||
rc := newConn(c, false, 1024, 1024)
|
|
||||||
|
|
||||||
var v struct {
|
|
||||||
A int
|
|
||||||
B string
|
|
||||||
}
|
|
||||||
v.A = 1
|
|
||||||
v.B = "hello"
|
|
||||||
|
|
||||||
messageCount := 0
|
|
||||||
|
|
||||||
// Partial JSON values.
|
|
||||||
|
|
||||||
data, err := json.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i := len(data) - 1; i >= 0; i-- {
|
|
||||||
if err := wc.WriteMessage(TextMessage, data[:i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
messageCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whitespace.
|
|
||||||
|
|
||||||
if err := wc.WriteMessage(TextMessage, []byte(" ")); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
messageCount++
|
|
||||||
|
|
||||||
// Close.
|
|
||||||
|
|
||||||
if err := wc.WriteMessage(CloseMessage, FormatCloseMessage(CloseNormalClosure, "")); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < messageCount; i++ {
|
|
||||||
err := rc.ReadJSON(&v)
|
|
||||||
if err != io.ErrUnexpectedEOF {
|
|
||||||
t.Error("read", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = rc.ReadJSON(&v)
|
|
||||||
if _, ok := err.(*CloseError); !ok {
|
|
||||||
t.Error("final", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeprecatedJSON(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
c := fakeNetConn{&buf, &buf}
|
|
||||||
wc := newConn(c, true, 1024, 1024)
|
|
||||||
rc := newConn(c, false, 1024, 1024)
|
|
||||||
|
|
||||||
var actual, expect struct {
|
|
||||||
A int
|
|
||||||
B string
|
|
||||||
}
|
|
||||||
expect.A = 1
|
|
||||||
expect.B = "hello"
|
|
||||||
|
|
||||||
if err := WriteJSON(wc, &expect); err != nil {
|
|
||||||
t.Fatal("write", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ReadJSON(rc, &actual); err != nil {
|
|
||||||
t.Fatal("read", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(&actual, &expect) {
|
|
||||||
t.Fatal("equal", actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
33
Godeps/_workspace/src/github.com/gorilla/websocket/server_test.go
generated
vendored
33
Godeps/_workspace/src/github.com/gorilla/websocket/server_test.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2013 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var subprotocolTests = []struct {
|
|
||||||
h string
|
|
||||||
protocols []string
|
|
||||||
}{
|
|
||||||
{"", nil},
|
|
||||||
{"foo", []string{"foo"}},
|
|
||||||
{"foo,bar", []string{"foo", "bar"}},
|
|
||||||
{"foo, bar", []string{"foo", "bar"}},
|
|
||||||
{" foo, bar", []string{"foo", "bar"}},
|
|
||||||
{" foo, bar ", []string{"foo", "bar"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSubprotocols(t *testing.T) {
|
|
||||||
for _, st := range subprotocolTests {
|
|
||||||
r := http.Request{Header: http.Header{"Sec-Websocket-Protocol": {st.h}}}
|
|
||||||
protocols := Subprotocols(&r)
|
|
||||||
if !reflect.DeepEqual(st.protocols, protocols) {
|
|
||||||
t.Errorf("SubProtocols(%q) returned %#v, want %#v", st.h, protocols, st.protocols)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
34
Godeps/_workspace/src/github.com/gorilla/websocket/util_test.go
generated
vendored
34
Godeps/_workspace/src/github.com/gorilla/websocket/util_test.go
generated
vendored
@ -1,34 +0,0 @@
|
|||||||
// Copyright 2014 The Gorilla WebSocket 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 websocket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var tokenListContainsValueTests = []struct {
|
|
||||||
value string
|
|
||||||
ok bool
|
|
||||||
}{
|
|
||||||
{"WebSocket", true},
|
|
||||||
{"WEBSOCKET", true},
|
|
||||||
{"websocket", true},
|
|
||||||
{"websockets", false},
|
|
||||||
{"x websocket", false},
|
|
||||||
{"websocket x", false},
|
|
||||||
{"other,websocket,more", true},
|
|
||||||
{"other, websocket, more", true},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTokenListContainsValue(t *testing.T) {
|
|
||||||
for _, tt := range tokenListContainsValueTests {
|
|
||||||
h := http.Header{"Upgrade": {tt.value}}
|
|
||||||
ok := tokenListContainsValue(h, "Upgrade", "websocket")
|
|
||||||
if ok != tt.ok {
|
|
||||||
t.Errorf("tokenListContainsValue(h, n, %q) = %v, want %v", tt.value, ok, tt.ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
45
Godeps/_workspace/src/github.com/hashicorp/go-multierror/append_test.go
generated
vendored
45
Godeps/_workspace/src/github.com/hashicorp/go-multierror/append_test.go
generated
vendored
@ -1,45 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAppend_Error(t *testing.T) {
|
|
||||||
original := &Error{
|
|
||||||
Errors: []error{errors.New("foo")},
|
|
||||||
}
|
|
||||||
|
|
||||||
result := Append(original, errors.New("bar"))
|
|
||||||
if len(result.Errors) != 2 {
|
|
||||||
t.Fatalf("wrong len: %d", len(result.Errors))
|
|
||||||
}
|
|
||||||
|
|
||||||
original = &Error{}
|
|
||||||
result = Append(original, errors.New("bar"))
|
|
||||||
if len(result.Errors) != 1 {
|
|
||||||
t.Fatalf("wrong len: %d", len(result.Errors))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test when a typed nil is passed
|
|
||||||
var e *Error
|
|
||||||
result = Append(e, errors.New("baz"))
|
|
||||||
if len(result.Errors) != 1 {
|
|
||||||
t.Fatalf("wrong len: %d", len(result.Errors))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppend_NilError(t *testing.T) {
|
|
||||||
var err error
|
|
||||||
result := Append(err, errors.New("bar"))
|
|
||||||
if len(result.Errors) != 1 {
|
|
||||||
t.Fatalf("wrong len: %d", len(result.Errors))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestAppend_NonError(t *testing.T) {
|
|
||||||
original := errors.New("foo")
|
|
||||||
result := Append(original, errors.New("bar"))
|
|
||||||
if len(result.Errors) != 2 {
|
|
||||||
t.Fatalf("wrong len: %d", len(result.Errors))
|
|
||||||
}
|
|
||||||
}
|
|
48
Godeps/_workspace/src/github.com/hashicorp/go-multierror/flatten_test.go
generated
vendored
48
Godeps/_workspace/src/github.com/hashicorp/go-multierror/flatten_test.go
generated
vendored
@ -1,48 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFlatten(t *testing.T) {
|
|
||||||
original := &Error{
|
|
||||||
Errors: []error{
|
|
||||||
errors.New("one"),
|
|
||||||
&Error{
|
|
||||||
Errors: []error{
|
|
||||||
errors.New("two"),
|
|
||||||
&Error{
|
|
||||||
Errors: []error{
|
|
||||||
errors.New("three"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := strings.TrimSpace(`
|
|
||||||
3 error(s) occurred:
|
|
||||||
|
|
||||||
* one
|
|
||||||
* two
|
|
||||||
* three
|
|
||||||
`)
|
|
||||||
actual := fmt.Sprintf("%s", Flatten(original))
|
|
||||||
|
|
||||||
if expected != actual {
|
|
||||||
t.Fatalf("expected: %s, got: %s", expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFlatten_nonError(t *testing.T) {
|
|
||||||
err := errors.New("foo")
|
|
||||||
actual := Flatten(err)
|
|
||||||
if !reflect.DeepEqual(actual, err) {
|
|
||||||
t.Fatalf("bad: %#v", actual)
|
|
||||||
}
|
|
||||||
}
|
|
23
Godeps/_workspace/src/github.com/hashicorp/go-multierror/format_test.go
generated
vendored
23
Godeps/_workspace/src/github.com/hashicorp/go-multierror/format_test.go
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestListFormatFunc(t *testing.T) {
|
|
||||||
expected := `2 error(s) occurred:
|
|
||||||
|
|
||||||
* foo
|
|
||||||
* bar`
|
|
||||||
|
|
||||||
errors := []error{
|
|
||||||
errors.New("foo"),
|
|
||||||
errors.New("bar"),
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := ListFormatFunc(errors)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad: %#v", actual)
|
|
||||||
}
|
|
||||||
}
|
|
70
Godeps/_workspace/src/github.com/hashicorp/go-multierror/multierror_test.go
generated
vendored
70
Godeps/_workspace/src/github.com/hashicorp/go-multierror/multierror_test.go
generated
vendored
@ -1,70 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestError_Impl(t *testing.T) {
|
|
||||||
var _ error = new(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorError_custom(t *testing.T) {
|
|
||||||
errors := []error{
|
|
||||||
errors.New("foo"),
|
|
||||||
errors.New("bar"),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn := func(es []error) string {
|
|
||||||
return "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
multi := &Error{Errors: errors, ErrorFormat: fn}
|
|
||||||
if multi.Error() != "foo" {
|
|
||||||
t.Fatalf("bad: %s", multi.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorError_default(t *testing.T) {
|
|
||||||
expected := `2 error(s) occurred:
|
|
||||||
|
|
||||||
* foo
|
|
||||||
* bar`
|
|
||||||
|
|
||||||
errors := []error{
|
|
||||||
errors.New("foo"),
|
|
||||||
errors.New("bar"),
|
|
||||||
}
|
|
||||||
|
|
||||||
multi := &Error{Errors: errors}
|
|
||||||
if multi.Error() != expected {
|
|
||||||
t.Fatalf("bad: %s", multi.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorErrorOrNil(t *testing.T) {
|
|
||||||
err := new(Error)
|
|
||||||
if err.ErrorOrNil() != nil {
|
|
||||||
t.Fatalf("bad: %#v", err.ErrorOrNil())
|
|
||||||
}
|
|
||||||
|
|
||||||
err.Errors = []error{errors.New("foo")}
|
|
||||||
if v := err.ErrorOrNil(); v == nil {
|
|
||||||
t.Fatal("should not be nil")
|
|
||||||
} else if !reflect.DeepEqual(v, err) {
|
|
||||||
t.Fatalf("bad: %#v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorWrappedErrors(t *testing.T) {
|
|
||||||
errors := []error{
|
|
||||||
errors.New("foo"),
|
|
||||||
errors.New("bar"),
|
|
||||||
}
|
|
||||||
|
|
||||||
multi := &Error{Errors: errors}
|
|
||||||
if !reflect.DeepEqual(multi.Errors, multi.WrappedErrors()) {
|
|
||||||
t.Fatalf("bad: %s", multi.WrappedErrors())
|
|
||||||
}
|
|
||||||
}
|
|
481
Godeps/_workspace/src/github.com/yudai/hcl/decoder_test.go
generated
vendored
481
Godeps/_workspace/src/github.com/yudai/hcl/decoder_test.go
generated
vendored
@ -1,481 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDecode_interface(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
File string
|
|
||||||
Err bool
|
|
||||||
Out interface{}
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"basic.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
"bar": "${file(\"bing/bong.txt\")}",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"basic_squish.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
"bar": "${file(\"bing/bong.txt\")}",
|
|
||||||
"foo-bar": "baz",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"empty.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"resource": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []map[string]interface{}{
|
|
||||||
map[string]interface{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"escape.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": "bar\"baz\\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"float.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"a": 1.02,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"multiline_bad.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{"foo": "bar\nbaz\n"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"multiline.json",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{"foo": "bar\nbaz"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"scientific.json",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"a": 1e-10,
|
|
||||||
"b": 1e+10,
|
|
||||||
"c": 1e10,
|
|
||||||
"d": 1.2e-10,
|
|
||||||
"e": 1.2e+10,
|
|
||||||
"f": 1.2e10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"scientific.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"a": 1e-10,
|
|
||||||
"b": 1e+10,
|
|
||||||
"c": 1e10,
|
|
||||||
"d": 1.2e-10,
|
|
||||||
"e": 1.2e+10,
|
|
||||||
"f": 1.2e10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"terraform_heroku.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"name": "terraform-test-app",
|
|
||||||
"config_vars": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"FOO": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_multi.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"baz": []map[string]interface{}{
|
|
||||||
map[string]interface{}{"key": 7},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"bar": []map[string]interface{}{
|
|
||||||
map[string]interface{}{"key": 12},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_multi.json",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"baz": []map[string]interface{}{
|
|
||||||
map[string]interface{}{"key": 7},
|
|
||||||
},
|
|
||||||
"bar": []map[string]interface{}{
|
|
||||||
map[string]interface{}{"key": 12},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_list.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"key": 7,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"key": 12,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_list.json",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"key": 7,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"key": 12,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_list_deep.json",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"bar": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"foo": []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"name": "terraform_example",
|
|
||||||
"ingress": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"from_port": 22,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"from_port": 80,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"nested_block_comment.hcl",
|
|
||||||
false,
|
|
||||||
map[string]interface{}{
|
|
||||||
"bar": "value",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"unterminated_block_comment.hcl",
|
|
||||||
true,
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.File))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var out interface{}
|
|
||||||
err = Decode(&out, string(d))
|
|
||||||
if (err != nil) != tc.Err {
|
|
||||||
t.Fatalf("Input: %s\n\nError: %s", tc.File, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(out, tc.Out) {
|
|
||||||
t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", tc.File, out, tc.Out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_equal(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
One, Two string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"basic.hcl",
|
|
||||||
"basic.json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"float.hcl",
|
|
||||||
"float.json",
|
|
||||||
},
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
"structure.hcl",
|
|
||||||
"structure.json",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"structure.hcl",
|
|
||||||
"structure_flat.json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"terraform_heroku.hcl",
|
|
||||||
"terraform_heroku.json",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
p1 := filepath.Join(fixtureDir, tc.One)
|
|
||||||
p2 := filepath.Join(fixtureDir, tc.Two)
|
|
||||||
|
|
||||||
d1, err := ioutil.ReadFile(p1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d2, err := ioutil.ReadFile(p2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var i1, i2 interface{}
|
|
||||||
err = Decode(&i1, string(d1))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = Decode(&i2, string(d2))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(i1, i2) {
|
|
||||||
t.Fatalf(
|
|
||||||
"%s != %s\n\n%#v\n\n%#v",
|
|
||||||
tc.One, tc.Two,
|
|
||||||
i1, i2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_flatMap(t *testing.T) {
|
|
||||||
var val map[string]map[string]string
|
|
||||||
|
|
||||||
err := Decode(&val, testReadFile(t, "structure_flatmap.hcl"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := map[string]map[string]string{
|
|
||||||
"foo": map[string]string{
|
|
||||||
"foo": "bar",
|
|
||||||
"key": "7",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(val, expected) {
|
|
||||||
t.Fatalf("Actual: %#v\n\nExpected: %#v", val, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_structure(t *testing.T) {
|
|
||||||
type V struct {
|
|
||||||
Key int
|
|
||||||
Foo string
|
|
||||||
}
|
|
||||||
|
|
||||||
var actual V
|
|
||||||
|
|
||||||
err := Decode(&actual, testReadFile(t, "flat.hcl"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := V{
|
|
||||||
Key: 7,
|
|
||||||
Foo: "bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_structurePtr(t *testing.T) {
|
|
||||||
type V struct {
|
|
||||||
Key int
|
|
||||||
Foo string
|
|
||||||
}
|
|
||||||
|
|
||||||
var actual *V
|
|
||||||
|
|
||||||
err := Decode(&actual, testReadFile(t, "flat.hcl"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := &V{
|
|
||||||
Key: 7,
|
|
||||||
Foo: "bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_structureArray(t *testing.T) {
|
|
||||||
// This test is extracted from a failure in Consul (consul.io),
|
|
||||||
// hence the interesting structure naming.
|
|
||||||
|
|
||||||
type KeyPolicyType string
|
|
||||||
|
|
||||||
type KeyPolicy struct {
|
|
||||||
Prefix string `hcl:",key"`
|
|
||||||
Policy KeyPolicyType
|
|
||||||
}
|
|
||||||
|
|
||||||
type Policy struct {
|
|
||||||
Keys []KeyPolicy `hcl:"key,expand"`
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := Policy{
|
|
||||||
Keys: []KeyPolicy{
|
|
||||||
KeyPolicy{
|
|
||||||
Prefix: "",
|
|
||||||
Policy: "read",
|
|
||||||
},
|
|
||||||
KeyPolicy{
|
|
||||||
Prefix: "foo/",
|
|
||||||
Policy: "write",
|
|
||||||
},
|
|
||||||
KeyPolicy{
|
|
||||||
Prefix: "foo/bar/",
|
|
||||||
Policy: "read",
|
|
||||||
},
|
|
||||||
KeyPolicy{
|
|
||||||
Prefix: "foo/bar/baz",
|
|
||||||
Policy: "deny",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
files := []string{
|
|
||||||
"decode_policy.hcl",
|
|
||||||
"decode_policy.json",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range files {
|
|
||||||
var actual Policy
|
|
||||||
|
|
||||||
err := Decode(&actual, testReadFile(t, f))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_structureMap(t *testing.T) {
|
|
||||||
// This test is extracted from a failure in Terraform (terraform.io),
|
|
||||||
// hence the interesting structure naming.
|
|
||||||
|
|
||||||
type hclVariable struct {
|
|
||||||
Default interface{}
|
|
||||||
Description string
|
|
||||||
Fields []string `hcl:",decodedFields"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type rawConfig struct {
|
|
||||||
Variable map[string]hclVariable
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := rawConfig{
|
|
||||||
Variable: map[string]hclVariable{
|
|
||||||
"foo": hclVariable{
|
|
||||||
Default: "bar",
|
|
||||||
Description: "bar",
|
|
||||||
Fields: []string{"Default", "Description"},
|
|
||||||
},
|
|
||||||
|
|
||||||
"amis": hclVariable{
|
|
||||||
Default: []map[string]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"east": "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Fields: []string{"Default"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
files := []string{
|
|
||||||
"decode_tf_variable.hcl",
|
|
||||||
"decode_tf_variable.json",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range files {
|
|
||||||
var actual rawConfig
|
|
||||||
|
|
||||||
err := Decode(&actual, testReadFile(t, f))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Input: %s\n\nerr: %s", f, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_interfaceNonPointer(t *testing.T) {
|
|
||||||
var value interface{}
|
|
||||||
err := Decode(value, testReadFile(t, "basic_int_string.hcl"))
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("should error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode_intString(t *testing.T) {
|
|
||||||
var value struct {
|
|
||||||
Count int
|
|
||||||
}
|
|
||||||
|
|
||||||
err := Decode(&value, testReadFile(t, "basic_int_string.hcl"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.Count != 3 {
|
|
||||||
t.Fatalf("bad: %#v", value.Count)
|
|
||||||
}
|
|
||||||
}
|
|
BIN
Godeps/_workspace/src/github.com/yudai/hcl/hcl/hcl.test
generated
vendored
BIN
Godeps/_workspace/src/github.com/yudai/hcl/hcl/hcl.test
generated
vendored
Binary file not shown.
4
Godeps/_workspace/src/github.com/yudai/hcl/hcl/hcl_test.go
generated
vendored
4
Godeps/_workspace/src/github.com/yudai/hcl/hcl/hcl_test.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
// This is the directory where our test fixtures are.
|
|
||||||
const fixtureDir = "./test-fixtures"
|
|
113
Godeps/_workspace/src/github.com/yudai/hcl/hcl/lex_test.go
generated
vendored
113
Godeps/_workspace/src/github.com/yudai/hcl/hcl/lex_test.go
generated
vendored
@ -1,113 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLex(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Input string
|
|
||||||
Output []int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"comment.hcl",
|
|
||||||
[]int{IDENTIFIER, EQUAL, STRING, lexEOF},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment_single.hcl",
|
|
||||||
[]int{lexEOF},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"complex_key.hcl",
|
|
||||||
[]int{IDENTIFIER, EQUAL, STRING, lexEOF},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"multiple.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, EQUAL, STRING,
|
|
||||||
IDENTIFIER, EQUAL, NUMBER,
|
|
||||||
lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"list.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, EQUAL, LEFTBRACKET,
|
|
||||||
NUMBER, COMMA, NUMBER, COMMA, STRING, COMMA, BOOL,
|
|
||||||
RIGHTBRACKET, lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"old.hcl",
|
|
||||||
[]int{IDENTIFIER, EQUAL, LEFTBRACE, STRING, lexEOF},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_basic.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, LEFTBRACE,
|
|
||||||
IDENTIFIER, EQUAL, NUMBER,
|
|
||||||
STRING, EQUAL, NUMBER,
|
|
||||||
STRING, EQUAL, NUMBER,
|
|
||||||
RIGHTBRACE, lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, IDENTIFIER, STRING, LEFTBRACE,
|
|
||||||
IDENTIFIER, EQUAL, NUMBER,
|
|
||||||
IDENTIFIER, EQUAL, STRING,
|
|
||||||
RIGHTBRACE, lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"array_comment.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, EQUAL, LEFTBRACKET,
|
|
||||||
STRING, COMMA,
|
|
||||||
STRING, COMMA,
|
|
||||||
RIGHTBRACKET, lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"null.hcl",
|
|
||||||
[]int{
|
|
||||||
IDENTIFIER, EQUAL, NULL,
|
|
||||||
IDENTIFIER, EQUAL, LEFTBRACKET, NUMBER, COMMA, NULL, COMMA, NUMBER, RIGHTBRACKET,
|
|
||||||
IDENTIFIER, LEFTBRACE, IDENTIFIER, EQUAL, NULL, RIGHTBRACE,
|
|
||||||
lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Input))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l := &hclLex{Input: string(d)}
|
|
||||||
var actual []int
|
|
||||||
for {
|
|
||||||
token := l.Lex(new(hclSymType))
|
|
||||||
actual = append(actual, token)
|
|
||||||
|
|
||||||
if token == lexEOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(actual) > 500 {
|
|
||||||
t.Fatalf("Input:%s\n\nExausted.", tc.Input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, tc.Output) {
|
|
||||||
t.Fatalf(
|
|
||||||
"Input: %s\n\nBad: %#v\n\nExpected: %#v",
|
|
||||||
tc.Input, actual, tc.Output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
83
Godeps/_workspace/src/github.com/yudai/hcl/hcl/parse_test.go
generated
vendored
83
Godeps/_workspace/src/github.com/yudai/hcl/hcl/parse_test.go
generated
vendored
@ -1,83 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Name string
|
|
||||||
Err bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"assign_colon.hcl",
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment_single.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"empty.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"list_comma.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"multiple.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_basic.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"structure_empty.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"complex.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"assign_deep.hcl",
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"types.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"array_comment.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"null.hcl",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Name))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = Parse(string(d))
|
|
||||||
if (err != nil) != tc.Err {
|
|
||||||
t.Fatalf("Input: %s\n\nError: %s", tc.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
19
Godeps/_workspace/src/github.com/yudai/hcl/hcl_test.go
generated
vendored
19
Godeps/_workspace/src/github.com/yudai/hcl/hcl_test.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is the directory where our test fixtures are.
|
|
||||||
const fixtureDir = "./test-fixtures"
|
|
||||||
|
|
||||||
func testReadFile(t *testing.T, n string) string {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, n))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(d)
|
|
||||||
}
|
|
4
Godeps/_workspace/src/github.com/yudai/hcl/json/json_test.go
generated
vendored
4
Godeps/_workspace/src/github.com/yudai/hcl/json/json_test.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
// This is the directory where our test fixtures are.
|
|
||||||
const fixtureDir = "./test-fixtures"
|
|
78
Godeps/_workspace/src/github.com/yudai/hcl/json/lex_test.go
generated
vendored
78
Godeps/_workspace/src/github.com/yudai/hcl/json/lex_test.go
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLexJson(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Input string
|
|
||||||
Output []int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"basic.json",
|
|
||||||
[]int{
|
|
||||||
LEFTBRACE,
|
|
||||||
STRING, COLON, STRING,
|
|
||||||
RIGHTBRACE,
|
|
||||||
lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"array.json",
|
|
||||||
[]int{
|
|
||||||
LEFTBRACE,
|
|
||||||
STRING, COLON, LEFTBRACKET,
|
|
||||||
NUMBER, COMMA, NUMBER, COMMA, STRING,
|
|
||||||
RIGHTBRACKET, COMMA,
|
|
||||||
STRING, COLON, STRING,
|
|
||||||
RIGHTBRACE,
|
|
||||||
lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"object.json",
|
|
||||||
[]int{
|
|
||||||
LEFTBRACE,
|
|
||||||
STRING, COLON, LEFTBRACE,
|
|
||||||
STRING, COLON, LEFTBRACKET,
|
|
||||||
NUMBER, COMMA, NUMBER,
|
|
||||||
RIGHTBRACKET,
|
|
||||||
RIGHTBRACE,
|
|
||||||
RIGHTBRACE,
|
|
||||||
lexEOF,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Input))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l := &jsonLex{Input: string(d)}
|
|
||||||
var actual []int
|
|
||||||
for {
|
|
||||||
token := l.Lex(new(jsonSymType))
|
|
||||||
actual = append(actual, token)
|
|
||||||
|
|
||||||
if token == lexEOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(actual) > 500 {
|
|
||||||
t.Fatalf("Input:%s\n\nExausted.", tc.Input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, tc.Output) {
|
|
||||||
t.Fatalf(
|
|
||||||
"Input: %s\n\nBad: %#v\n\nExpected: %#v",
|
|
||||||
tc.Input, actual, tc.Output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
43
Godeps/_workspace/src/github.com/yudai/hcl/json/parse_test.go
generated
vendored
43
Godeps/_workspace/src/github.com/yudai/hcl/json/parse_test.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Name string
|
|
||||||
Err bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"basic.json",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"object.json",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"array.json",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"types.json",
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.Name))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = Parse(string(d))
|
|
||||||
if (err != nil) != tc.Err {
|
|
||||||
t.Fatalf("Input: %s\n\nError: %s", tc.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
37
Godeps/_workspace/src/github.com/yudai/hcl/lex_test.go
generated
vendored
37
Godeps/_workspace/src/github.com/yudai/hcl/lex_test.go
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
package hcl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLexMode(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Input string
|
|
||||||
Mode lexModeValue
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"",
|
|
||||||
lexModeHcl,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo",
|
|
||||||
lexModeHcl,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"{}",
|
|
||||||
lexModeJson,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
" {}",
|
|
||||||
lexModeJson,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, tc := range cases {
|
|
||||||
actual := lexMode(tc.Input)
|
|
||||||
|
|
||||||
if actual != tc.Mode {
|
|
||||||
t.Fatalf("%d: %#v", i, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
50
Godeps/_workspace/src/github.com/yudai/umutex/umutex_test.go
generated
vendored
50
Godeps/_workspace/src/github.com/yudai/umutex/umutex_test.go
generated
vendored
@ -1,50 +0,0 @@
|
|||||||
package umutex
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTryLock(t *testing.T) {
|
|
||||||
var result bool
|
|
||||||
|
|
||||||
mutex := New()
|
|
||||||
|
|
||||||
result = mutex.TryLock()
|
|
||||||
if result != true {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
result = mutex.TryLock()
|
|
||||||
if result != false {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex.Unlock()
|
|
||||||
|
|
||||||
result = mutex.TryLock()
|
|
||||||
if result != true {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForceLock(t *testing.T) {
|
|
||||||
var result bool
|
|
||||||
|
|
||||||
mutex := New()
|
|
||||||
|
|
||||||
result = mutex.TryLock()
|
|
||||||
if result != true {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
mutex.ForceLock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
mutex.Unlock()
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user