Skip to content

Commit

Permalink
all: support list with json format
Browse files Browse the repository at this point in the history
Fixes #3
  • Loading branch information
cuonglm committed Jul 27, 2021
1 parent 4fb1258 commit 401f0d4
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 71 deletions.
71 changes: 50 additions & 21 deletions cmd/gogi/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"log"
Expand All @@ -12,6 +13,7 @@ import (

var (
listFlag bool
jsonFlag bool
createFlag string
searchFlag string
gogiClient *gogi.Client
Expand All @@ -21,40 +23,50 @@ var (

func init() {
flag.BoolVar(&listFlag, "list", false, "List all defined types")
flag.BoolVar(&jsonFlag, "json", false, "List with JSON format, use with -list")
flag.StringVar(&createFlag, "create", "", "Create .gitignore content for given types")
flag.StringVar(&searchFlag, "search", "", "Show all types match string")

apiURL = os.Getenv("GOGI_API_URL")
if apiURL == "" {
gogiClient, _ = gogi.NewHTTPClient()
} else {
gogiClient, err = gogi.NewHTTPClient(gogi.WithAPIUrl(apiURL))
if err != nil {
panic(err)
}
return
}
gogiClient, err = gogi.NewHTTPClient(gogi.WithAPIUrl(apiURL))
if err != nil {
printError(err.Error())
os.Exit(1)
}
}

func main() {
flag.Parse()

n := flag.NFlag()
switch {
case n == 1:
switch {
case listFlag:
list()
case createFlag != "":
create(createFlag)
case searchFlag != "":
search(searchFlag)
switch flag.NFlag() {
case 1:
// ok
case 2:
if listFlag && jsonFlag {
break // ok
}
case n >= 2:
fmt.Println("Only one action allow.")
fmt.Println()
fallthrough
default:
printError("Only one action allow.")
flag.Usage()
os.Exit(1)
}
switch {
case listFlag && jsonFlag:
listJson()
case jsonFlag:
printError("-json flag must be used with -list")
os.Exit(1)
case listFlag:
list()
case createFlag != "":
create(createFlag)
case searchFlag != "":
search(searchFlag)
}
}

Expand All @@ -64,7 +76,19 @@ func list() {
log.Fatal(err)
}

fmt.Println(data)
_, _ = fmt.Fprintln(os.Stderr, data)
}

func listJson() {
data, err := gogiClient.ListJson()
if err != nil {
printError(err.Error())
os.Exit(1)
}

encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", "\t")
_ = encoder.Encode(data)
}

func create(s string) {
Expand All @@ -73,13 +97,14 @@ func create(s string) {
log.Fatal(err)
}

fmt.Println(data)
_, _ = fmt.Fprintln(os.Stderr, data)
}

func search(s string) {
data, err := gogiClient.List()
if err != nil {
log.Fatal(err)
printError(err.Error())
os.Exit(1)
}
data = strings.Replace(data, "\n", ",", -1)

Expand All @@ -89,3 +114,7 @@ func search(s string) {
}
}
}

func printError(msg string) {
_, _ = fmt.Fprintln(os.Stderr, msg)
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/cuonglm/gogi

go 1.13

require github.com/stretchr/testify v1.7.0
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion gogi.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

const (
version = "0.0.4"
version = "v1"
ua = "gogi/" + version
defaultAPIURL = "https://www.toptal.com"
typePath = "/developers/gitignore/api"
Expand Down
52 changes: 18 additions & 34 deletions gogi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var (
Expand All @@ -28,71 +30,53 @@ func tearDown() {
server.Close()
}

func assertEqual(t *testing.T, result interface{}, expect interface{}) {
if result != expect {
t.Fatalf("Expect (Value: %v) (Type: %T) - Got (Value: %v) (Type: %T)", expect, expect, result, result)
}
}

func TestNewHTTPClient(t *testing.T) {
c, _ := NewHTTPClient()

assertEqual(t, c.UserAgent, ua)
assertEqual(t, c.APIURL.String(), defaultAPIURL)
assert.Equal(t, ua, c.UserAgent)
assert.Equal(t, defaultAPIURL, c.APIURL.String())
}

func TestNewrequest(t *testing.T) {
c, _ := NewHTTPClient()

req, _ := c.NewRequest("GET", "/foo", nil)
assertEqual(t, req.URL.String(), defaultAPIURL+"/foo")
assertEqual(t, req.Header.Get("User-Agent"), ua)

assert.Equal(t, defaultAPIURL+"/foo", req.URL.String())
assert.Equal(t, ua, req.Header.Get("User-Agent"))
}

func TestDo(t *testing.T) {
setUp()
defer tearDown()

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
assertEqual(t, r.Method, "GET")
assert.Equal(t, "GET", r.Method)

_, _ = w.Write([]byte("foo"))
})

req, _ := client.NewRequest("GET", "/", nil)
req, err := client.NewRequest("GET", "/", nil)
require.NoError(t, err)

resp, err := client.Do(req)

if err != nil {
t.Fatalf("Do(): %v", err)
}
require.NoError(t, err)

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Do(): %v", err)
}
require.NoError(t, err)

res := string(body)
expected := "foo"
if !reflect.DeepEqual(res, expected) {
t.Fatalf("Expected %v - Got %v", expected, res)
}
assert.Equal(t, expected, res)
}

func TestWithAPIUrl(t *testing.T) {
c, _ := NewHTTPClient()
u := "http://cuonglm.xyz"
if err := WithAPIUrl(u)(c); err != nil {
t.Fatalf("APIUrl() %+v", err)
}

assertEqual(t, c.APIURL.String(), u)
u := "https://cuonglm.xyz"
require.NoError(t, WithAPIUrl(u)(c))
assert.Equal(t, u, c.APIURL.String())
}

func TestWithHTTPClient(t *testing.T) {
c, _ := NewHTTPClient()

if err := WithHTTPClient(nil)(c); err == nil {
t.Fatal("APIUrl() want error, got nil")
}
require.Error(t, WithHTTPClient(nil)(c))
}
36 changes: 34 additions & 2 deletions methods.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package gogi

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

// List list all defined gitignore types
type ListJsonItem struct {
Contents string `json:"contents"`
FileName string `json:"fileName"`
Key string `json:"key"`
Name string `json:"name"`
}

// List lists all defined gitignore types with lines format
func (c *Client) List() (string, error) {
path := fmt.Sprintf("%s/list", typePath)
req, err := c.NewRequest("GET", path, nil)
Expand All @@ -23,7 +31,31 @@ func (c *Client) List() (string, error) {
return getResponseBody(resp)
}

// Create create .gitignore content for input type
// ListJson lists all defined gitignore types with json format.
func (c *Client) ListJson() (map[string]*ListJsonItem, error) {
path := fmt.Sprintf("%s/list", typePath)
req, err := c.NewRequest("GET", path, nil)
if err != nil {
return nil, err
}
q := req.URL.Query()
q.Add("format", "json")
req.URL.RawQuery = q.Encode()

resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var res map[string]*ListJsonItem
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
return nil, err
}
return res, nil
}

// Create creates .gitignore file content for given input type.
func (c *Client) Create(typeName string) (string, error) {
path := fmt.Sprintf("%s/%s", typePath, typeName)
req, err := c.NewRequest("GET", path, nil)
Expand Down
50 changes: 37 additions & 13 deletions methods_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package gogi

import (
"encoding/json"
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestList(t *testing.T) {
Expand All @@ -12,20 +16,44 @@ func TestList(t *testing.T) {

path := fmt.Sprintf("%s/list", typePath)
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
assertEqual(t, r.Method, "GET")
assert.Equal(t, "GET", r.Method)

_, _ = w.Write([]byte("test list"))
})

data, err := client.List()
if err != nil {
t.Fatalf("List(): %v", err)
}
require.NoError(t, err)

expected := "test list"
if data != expected {
t.Fatalf("Expected %v - Got %v", expected, data)
assert.Equal(t, expected, data)
}

func TestListJson(t *testing.T) {
setUp()
defer tearDown()

goItem := &ListJsonItem{
Contents: "\n### Go ###\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n### Go Patch ###\n/vendor/\n/Godeps/\n",
FileName: "Go.gitignore",
Key: "go",
Name: "go",
}
path := fmt.Sprintf("%s/list", typePath)
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method)
assert.Equal(t, "json", r.URL.Query().Get("format"))

res := map[string]*ListJsonItem{
"go": goItem,
}
assert.NoError(t, json.NewEncoder(w).Encode(res))
})

data, err := client.ListJson()
require.NoError(t, err)

assert.Len(t, data, 1)
assert.Equal(t, goItem, data["go"])
}

func TestCreate(t *testing.T) {
Expand All @@ -34,18 +62,14 @@ func TestCreate(t *testing.T) {

path := fmt.Sprintf("%s/foo", typePath)
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
assertEqual(t, r.Method, "GET")
assert.Equal(t, "GET", r.Method)

_, _ = w.Write([]byte("test create foo"))
})

data, err := client.Create("foo")
if err != nil {
t.Fatalf("Create(): %v", err)
}
require.NoError(t, err)

expected := "test create foo"
if data != expected {
t.Fatalf("Expected %v - Got %v", expected, data)
}
assert.Equal(t, expected, data)
}

0 comments on commit 401f0d4

Please sign in to comment.