From 6366acc45f228c07d66c0fffd5ba861099ec21ee Mon Sep 17 00:00:00 2001 From: nicerobot Date: Fri, 28 Oct 2016 21:36:45 -0700 Subject: [PATCH] +start graphql servicer. +separate route registry. --- vendor/application/route_login.go | 30 ++ vendor/application/route_query.go | 31 ++ vendor/application/route_starwars.go | 31 ++ vendor/application/route_tests.go | 67 +++ vendor/application/routes.go | 86 +--- vendor/application/start.go | 4 +- .../vendor/middleware/logging/logging.go | 11 +- .../vendor/service/query/README.md | 0 .../application/vendor/service/query/query.go | 86 ++++ .../vendor/service/query/query_test.go | 13 + .../vendor/service/starwars/README.md | 0 .../vendor/service/starwars/service.go | 86 ++++ .../vendor/service/starwars/starwars.go | 464 ++++++++++++++++++ .../vendor/service/starwars/starwars_test.go | 13 + 14 files changed, 839 insertions(+), 83 deletions(-) create mode 100644 vendor/application/route_login.go create mode 100644 vendor/application/route_query.go create mode 100644 vendor/application/route_starwars.go create mode 100644 vendor/application/route_tests.go create mode 100644 vendor/application/vendor/service/query/README.md create mode 100644 vendor/application/vendor/service/query/query.go create mode 100644 vendor/application/vendor/service/query/query_test.go create mode 100644 vendor/application/vendor/service/starwars/README.md create mode 100644 vendor/application/vendor/service/starwars/service.go create mode 100644 vendor/application/vendor/service/starwars/starwars.go create mode 100644 vendor/application/vendor/service/starwars/starwars_test.go diff --git a/vendor/application/route_login.go b/vendor/application/route_login.go new file mode 100644 index 0000000..257e408 --- /dev/null +++ b/vendor/application/route_login.go @@ -0,0 +1,30 @@ +package application + +import ( + "middleware/logging" + "service/login" + + "github.com/gorilla/mux" + + httptransport "github.com/go-kit/kit/transport/http" + + "golang.org/x/net/context" +) + +// +func routeLoginService(ctx context.Context, r *mux.Router) { + + logged := logging.New("login", Settings.Program.Name).Middleware() + + loginService := login.New() + + // POST / + + r.Methods("POST").Path("/").Handler(httptransport.NewServer( + ctx, + logged(loginService.Endpoint()), + loginService.Decoder, + servered(jsoned(loginService.Encoder)), + )).Name("POST") + +} diff --git a/vendor/application/route_query.go b/vendor/application/route_query.go new file mode 100644 index 0000000..43fa6fb --- /dev/null +++ b/vendor/application/route_query.go @@ -0,0 +1,31 @@ +package application + +import ( + "middleware/logging" + "service/query" + "transport/http/caching" + + "github.com/gorilla/mux" + + httptransport "github.com/go-kit/kit/transport/http" + + "golang.org/x/net/context" +) + +// +func routeQueryService(ctx context.Context, r *mux.Router) { + + logged := logging.New("query", Settings.Program.Name).Middleware() + + queryService := query.New() + + // GET /:id + + r.Methods("GET").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( + ctx, + logged(queryService.Endpoint()), + queryService.Decoder, + servered(jsoned(queryService.Encoder)), + ))).Name("GET Id") + +} diff --git a/vendor/application/route_starwars.go b/vendor/application/route_starwars.go new file mode 100644 index 0000000..2be1453 --- /dev/null +++ b/vendor/application/route_starwars.go @@ -0,0 +1,31 @@ +package application + +import ( + "middleware/logging" + "service/starwars" + "transport/http/caching" + + "github.com/gorilla/mux" + + httptransport "github.com/go-kit/kit/transport/http" + + "golang.org/x/net/context" +) + +// +func routeStarWarsService(ctx context.Context, r *mux.Router) { + + logged := logging.New("starwars", Settings.Program.Name).Middleware() + + starWarsService := starwars.New() + + // GET /:query + + r.Methods("GET").Path("/{query}").Handler(caching.New(-1, httptransport.NewServer( + ctx, + logged(starWarsService.Endpoint()), + starWarsService.Decoder, + servered(jsoned(starWarsService.Encoder)), + ))).Name("GET Id") + +} diff --git a/vendor/application/route_tests.go b/vendor/application/route_tests.go new file mode 100644 index 0000000..680b09a --- /dev/null +++ b/vendor/application/route_tests.go @@ -0,0 +1,67 @@ +package application + +import ( + "middleware/logging" + "service/testing" + "transport/http/caching" + + "github.com/gorilla/mux" + + httptransport "github.com/go-kit/kit/transport/http" + + "golang.org/x/net/context" +) + +// +func routeTestService(ctx context.Context, r *mux.Router) { + + logged := logging.New("test", Settings.Program.Name).Middleware() + + testService := testing.New() + + // POST / + + r.Methods("POST").Path("/").Handler(httptransport.NewServer( + ctx, + logged(testService.Post()), + testService.DecodePost, + servered(jsoned(testService.EncodePost)), + )).Name("POST") + + // GET /:id + + r.Methods("POST", "GET").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( + ctx, + logged(testService.Get()), + testService.DecodeGet, + servered(jsoned(testService.EncodeGet)), + ))).Name("GET/POST Id") + + // PUT /:id + + r.Methods("PUT").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( + ctx, + logged(testService.Put()), + testService.DecodePut, + servered(jsoned(testService.EncodePut)), + ))).Name("PUT Id") + + // PATCH /:id + + r.Methods("PATCH").Path("/{id}").Handler(httptransport.NewServer( + ctx, + logged(testService.Patch()), + testService.DecodePatch, + servered(jsoned(testService.EncodePatch)), + )).Name("PATCH Id") + + // DELETE /:id + + r.Methods("DELETE").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( + ctx, + logged(testService.Delete()), + testService.DecodeDelete, + servered(jsoned(testService.EncodeDelete)), + ))).Name("DELETE Id") + +} diff --git a/vendor/application/routes.go b/vendor/application/routes.go index cbf6e30..9ee02a6 100644 --- a/vendor/application/routes.go +++ b/vendor/application/routes.go @@ -1,17 +1,11 @@ package application import ( - "middleware/logging" "net/http" - "service/login" - "service/testing" - "transport/http/caching" "transport/http/headered" "github.com/gorilla/mux" - httptransport "github.com/go-kit/kit/transport/http" - "golang.org/x/net/context" ) @@ -24,6 +18,14 @@ func routeServices() *mux.Router { routeLoginService(ctx, r.PathPrefix("/login").Subrouter().StrictSlash(true)) + // Query + + routeQueryService(ctx, r.PathPrefix("/query").Subrouter().StrictSlash(true)) + + // StarWars + + routeStarWarsService(ctx, r.PathPrefix("/starwars").Subrouter().StrictSlash(true)) + // Testing routeTestService(ctx, r.PathPrefix("/test").Subrouter().StrictSlash(true)) @@ -40,75 +42,3 @@ var ( hs.Set("Content-Type", "application/json") }) ) - -// -func routeLoginService(ctx context.Context, r *mux.Router) { - - logged := logging.New("login").Middleware() - - loginService := login.New() - - // POST / - - r.Methods("POST").Path("/").Handler(httptransport.NewServer( - ctx, - logged(loginService.Endpoint()), - loginService.Decoder, - servered(jsoned(loginService.Encoder)), - )).Name("POST") - -} - -// -func routeTestService(ctx context.Context, r *mux.Router) { - - logged := logging.New("test").Middleware() - - testService := testing.New() - - // POST / - - r.Methods("POST").Path("/").Handler(httptransport.NewServer( - ctx, - logged(testService.Post()), - testService.DecodePost, - servered(jsoned(testService.EncodePost)), - )).Name("POST") - - // GET /:id - - r.Methods("POST", "GET").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( - ctx, - logged(testService.Get()), - testService.DecodeGet, - servered(jsoned(testService.EncodeGet)), - ))).Name("GET/POST Id") - - // PUT /:id - - r.Methods("PUT").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( - ctx, - logged(testService.Put()), - testService.DecodePut, - servered(jsoned(testService.EncodePut)), - ))).Name("PUT Id") - - // PATCH /:id - - r.Methods("PATCH").Path("/{id}").Handler(httptransport.NewServer( - ctx, - logged(testService.Patch()), - testService.DecodePatch, - servered(jsoned(testService.EncodePatch)), - )).Name("PATCH Id") - - // DELETE /:id - - r.Methods("DELETE").Path("/{id}").Handler(caching.New(-1, httptransport.NewServer( - ctx, - logged(testService.Delete()), - testService.DecodeDelete, - servered(jsoned(testService.EncodeDelete)), - ))).Name("DELETE Id") - -} diff --git a/vendor/application/start.go b/vendor/application/start.go index 5853fc7..e17c9ae 100644 --- a/vendor/application/start.go +++ b/vendor/application/start.go @@ -29,8 +29,8 @@ func Start() error { privPort := strconv.Itoa(Settings.Port) pubPort := "80" - if Settings.Port != 443 || Settings.Port >= 3000 { - pubPort = strconv.Itoa(Settings.Port - 443) + if Settings.Port != 443 || Settings.Port >= 3443 { + pubPort = strconv.Itoa(Settings.Port - 363) } srv := &http.Server{ ReadTimeout: 5 * time.Second, diff --git a/vendor/application/vendor/middleware/logging/logging.go b/vendor/application/vendor/middleware/logging/logging.go index f44854a..bda023b 100644 --- a/vendor/application/vendor/middleware/logging/logging.go +++ b/vendor/application/vendor/middleware/logging/logging.go @@ -15,11 +15,16 @@ type logger struct { } // -func New(name string) *logger { +func New(options ...string) *logger { l := log.NewLogfmtLogger(os.Stderr) c := log.NewContext(l).With("time", log.DefaultTimestampUTC) - if name != "" { - c = c.With("service", name) + for i := len(options) - 1; i >= 0; i-- { + switch i { + case 0: + c = c.With("service", options[i]) + case 1: + c = c.With("app", options[i]) + } } return &logger{c} } diff --git a/vendor/application/vendor/service/query/README.md b/vendor/application/vendor/service/query/README.md new file mode 100644 index 0000000..e69de29 diff --git a/vendor/application/vendor/service/query/query.go b/vendor/application/vendor/service/query/query.go new file mode 100644 index 0000000..986a856 --- /dev/null +++ b/vendor/application/vendor/service/query/query.go @@ -0,0 +1,86 @@ +package query + +import ( + "encoding/json" + "errors" + "net/http" + "strings" + + "github.com/go-kit/kit/endpoint" + + "golang.org/x/net/context" +) + +// Errors + +// ErrNoQuery. +var ErrNoQuery = errors.New("empty query") + +// Model + +// Query operations. +type Service interface { + Query(string) (string, error) +} + +// Private Query model. +type queryService struct{} + +// Query requests. +type queryRequest struct { + S string `json:"s"` +} + +// Query response. +type queryResponse struct { + V string `json:"v"` + Err string `json:"err,omitempty"` // errors don't define JSON marshaling +} + +// +func (queryService) Query(s string) (string, error) { + if s == "" { + return "", ErrNoQuery + } + return strings.ToUpper(s), nil +} + +// Initialization + +// +type queryEndpoint endpoint.Endpoint + +// +func New() queryEndpoint { + svc := queryService{} + + return func(ctx context.Context, request interface{}) (interface{}, error) { + req := request.(queryRequest) + v, err := svc.Query(req.S) + if err != nil { + return queryResponse{v, err.Error()}, nil + } + return queryResponse{v, ""}, nil + } +} + +// Convenience to get a go-kit type back of query's private endpoint type. +func (e queryEndpoint) Endpoint() endpoint.Endpoint { + return endpoint.Endpoint(e) +} + +// Request/response encoding and decoding. + +// +func (e queryEndpoint) Decoder(_ context.Context, r *http.Request) (interface{}, error) { + var request queryRequest + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + return nil, err + } + return request, nil +} + +// +func (e queryEndpoint) Encoder(_ context.Context, w http.ResponseWriter, response interface{}) error { + return json.NewEncoder(w).Encode(response) +} diff --git a/vendor/application/vendor/service/query/query_test.go b/vendor/application/vendor/service/query/query_test.go new file mode 100644 index 0000000..4e23aed --- /dev/null +++ b/vendor/application/vendor/service/query/query_test.go @@ -0,0 +1,13 @@ +package query + +import "testing" + +// +func TestMain(m *testing.M) { + m.Run() +} + +// +func TestQuery(t *testing.T) { + +} diff --git a/vendor/application/vendor/service/starwars/README.md b/vendor/application/vendor/service/starwars/README.md new file mode 100644 index 0000000..e69de29 diff --git a/vendor/application/vendor/service/starwars/service.go b/vendor/application/vendor/service/starwars/service.go new file mode 100644 index 0000000..d5ab097 --- /dev/null +++ b/vendor/application/vendor/service/starwars/service.go @@ -0,0 +1,86 @@ +package starwars + +import ( + "encoding/json" + "errors" + "net/http" + "strings" + + "github.com/go-kit/kit/endpoint" + + "golang.org/x/net/context" +) + +// Errors + +// ErrNoQuery. +var ErrNoQuery = errors.New("empty starwars") + +// Model + +// Query operations. +type Service interface { + Query(string) (string, error) +} + +// Private Query model. +type starwarsService struct{} + +// Query requests. +type starwarsRequest struct { + S string `json:"s"` +} + +// Query response. +type starwarsResponse struct { + V string `json:"v"` + Err string `json:"err,omitempty"` // errors don't define JSON marshaling +} + +// +func (starwarsService) Query(s string) (string, error) { + if s == "" { + return "", ErrNoQuery + } + return strings.ToUpper(s), nil +} + +// Initialization + +// +type starwarsEndpoint endpoint.Endpoint + +// +func New() starwarsEndpoint { + svc := starwarsService{} + + return func(ctx context.Context, request interface{}) (interface{}, error) { + req := request.(starwarsRequest) + v, err := svc.Query(req.S) + if err != nil { + return starwarsResponse{v, err.Error()}, nil + } + return starwarsResponse{v, ""}, nil + } +} + +// Convenience to get a go-kit type back of starwars's private endpoint type. +func (e starwarsEndpoint) Endpoint() endpoint.Endpoint { + return endpoint.Endpoint(e) +} + +// Request/response encoding and decoding. + +// +func (e starwarsEndpoint) Decoder(_ context.Context, r *http.Request) (interface{}, error) { + var request starwarsRequest + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + return nil, err + } + return request, nil +} + +// +func (e starwarsEndpoint) Encoder(_ context.Context, w http.ResponseWriter, response interface{}) error { + return json.NewEncoder(w).Encode(response) +} diff --git a/vendor/application/vendor/service/starwars/starwars.go b/vendor/application/vendor/service/starwars/starwars.go new file mode 100644 index 0000000..7938bf3 --- /dev/null +++ b/vendor/application/vendor/service/starwars/starwars.go @@ -0,0 +1,464 @@ +package starwars + +import ( + "encoding/json" + "reflect" + "strconv" + "testing" + + "github.com/graphql-go/graphql" + "github.com/graphql-go/graphql/language/ast" + "github.com/graphql-go/graphql/language/parser" + "github.com/kr/pretty" +) + +var ( + Luke StarWarsChar + Vader StarWarsChar + Han StarWarsChar + Leia StarWarsChar + Tarkin StarWarsChar + Threepio StarWarsChar + Artoo StarWarsChar + HumanData map[int]StarWarsChar + DroidData map[int]StarWarsChar + StarWarsSchema graphql.Schema + + humanType *graphql.Object + droidType *graphql.Object +) + +type StarWarsChar struct { + ID string + Name string + Friends []StarWarsChar + AppearsIn []int + HomePlanet string + PrimaryFunction string +} + +func init() { + Luke = StarWarsChar{ + ID: "1000", + Name: "Luke Skywalker", + AppearsIn: []int{4, 5, 6}, + HomePlanet: "Tatooine", + } + Vader = StarWarsChar{ + ID: "1001", + Name: "Darth Vader", + AppearsIn: []int{4, 5, 6}, + HomePlanet: "Tatooine", + } + Han = StarWarsChar{ + ID: "1002", + Name: "Han Solo", + AppearsIn: []int{4, 5, 6}, + } + Leia = StarWarsChar{ + ID: "1003", + Name: "Leia Organa", + AppearsIn: []int{4, 5, 6}, + HomePlanet: "Alderaa", + } + Tarkin = StarWarsChar{ + ID: "1004", + Name: "Wilhuff Tarkin", + AppearsIn: []int{4}, + } + Threepio = StarWarsChar{ + ID: "2000", + Name: "C-3PO", + AppearsIn: []int{4, 5, 6}, + PrimaryFunction: "Protocol", + } + Artoo = StarWarsChar{ + ID: "2001", + Name: "R2-D2", + AppearsIn: []int{4, 5, 6}, + PrimaryFunction: "Astromech", + } + Luke.Friends = append(Luke.Friends, []StarWarsChar{Han, Leia, Threepio, Artoo}...) + Vader.Friends = append(Luke.Friends, []StarWarsChar{Tarkin}...) + Han.Friends = append(Han.Friends, []StarWarsChar{Luke, Leia, Artoo}...) + Leia.Friends = append(Leia.Friends, []StarWarsChar{Luke, Han, Threepio, Artoo}...) + Tarkin.Friends = append(Tarkin.Friends, []StarWarsChar{Vader}...) + Threepio.Friends = append(Threepio.Friends, []StarWarsChar{Luke, Han, Leia, Artoo}...) + Artoo.Friends = append(Artoo.Friends, []StarWarsChar{Luke, Han, Leia}...) + HumanData = map[int]StarWarsChar{ + 1000: Luke, + 1001: Vader, + 1002: Han, + 1003: Leia, + 1004: Tarkin, + } + DroidData = map[int]StarWarsChar{ + 2000: Threepio, + 2001: Artoo, + } + + episodeEnum := graphql.NewEnum(graphql.EnumConfig{ + Name: "Episode", + Description: "One of the films in the Star Wars Trilogy", + Values: graphql.EnumValueConfigMap{ + "NEWHOPE": &graphql.EnumValueConfig{ + Value: 4, + Description: "Released in 1977.", + }, + "EMPIRE": &graphql.EnumValueConfig{ + Value: 5, + Description: "Released in 1980.", + }, + "JEDI": &graphql.EnumValueConfig{ + Value: 6, + Description: "Released in 1983.", + }, + }, + }) + + characterInterface := graphql.NewInterface(graphql.InterfaceConfig{ + Name: "Character", + Description: "A character in the Star Wars Trilogy", + Fields: graphql.Fields{ + "id": &graphql.Field{ + Type: graphql.NewNonNull(graphql.String), + Description: "The id of the character.", + }, + "name": &graphql.Field{ + Type: graphql.String, + Description: "The name of the character.", + }, + "appearsIn": &graphql.Field{ + Type: graphql.NewList(episodeEnum), + Description: "Which movies they appear in.", + }, + }, + ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { + if character, ok := p.Value.(StarWarsChar); ok { + id, _ := strconv.Atoi(character.ID) + human := GetHuman(id) + if human.ID != "" { + return humanType + } + } + return droidType + }, + }) + characterInterface.AddFieldConfig("friends", &graphql.Field{ + Type: graphql.NewList(characterInterface), + Description: "The friends of the character, or an empty list if they have none.", + }) + + humanType = graphql.NewObject(graphql.ObjectConfig{ + Name: "Human", + Description: "A humanoid creature in the Star Wars universe.", + Fields: graphql.Fields{ + "id": &graphql.Field{ + Type: graphql.NewNonNull(graphql.String), + Description: "The id of the human.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if human, ok := p.Source.(StarWarsChar); ok { + return human.ID, nil + } + return nil, nil + }, + }, + "name": &graphql.Field{ + Type: graphql.String, + Description: "The name of the human.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if human, ok := p.Source.(StarWarsChar); ok { + return human.Name, nil + } + return nil, nil + }, + }, + "friends": &graphql.Field{ + Type: graphql.NewList(characterInterface), + Description: "The friends of the human, or an empty list if they have none.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if human, ok := p.Source.(StarWarsChar); ok { + return human.Friends, nil + } + return []interface{}{}, nil + }, + }, + "appearsIn": &graphql.Field{ + Type: graphql.NewList(episodeEnum), + Description: "Which movies they appear in.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if human, ok := p.Source.(StarWarsChar); ok { + return human.AppearsIn, nil + } + return nil, nil + }, + }, + "homePlanet": &graphql.Field{ + Type: graphql.String, + Description: "The home planet of the human, or null if unknown.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if human, ok := p.Source.(StarWarsChar); ok { + return human.HomePlanet, nil + } + return nil, nil + }, + }, + }, + Interfaces: []*graphql.Interface{ + characterInterface, + }, + }) + droidType = graphql.NewObject(graphql.ObjectConfig{ + Name: "Droid", + Description: "A mechanical creature in the Star Wars universe.", + Fields: graphql.Fields{ + "id": &graphql.Field{ + Type: graphql.NewNonNull(graphql.String), + Description: "The id of the droid.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if droid, ok := p.Source.(StarWarsChar); ok { + return droid.ID, nil + } + return nil, nil + }, + }, + "name": &graphql.Field{ + Type: graphql.String, + Description: "The name of the droid.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if droid, ok := p.Source.(StarWarsChar); ok { + return droid.Name, nil + } + return nil, nil + }, + }, + "friends": &graphql.Field{ + Type: graphql.NewList(characterInterface), + Description: "The friends of the droid, or an empty list if they have none.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if droid, ok := p.Source.(StarWarsChar); ok { + friends := []map[string]interface{}{} + for _, friend := range droid.Friends { + friends = append(friends, map[string]interface{}{ + "name": friend.Name, + "id": friend.ID, + }) + } + return droid.Friends, nil + } + return []interface{}{}, nil + }, + }, + "appearsIn": &graphql.Field{ + Type: graphql.NewList(episodeEnum), + Description: "Which movies they appear in.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if droid, ok := p.Source.(StarWarsChar); ok { + return droid.AppearsIn, nil + } + return nil, nil + }, + }, + "primaryFunction": &graphql.Field{ + Type: graphql.String, + Description: "The primary function of the droid.", + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if droid, ok := p.Source.(StarWarsChar); ok { + return droid.PrimaryFunction, nil + } + return nil, nil + }, + }, + }, + Interfaces: []*graphql.Interface{ + characterInterface, + }, + }) + + queryType := graphql.NewObject(graphql.ObjectConfig{ + Name: "Query", + Fields: graphql.Fields{ + "hero": &graphql.Field{ + Type: characterInterface, + Args: graphql.FieldConfigArgument{ + "episode": &graphql.ArgumentConfig{ + Description: "If omitted, returns the hero of the whole saga. If " + + "provided, returns the hero of that particular episode.", + Type: episodeEnum, + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return GetHero(p.Args["episode"]), nil + }, + }, + "human": &graphql.Field{ + Type: humanType, + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{ + Description: "id of the human", + Type: graphql.NewNonNull(graphql.String), + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return GetHuman(p.Args["id"].(int)), nil + }, + }, + "droid": &graphql.Field{ + Type: droidType, + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{ + Description: "id of the droid", + Type: graphql.NewNonNull(graphql.String), + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return GetDroid(p.Args["id"].(int)), nil + }, + }, + }, + }) + StarWarsSchema, _ = graphql.NewSchema(graphql.SchemaConfig{ + Query: queryType, + }) +} + +func GetHuman(id int) StarWarsChar { + if human, ok := HumanData[id]; ok { + return human + } + return StarWarsChar{} +} +func GetDroid(id int) StarWarsChar { + if droid, ok := DroidData[id]; ok { + return droid + } + return StarWarsChar{} +} +func GetHero(episode interface{}) interface{} { + if episode == 5 { + return Luke + } + return Artoo +} + +// Test helper functions + +func TestParse(t *testing.T, query string) *ast.Document { + astDoc, err := parser.Parse(parser.ParseParams{ + Source: query, + Options: parser.ParseOptions{ + // include source, for error reporting + NoSource: false, + }, + }) + if err != nil { + t.Fatalf("Parse failed: %v", err) + } + return astDoc +} +func TestExecute(t *testing.T, ep graphql.ExecuteParams) *graphql.Result { + return graphql.Execute(ep) +} + +func Diff(a, b interface{}) []string { + return pretty.Diff(a, b) +} + +func ASTToJSON(t *testing.T, a ast.Node) interface{} { + b, err := json.Marshal(a) + if err != nil { + t.Fatalf("Failed to marshal Node %v", err) + } + var f interface{} + err = json.Unmarshal(b, &f) + if err != nil { + t.Fatalf("Failed to unmarshal Node %v", err) + } + return f +} + +func ContainSubsetSlice(super []interface{}, sub []interface{}) bool { + if len(sub) == 0 { + return true + } +subLoop: + for _, subVal := range sub { + found := false + innerLoop: + for _, superVal := range super { + if subVal, ok := subVal.(map[string]interface{}); ok { + if superVal, ok := superVal.(map[string]interface{}); ok { + if ContainSubset(superVal, subVal) { + found = true + break innerLoop + } else { + continue + } + } else { + return false + } + + } + if subVal, ok := subVal.([]interface{}); ok { + if superVal, ok := superVal.([]interface{}); ok { + if ContainSubsetSlice(superVal, subVal) { + found = true + break innerLoop + } else { + continue + } + } else { + return false + } + } + if reflect.DeepEqual(superVal, subVal) { + found = true + break innerLoop + } + } + if !found { + return false + } + continue subLoop + } + return true +} + +func ContainSubset(super map[string]interface{}, sub map[string]interface{}) bool { + if len(sub) == 0 { + return true + } + for subKey, subVal := range sub { + if superVal, ok := super[subKey]; ok { + switch superVal := superVal.(type) { + case []interface{}: + if subVal, ok := subVal.([]interface{}); ok { + if !ContainSubsetSlice(superVal, subVal) { + return false + } + } else { + return false + } + case map[string]interface{}: + if subVal, ok := subVal.(map[string]interface{}); ok { + if !ContainSubset(superVal, subVal) { + return false + } + } else { + return false + } + default: + if !reflect.DeepEqual(superVal, subVal) { + return false + } + } + } else { + return false + } + } + return true +} + +func EqualErrorMessage(expected, result *graphql.Result, i int) bool { + return expected.Errors[i].Message == result.Errors[i].Message +} diff --git a/vendor/application/vendor/service/starwars/starwars_test.go b/vendor/application/vendor/service/starwars/starwars_test.go new file mode 100644 index 0000000..96486b4 --- /dev/null +++ b/vendor/application/vendor/service/starwars/starwars_test.go @@ -0,0 +1,13 @@ +package starwars + +import "testing" + +// +func TestMain(m *testing.M) { + m.Run() +} + +// +func TestStarWars(t *testing.T) { + +}