diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..4817db8 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @n3m \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index fcf71f0..8fa245c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: go +go: + - master script: - go test -v ./... diff --git a/README.md b/README.md index 31bb66c..ffe4678 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Pretty Print for Golang (Maps, Models and Normal Variables) ## How to install -##### Version: 1.10.3 +##### Version: 1.11.0 `go get github.com/n3m/pprnt` @@ -19,10 +19,10 @@ Pretty Print is a Golang Package designed to print Maps and Structs as if they w ```go package main -import "github.com/DrN3MESiS/pprnt" +import "github.com/n3m/pprnt" func main(){ - example := map[string]interface{}{"get": map[string]interface{}{"some":"brother"}} + example := map[string]interface{}{"hell": map[string]interface{}{"yeah":"brother"}} // Print(interface) :: The function Print() expects an interface to be passed as parameters // So you can pass any type of variable @@ -36,8 +36,8 @@ func main(){ $ go run . { - "get": { - "some": "brother" + "hell": { + "yeah": "brother" } } ``` diff --git a/deprecated_test.go b/deprecated_test.go new file mode 100644 index 0000000..2129524 --- /dev/null +++ b/deprecated_test.go @@ -0,0 +1,11 @@ +package pprnt + +import "testing" + +func Test_Deprecated_Print(t *testing.T) { + + Deprecated.CleanMap(map[string]interface{}{}) + + Deprecated.CleanArray([]interface{}{}) + +} diff --git a/go.mod b/go.mod index fa4a150..780ac2c 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,8 @@ module github.com/n3m/pprnt go 1.13 -require github.com/mattn/go-isatty v0.0.12 +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/stretchr/testify v1.7.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/go.sum b/go.sum index 621abe5..c221f64 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,13 @@ -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..78be9f8 --- /dev/null +++ b/helpers.go @@ -0,0 +1,60 @@ +package pprnt + +import ( + "fmt" + "reflect" + "strings" +) + +var indentation int = 2 + +var lvl string = strings.Repeat("\t", indentation) + +func _CreateLevelString() string { + return strings.Repeat(lvl, _state.Level) +} + +func _ProcessArchitecture(arg interface{}, key *string, endChar *string) string { + value := reflect.ValueOf(arg) + + if arg == nil { + return _PrintNil(arg, key, endChar) + } + + switch reflect.TypeOf(arg).Kind() { + + case reflect.Slice, reflect.Array: + return _PrintSliceOrArray(reflect.Indirect(value).Interface(), key, endChar) + case reflect.Map: + return _PrintMap(reflect.Indirect(value).Interface(), key, endChar) + case reflect.Struct: + return _PrintStruct(reflect.Indirect(value).Interface(), key, endChar) + // case reflect.Chan: + // case reflect.Interface: + case reflect.Ptr: + newValue := value.Elem() + newValue = reflect.Indirect(newValue) + return _ProcessArchitecture(newValue.Interface(), key, endChar) + // case reflect.UnsafePointer: + // case reflect.Uintptr: + } + + return _PrintPrimitive(reflect.Indirect(value).Interface(), key, endChar) +} + +func _PrintPrimitive(arg interface{}, key *string, endChar *string) string { + switch reflect.TypeOf(arg).Kind() { + case reflect.String: + return _PrintString(arg, key, endChar) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return _PrintInt(arg, key, endChar) + case reflect.Bool: + return _PrintBoolean(arg, key, endChar) + case reflect.Float32, reflect.Float64: + return _PrintFloat(arg, key, endChar) + default: + + fmt.Printf("[!!] %+v\n", arg) + return fmt.Sprintf("%+v\n", arg) + } +} diff --git a/helpers/main.go b/helpers/main.go deleted file mode 100644 index 3226d7f..0000000 --- a/helpers/main.go +++ /dev/null @@ -1,44 +0,0 @@ -package helpers - -import ( - "encoding/json" - "errors" - "fmt" -) - -//StructToMap ... -func StructToMap(data interface{}) (map[string]interface{}, error) { - errMessage := "[structToMap()] > " - m := make(map[string]interface{}) - - j, err := json.Marshal(data) - if err != nil { - return nil, errors.New(errMessage + err.Error() + " :: [001]") - } - - err = json.Unmarshal(j, &m) - if err != nil { - return nil, errors.New(errMessage + err.Error() + " :: [002]") - } - - return m, nil -} - -//ValueToMap ... -func ValueToMap(arg interface{}) (map[string]interface{}, error) { - errMessage := "[ERR][Stage: Convert Data] >" - m := make(map[string]interface{}) - - j, err := json.Marshal(arg) - if err != nil { - - return nil, fmt.Errorf("%+v %+v", errMessage, err.Error()) - } - - err = json.Unmarshal(j, &m) - if err != nil { - return nil, fmt.Errorf("%+v %+v", errMessage, err.Error()) - } - - return m, nil -} diff --git a/helpers_color.go b/helpers_color.go new file mode 100644 index 0000000..c3580f4 --- /dev/null +++ b/helpers_color.go @@ -0,0 +1,22 @@ +package pprnt + +const ( + //ColorReset ... + ColorReset string = "\033[0m" + //ColorRed ... + ColorRed string = "\033[31m" //Not supported or nil + //ColorGreen ... + ColorGreen string = "\033[32m" //String + //ColorYellow ... + ColorYellow string = "\033[33m" //Keys + //ColorBlue ... + ColorBlue string = "\033[34m" //Bool + //ColorPurple ... + ColorPurple string = "\033[35m" //Int floats + //ColorCyan ... + ColorCyan string = "\033[36m" //Brackets or Corch + //ColorGray ... + ColorGray string = "\033[37m" + //ColorWhite ... + ColorWhite string = "\033[97m" +) diff --git a/helpers_primitive.go b/helpers_primitive.go new file mode 100644 index 0000000..b0cf8f4 --- /dev/null +++ b/helpers_primitive.go @@ -0,0 +1,59 @@ +package pprnt + +import ( + "fmt" +) + +const formatString string = "\"%+v\"" +const formatInt string = "%d" +const formatBoolean string = "%t" +const formatNil string = "%s" +const formatFloat string = "%+v" + +func _PrintString(elem interface{}, key *string, endChar *string) string { + return _DoPrintPrimitive(formatString, key, endChar, elem) +} + +func _PrintInt(elem interface{}, key *string, endChar *string) string { + return _DoPrintPrimitive(formatInt, key, endChar, elem) +} + +func _PrintBoolean(elem interface{}, key *string, endChar *string) string { + return _DoPrintPrimitive(formatBoolean, key, endChar, elem) +} + +func _PrintNil(elem interface{}, key *string, endChar *string) string { + return _DoPrintPrimitive(formatNil, key, endChar, "") +} + +func _PrintFloat(elem interface{}, key *string, endChar *string) string { + return _DoPrintPrimitive(formatFloat, key, endChar, elem) +} + +func _DoPrintPrimitive(format string, key *string, endChar *string, elem interface{}) string { + lvlStr := _CreateLevelString() + + strToPrint := "" + + if key != nil { + strToPrint += lvlStr + "\"" + *key + "\"" + ": " + key = nil + } else { + strToPrint += lvlStr + } + + strToPrint += fmt.Sprintf(format, elem) + + if _state.Level > 0 { + strToPrint += "," + } + + if endChar != nil { + strToPrint += *endChar + } else { + strToPrint += "\n" + } + + fmt.Print(strToPrint) + return fmt.Sprint(strToPrint) +} diff --git a/helpers_special.go b/helpers_special.go new file mode 100644 index 0000000..2732495 --- /dev/null +++ b/helpers_special.go @@ -0,0 +1,114 @@ +package pprnt + +import ( + "fmt" + "reflect" +) + +func _PrintSpecialInitSetup(str, lvlStr string, key *string, initSetupChar string) (string, *string) { + if key != nil { + str += lvlStr + "\"" + *key + "\"" + ": " + key = nil + } else { + str += lvlStr + } + + str += initSetupChar + "\n" + fmt.Print(str) + + return str, key +} + +func _PrintSpecialEndSetup(str, lvlStr string, endChar *string, endSetupChar string) string { + finalStrToPrint := lvlStr + endSetupChar + if _state.Level > 0 { + finalStrToPrint += "," + } + + if endChar != nil { + finalStrToPrint += *endChar + } else { + finalStrToPrint += "\n" + } + + return finalStrToPrint +} + +func _PrintSliceOrArray(arg interface{}, key *string, endChar *string) string { + str := "" + lvlStr := _CreateLevelString() + + // Initial Setup + str, key = _PrintSpecialInitSetup(str, lvlStr, key, "[") + _state.Level++ + + // Processing each element + items := reflect.ValueOf(arg) + items = reflect.Indirect(items) + for i := 0; i < items.Len(); i++ { + item := items.Index(i) + item = reflect.Indirect(item) + + str += _ProcessArchitecture(item.Interface(), key, endChar) + } + + // Final Setup + _state.Level-- + finalStrToPrint := _PrintSpecialEndSetup(str, lvlStr, endChar, "]") + str += finalStrToPrint + fmt.Print(finalStrToPrint) + return str +} + +func _PrintMap(arg interface{}, key *string, endChar *string) string { + lvlStr := _CreateLevelString() + str := "" + + // Initial Setup + str, _ = _PrintSpecialInitSetup(str, lvlStr, key, "{") + _state.Level++ + + // Processing each element + mapObj := reflect.ValueOf(arg) + for _, key := range mapObj.MapKeys() { + value := mapObj.MapIndex(key).Interface() + + str += _ProcessArchitecture(value, + GetStringAdddress(key.String()), + endChar) + } + + // Final Setup + _state.Level-- + finalStrToPrint := _PrintSpecialEndSetup(str, lvlStr, endChar, "}") + str += finalStrToPrint + fmt.Print(finalStrToPrint) + return str +} + +func _PrintStruct(arg interface{}, key *string, endChar *string) string { + + lvlStr := _CreateLevelString() + str := "" + + // Initial Setup + str, _ = _PrintSpecialInitSetup(str, lvlStr, key, "{") + _state.Level++ + + // Processing each element + structValues := reflect.ValueOf(arg) + structValues = reflect.Indirect(structValues) + + for j := 0; j < structValues.NumField(); j++ { + str += _ProcessArchitecture(structValues.Field(j).Interface(), + GetStringAdddress(structValues.Type().Field(j).Name), + endChar) + } + + // Final Setup + _state.Level-- + finalStrToPrint := _PrintSpecialEndSetup(str, lvlStr, endChar, "}") + str += finalStrToPrint + fmt.Print(finalStrToPrint) + return str +} diff --git a/cleaner/main.go b/legacy.go similarity index 64% rename from cleaner/main.go rename to legacy.go index de2d31e..e750459 100644 --- a/cleaner/main.go +++ b/legacy.go @@ -1,7 +1,10 @@ -package cleaner +package pprnt + +type deprecatedHolder struct { +} //CleanMap ... -func CleanMap(clmap map[string]interface{}) map[string]interface{} { +func (dh *deprecatedHolder) CleanMap(clmap map[string]interface{}) map[string]interface{} { newMap := map[string]interface{}{} for key, value := range clmap { if value == nil { @@ -11,11 +14,11 @@ func CleanMap(clmap map[string]interface{}) map[string]interface{} { switch value.(type) { case map[string]interface{}: childMap := value.(map[string]interface{}) - newMap[key] = CleanMap(childMap) + newMap[key] = dh.CleanMap(childMap) break case []interface{}: arr := value.([]interface{}) - newMap[key] = CleanArray(arr) + newMap[key] = dh.CleanArray(arr) break default: newMap[key] = value @@ -26,7 +29,7 @@ func CleanMap(clmap map[string]interface{}) map[string]interface{} { } //CleanArray ... -func CleanArray(clarr []interface{}) []interface{} { +func (dh *deprecatedHolder) CleanArray(clarr []interface{}) []interface{} { newArr := []interface{}{} for _, each := range clarr { if each == nil { @@ -35,11 +38,11 @@ func CleanArray(clarr []interface{}) []interface{} { switch each.(type) { case map[string]interface{}: childMap := each.(map[string]interface{}) - newArr = append(newArr, CleanMap(childMap)) + newArr = append(newArr, dh.CleanMap(childMap)) break case []interface{}: arr := each.([]interface{}) - newArr = append(newArr, CleanArray(arr)) + newArr = append(newArr, dh.CleanArray(arr)) break default: newArr = append(newArr, each) diff --git a/main.go b/main.go deleted file mode 100644 index f9fb7c8..0000000 --- a/main.go +++ /dev/null @@ -1,144 +0,0 @@ -package pprnt - -/* - Version: 1.10.3 - Author: Alan Maldonado -*/ - -import ( - "fmt" - "log" - "reflect" - "strings" - - "github.com/n3m/pprnt/cleaner" - "github.com/n3m/pprnt/helpers" - "github.com/n3m/pprnt/printer" -) - -var ( - detailMode bool = false - initialDepth int = 0 -) - -//SetDetailMode ... -/* -This function allows the developer to change the printing "Detail Mode", which in summary, -prints the type of the value that it has read. - -Param: "code" -Expects an integer: '1' to enable "Detail Mode" or '0' to disable "Detail Mode" - -TL;DR: '1' to enable, '0' to disable -*/ -func SetDetailMode(code int) { - switch code { - case 1: - detailMode = true - break - case 0: - detailMode = false - break - } -} - -//SetIdentLength ... -/* -This function allows the developer to change the number of spaces defined as "Identantion" -while printing a value. - -Param: "length" -Expects a positive integer. - -TL;DR: The given value in the parameter will be the number of spaces in the "Identation" -*/ -func SetIdentLength(length int) { - if length < 0 { - panic("SetIdentLength() :: Function expects a positive length value") - } - printer.IdentString = strings.Repeat(" ", length) -} - -//Print ... -/* -This function allows the developer to print any type of variable with a prettier printing -structure - -Param: "arg" -Expects any type of variable of any type of value. - -TL;DR: Prints a single parameter -*/ -func Print(arg interface{}) { - errMessage := "[PPRNT]" - switch reflect.ValueOf(arg).Kind() { - case reflect.Map, reflect.Struct: - MTP, err := helpers.ValueToMap(arg) - if err != nil { - log.Printf("%+v Couldn't print the provided data > %+v", errMessage, err.Error()) - return - } - - err = printer.PrintMap(MTP, initialDepth, detailMode) - if err != nil { - log.Printf("%+v Couldn't print the provided data > %+v", errMessage, err.Error()) - return - } - break - case reflect.Array, reflect.Slice: - tempArray := arg.([]interface{}) - err := printer.PrintArray(tempArray, initialDepth, detailMode) - if err != nil { - log.Printf("%+v Couldn't print the provided data > %+v", errMessage, err.Error()) - return - } - break - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64, reflect.Bool, - reflect.Float32, reflect.Float64, reflect.String: - printer.PrintValue(arg, detailMode) - break - default: - err := printer.PrintNormal(arg, initialDepth, detailMode) - if err != nil { - log.Printf("%+v Couldn't print the provided data > %+v", errMessage, err.Error()) - return - } - - break - } - - fmt.Println(printer.ColorReset) - -} - -//MPrint ... -/* -This function allows the developer to print an 'N' amount of variables with a prettier printing -structure - -Param: "args" -Expects an 'N' amount of paramters of any type - -TL;DR: Prints an 'N' amount of given parameters -*/ -func MPrint(args ...interface{}) { - for _, arg := range args { - Print(arg) - } - -} - -//SuperDepthMapCleaning ... -/* -This function allows the developer to "Clean" a map[string]interface{} structure from any 'nil' fields. -Basically it removes the fields with value of type 'nil'. - -Param: "aMap" -Expects a map[string]interface{} - -TL;DR: Cleans a map from all nil key:values -*/ -func SuperDepthMapCleaning(aMap map[string]interface{}) (map[string]interface{}, error) { - return cleaner.CleanMap(aMap), nil -} diff --git a/main_test.go b/main_test.go deleted file mode 100644 index 32d0bd2..0000000 --- a/main_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package pprnt - -import ( - "fmt" - "testing" -) - -type StructToTest struct { - Name string - ID int32 - Enabled bool - Server *InnerStructForTesting -} - -type InnerStructForTesting struct { - ID string -} - -func TestSuperDepthMapCleaning(t *testing.T) { - curMap := map[string]interface{}{ - "test1": nil, - "test2": 1, - "test3": map[string]interface{}{ - "test3.1": "lol", - "test3.2": nil, - "test3.3": []interface{}{ - nil, - 1, - 2, - }, - }, - } - - Print(curMap) - curMap, err := SuperDepthMapCleaning(curMap) - if err != nil { - t.Fatal(err) - } - Print(curMap) -} - -func TestPrintNormal(t *testing.T) { - tests := map[string]interface{}{ - "int": 1, - "float": 5.2, - "bool": false, - "string": "some string", - } - - for key, test := range tests { - fmt.Printf("> Test: %+v\n", key) - Print(test) - } - - fmt.Printf("= = =\n") - - SetDetailMode(1) - for key, test := range tests { - fmt.Printf("> Test: %+v\n", key) - Print(test) - } -} - -func TestPrintMapStruct(t *testing.T) { - tests := map[string]interface{}{ - "map": map[string]interface{}{ - "test1": nil, - "test2": 1, - "test3": map[string]interface{}{ - "test3.1": "lol", - "test3.2": nil, - "test3.3": []interface{}{ - nil, - 1, - 2, - }, - }, - }, - "struct": StructToTest{ - Name: "Alan", - ID: 654, - Enabled: true, - Server: &InnerStructForTesting{ - ID: "897465", - }, - }, - } - - for key, test := range tests { - fmt.Printf("\n\n\n> Test: %+v\n", key) - Print(test) - } -} -func TestPrintArray(t *testing.T) { - tests := map[string][]interface{}{ - "arr1": { - 1, - map[string]interface{}{ - "test1": nil, - "test2": 1, - "test3": map[string]interface{}{ - "test3.1": "lol", - "test3.2": nil, - "test3.3": []interface{}{ - nil, - 1, - 2, - }, - }, - }, - }, - "arr2": { - 3, - nil, - StructToTest{ - Name: "Alan", - ID: 654, - Enabled: true, - Server: &InnerStructForTesting{ - ID: "897465", - }, - }, - }, - "arr3": { - "data", - "test", - }, - } - - for key, test := range tests { - fmt.Printf("\n\n\n> Test: %+v\n", key) - Print(test) - } -} diff --git a/models.go b/models.go new file mode 100644 index 0000000..527c584 --- /dev/null +++ b/models.go @@ -0,0 +1,14 @@ +package pprnt + +type localState struct { + Level int + InOperation bool +} + +func (ls *localState) Reset() { + ls.Level = 0 +} + +type PrintOptions struct { + EndComma bool +} diff --git a/print.go b/print.go new file mode 100644 index 0000000..ce55ed2 --- /dev/null +++ b/print.go @@ -0,0 +1,15 @@ +package pprnt + +var _state *localState = &localState{ + Level: 0, +} + +var Deprecated *deprecatedHolder = &deprecatedHolder{} + +// var NoColor bool = !isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()) + +func Print(arg interface{}) string { + _state.Reset() + + return _ProcessArchitecture(arg, nil, nil) +} diff --git a/print_primitives_pointer_test.go b/print_primitives_pointer_test.go new file mode 100644 index 0000000..8d67daf --- /dev/null +++ b/print_primitives_pointer_test.go @@ -0,0 +1,60 @@ +package pprnt + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_PrintPointerString(t *testing.T) { + cases := []*string{ + GetStringAdddress("t1"), + GetStringAdddress("t2"), + GetStringAdddress("t3"), + GetStringAdddress("t4"), + GetStringAdddress("t5"), + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("\"%+v\"\n", *c), output) + } +} + +func Test_PrintPointerInt(t *testing.T) { + cases := []*int{ + new(int), new(int), new(int), new(int), new(int), + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", *c), output) + } +} + +func Test_PrintPointerBoolean(t *testing.T) { + cases := []*bool{ + new(bool), new(bool), new(bool), new(bool), new(bool), + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", *c), output) + } +} + +func Test_PrintPointerFloat64(t *testing.T) { + cases := []*float64{ + new(float64), new(float64), new(float64), new(float64), new(float64), + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", *c), output) + } +} diff --git a/print_primitives_test.go b/print_primitives_test.go new file mode 100644 index 0000000..792c676 --- /dev/null +++ b/print_primitives_test.go @@ -0,0 +1,60 @@ +package pprnt + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_PrintString(t *testing.T) { + cases := []string{ + "Howdy", + "Hello world", + "God\"s eye", + "Mamma mia", + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("\"%+v\"\n", c), output) + } + +} + +func Test_PrintInt(t *testing.T) { + cases := []int{ + 111, 69, 420, 000, 646545465, + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", c), output) + } +} + +func Test_PrintBoolean(t *testing.T) { + cases := []bool{ + true, false, false, true, + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", c), output) + } +} + +func Test_PrintFloat64(t *testing.T) { + cases := []float64{ + 1.1, 1.2, 1.3, 1.4, 1.5, + } + + for _, c := range cases { + output := Print(c) + + assert.Equal(t, fmt.Sprintf("%+v\n", c), output) + } +} diff --git a/print_slice_array_test.go b/print_slice_array_test.go new file mode 100644 index 0000000..7b43191 --- /dev/null +++ b/print_slice_array_test.go @@ -0,0 +1,25 @@ +package pprnt + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_PrintSlice(t *testing.T) { + cases := []interface{}{ + "Howdy", + nil, + } + + output := Print(cases) + + expected := + `[ + "Howdy", + , +] +` + + assert.Equal(t, expected, output) +} diff --git a/print_special_pointer_test.go b/print_special_pointer_test.go new file mode 100644 index 0000000..2684fcc --- /dev/null +++ b/print_special_pointer_test.go @@ -0,0 +1,130 @@ +package pprnt + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_PrintMapPointerString(t *testing.T) { + caseT := &map[string]string{ + "At1": "t1", + "At2": "t2", + } + output := Print(caseT) + + tests := []string{ + "\t\t\"At1\": \"t1\",\n", + "\t\t\"At2\": \"t2\",\n", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } +} + +func Test_PrintMapPointerInterface(t *testing.T) { + caseT := map[string]interface{}{ + "At1": GetStringAdddress("t1"), + "At2": GetStringAdddress("t2"), + } + output := Print(caseT) + + tests := []string{ + "\t\t\"At1\": \"t1\",\n", + "\t\t\"At2\": \"t2\",\n", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } +} + +func Test_PrintMapPointerValueString(t *testing.T) { + caseT := &_Test{ + A: "Howdy", + B: 2, + C: true, + D: 1.5000000004, + ARR: []string{ + "TEST", + }, + } + output := Print(caseT) + + tests := []string{ + "\t\t\"A\": \"Howdy\",\n", + "\t\t\"B\": 2,\n", + "\t\t\"C\": true,\n", + "\t\t\"D\": 1.5000000004,\n", + "\t\t\"ARR\": [\n", + "\t\t\t\t\"TEST\",\n", + "\t\t],\n", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } +} + +func Test_PrintHyperAnnidated(t *testing.T) { + + caseTest := []interface{}{ + &_Test{ + A: "Howdy", + B: 2, + C: true, + D: 1.5000000004, + ARR: []string{ + "TEST", + }, + }, + map[string]interface{}{ + "At1": "t1", + "At2": GetStringAdddress("t2"), + "Stct1": &_Test{ + A: "Cowboy", + B: 3, + C: false, + D: 1, + }, + }, + } + + output := Print(caseTest) + + tests := []string{ + "\t\t{", + "\t\t\t\t\"A\": \"Howdy\",", + "\t\t\t\t\"B\": 2,", + "\t\t\t\t\"C\": true,", + "\t\t\t\t\"D\": 1.5000000004,", + "\t\t\t\t\"ARR\": [", + "\t\t\t\t\t\t\"TEST\",", + "\t\t\t\t],", + "\t\t},", + "\t\t{", + "\t\t\t\t\"At1\": \"t1\",", + "\t\t\t\t\"At2\": \"t2\",", + "\t\t\t\t\"Stct1\": {", + "\t\t\t\t\t\t\"A\": \"Cowboy\",", + "\t\t\t\t\t\t\"B\": 3,", + "\t\t\t\t\t\t\"C\": false,", + "\t\t\t\t\t\t\"D\": 1,", + "\t\t\t\t\t\t\"ARR\": [", + "\t\t\t\t\t\t],", + "\t\t}", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } +} diff --git a/print_struct_map_test.go b/print_struct_map_test.go new file mode 100644 index 0000000..e6a73ef --- /dev/null +++ b/print_struct_map_test.go @@ -0,0 +1,78 @@ +package pprnt + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type _Test struct { + A string + B int + C bool + D float64 + ARR []string +} + +func Test_PrintStruct(t *testing.T) { + caseT := _Test{ + A: "Howdy", + B: 2, + C: true, + D: 1.5000000004, + ARR: []string{ + "TEST", + }, + } + + output := Print(caseT) + + tests := []string{ + "\t\t\"A\": \"Howdy\",\n", + "\t\t\"B\": 2,\n", + "\t\t\"C\": true,\n", + "\t\t\"D\": 1.5000000004,\n", + "\t\t\"ARR\": [\n", + "\t\t\t\t\"TEST\",\n", + "\t\t],\n", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } +} + +func Test_PrintMap(t *testing.T) { + caseT := map[string]interface{}{ + "A": "Howdy", + "B": 2, + "C": true, + "D": 1.5000000004, + } + + output := Print(caseT) + + tests := []string{ + "\t\t\"A\": \"Howdy\",\n", + "\t\t\"B\": 2,\n", + "\t\t\"C\": true,\n", + "\t\t\"D\": 1.5000000004,\n", + } + + for _, test := range tests { + if !assert.Contains(t, output, test) { + t.Fatalf("Case test failed > " + test) + } + } + + // expected := + // `{ + // "A": "Howdy", + // "B": 2, + // "C": true, + // "D": 1.5000000004, + // } + // ` +} diff --git a/printer/main.go b/printer/main.go deleted file mode 100644 index 2bf5313..0000000 --- a/printer/main.go +++ /dev/null @@ -1,255 +0,0 @@ -package printer - -import ( - "fmt" - "os" - "reflect" - - "github.com/mattn/go-isatty" - "github.com/n3m/pprnt/helpers" -) - -var ( - //IdentString ... - IdentString string = " " - //NoColor ... - NoColor bool = !isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()) -) - -const ( - //ColorReset ... - ColorReset string = "\033[0m" - //ColorRed ... - ColorRed string = "\033[31m" //Not supported or nil - //ColorGreen ... - ColorGreen string = "\033[32m" //String - //ColorYellow ... - ColorYellow string = "\033[33m" //Keys - //ColorBlue ... - ColorBlue string = "\033[34m" //Bool - //ColorPurple ... - ColorPurple string = "\033[35m" //Int floats - //ColorCyan ... - ColorCyan string = "\033[36m" //Brackets or Corch - //ColorGray ... - ColorGray string = "\033[37m" - //ColorWhite ... - ColorWhite string = "\033[97m" -) - -//PrintMap ... -func PrintMap(MAP map[string]interface{}, depth int, detailMode bool) error { - stringToPrint := _CreateDepthString(depth) - - _PrintSymbol("{", stringToPrint) - - //INIT - newIdentDepth := depth + 1 - newDepthString := _CreateDepthString(newIdentDepth) - for key, value := range MAP { - - _PrintMapKey(key, newDepthString) - - newMAPIdentDepth := depth + 1 - switch reflect.ValueOf(value).Kind() { - //Case of Nested Maps or Structs - case reflect.Map, reflect.Struct: - //Value Print - newMAP, err := helpers.ValueToMap(value) - if err != nil { - return err - } - newMAPIdentDepth := depth + 1 - PrintMap(newMAP, newMAPIdentDepth, detailMode) - break - //Case of Nested Array - case reflect.Array, reflect.Slice: - arrVal := value.([]interface{}) - PrintArray(arrVal, newMAPIdentDepth, detailMode) - break - //Case of Regular Value - default: - PrintValue(value, detailMode) - break - } - - } - //FINISH - - if depth > 0 { - _PrintSymbol("},", stringToPrint) - } else { - _PrintSymbol("}", stringToPrint) - } - return nil -} - -//PrintArray ... -func PrintArray(ARR []interface{}, depth int, detailMode bool) error { - stringToPrint := _CreateDepthString(depth) - _PrintSymbol("[", stringToPrint) - - //INIT - newIdentDepth := depth + 1 - newDepthString := _CreateDepthString(newIdentDepth) - for i, value := range ARR { - fmt.Print(fmt.Sprintf("%s[%d]: ", newDepthString, i)) - newMAPIdentDepth := depth + 1 - switch reflect.ValueOf(value).Kind() { - //Case of Nested Maps or Structs - case reflect.Map, reflect.Struct: - //Value Print - newMAP, err := helpers.ValueToMap(value) - if err != nil { - return err - } - newMAPIdentDepth := depth + 1 - PrintMap(newMAP, newMAPIdentDepth, detailMode) - break - //Case of Nested Array - case reflect.Array, reflect.Slice: - arrVal := value.([]interface{}) - PrintArray(arrVal, newMAPIdentDepth, detailMode) - break - //Case of Regular Value - default: - PrintValue(value, detailMode) - break - } - - } - //FINISH - - if depth > 0 { - _PrintSymbol("],", stringToPrint) - } else { - _PrintSymbol("]", stringToPrint) - } - return nil -} - -//PrintNormal ... -func PrintNormal(value interface{}, depth int, detailMode bool) error { - stringToPrint := _CreateDepthString(depth) - if detailMode { - fmt.Println(fmt.Sprintf("%s%#v", stringToPrint, value)) - } else { - fmt.Println(fmt.Sprintf("%s%+v", stringToPrint, value)) - } - return nil -} - -func _CreateDepthString(depth int) string { - depthString := "" - for i := 0; i < depth; i++ { - depthString += IdentString - } - - return depthString -} - -func _PrintSymbol(symbol, stringToPrint string) { - if NoColor { - fmt.Println(fmt.Sprintf("%s%+v", stringToPrint, symbol)) - } else { - fmt.Println(ColorCyan, fmt.Sprintf("%s%+v", stringToPrint, symbol)) - } -} - -func _PrintMapKey(key, newDepthString string) { - if NoColor { - fmt.Print(fmt.Sprintf("%s'%+v': ", newDepthString, key)) - } else { - fmt.Print(ColorYellow, fmt.Sprintf("%s'%+v': ", newDepthString, key)) - } -} - -//PrintValue ... -func PrintValue(value interface{}, detailMode bool) { - switch reflect.ValueOf(value).Kind() { - case - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64: - - if detailMode { - if NoColor { - fmt.Println(fmt.Sprintf("%#v,", value)) - } else { - fmt.Println(ColorPurple, fmt.Sprintf("%#v,", value)) - } - } else { - if NoColor { - fmt.Println(fmt.Sprintf("%+v,", value)) - } else { - fmt.Println(ColorPurple, fmt.Sprintf("%+v,", value)) - } - } - break - case reflect.Bool: - if detailMode { - if NoColor { - fmt.Println(fmt.Sprintf("%#v,", value)) - } else { - fmt.Println(ColorBlue, fmt.Sprintf("%#v,", value)) - } - } else { - if NoColor { - fmt.Println(fmt.Sprintf("%+v,", value)) - } else { - fmt.Println(ColorBlue, fmt.Sprintf("%+v,", value)) - } - } - break - case reflect.Float32, reflect.Float64: - if detailMode { - if NoColor { - fmt.Println(fmt.Sprintf("%#v,", value)) - } else { - fmt.Println(ColorPurple, fmt.Sprintf("%#v,", value)) - } - } else { - if NoColor { - fmt.Println(fmt.Sprintf("%+v,", value)) - } else { - fmt.Println(ColorPurple, fmt.Sprintf("%+v,", value)) - } - } - break - case reflect.String: - if detailMode { - if NoColor { - fmt.Println(fmt.Sprintf("%#v,", value)) - } else { - fmt.Println(ColorGreen, fmt.Sprintf("%#v,", value)) - } - } else { - if NoColor { - fmt.Println(fmt.Sprintf("%+v,", value)) - } else { - fmt.Println(ColorGreen, fmt.Sprintf("\"%+v\",", value)) - } - } - break - default: - test := "" - obtainedVal := fmt.Sprintf("%+v", value) - - if obtainedVal == test { - if NoColor { - fmt.Println(",") - } else { - fmt.Println(ColorRed, ",") - } - - } else { - if NoColor { - fmt.Println("{{Type not supported by PPRNT}}") - } else { - fmt.Println(ColorRed, "{{Type not supported by PPRNT}}") - } - } - - break - } - -} diff --git a/type_helpers.go b/type_helpers.go new file mode 100644 index 0000000..6e50b59 --- /dev/null +++ b/type_helpers.go @@ -0,0 +1,5 @@ +package pprnt + +func GetStringAdddress(arg string) *string { + return &arg +}