Skip to content

Commit

Permalink
Update mapsutil #13 (#14)
Browse files Browse the repository at this point in the history
* Update mapsutil #13

* refactoring clear func

* adding clear's tests

* fixing execs on windows

* run sh only on unix system

Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
  • Loading branch information
edoardottt and Mzack9999 committed Nov 6, 2022
1 parent 9bda3fc commit c62b9b7
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 16 deletions.
4 changes: 4 additions & 0 deletions exec/executil.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"io"
"os/exec"
"runtime"
)

const (
Expand Down Expand Up @@ -105,6 +106,9 @@ func splitCmdArgs(cmds string) []string {

// Run the specified command and return the output
func Run(cmd string) (string, error) {
if runtime.GOOS == "windows" {
return "", errors.New("can't execute sh on windows platform")
}
return RunSh(splitCmdArgs(cmd)...)
}

Expand Down
6 changes: 6 additions & 0 deletions exec/executil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ func init() {
}

func TestRun(t *testing.T) {
if runtime.GOOS == "windows" {
return
}
// try to run the echo command
s, err := Run("echo test")
require.Nil(t, err, "failed execution", err)
require.Equal(t, "test"+newLineMarker, s, "output doesn't contain expected result", s)
}

func TestRunSh(t *testing.T) {
if runtime.GOOS == "windows" {
return
}
// try to run the echo command
s, err := RunSh("echo", "test")
require.Nil(t, err, "failed execution", err)
Expand Down
37 changes: 33 additions & 4 deletions maps/mapsutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"time"

"github.com/miekg/dns"
"golang.org/x/exp/maps"
extmaps "golang.org/x/exp/maps"
)

// MergeMaps merges the inputted maps into a new one.
// Merge merges the inputted maps into a new one.
// Be aware: In case of duplicated keys in multiple maps,
// the one ending in the result is unknown a priori.
func MergeMaps[K comparable, V any](maps ...map[K]V) (result map[K]V) {
func Merge[K comparable, V any](maps ...map[K]V) (result map[K]V) {
result = make(map[K]V)

for _, m := range maps {
Expand Down Expand Up @@ -102,8 +103,8 @@ func DNSToMap(msg *dns.Msg, format string) (m map[string]interface{}) {
return m
}

// HTTPRequesToMap Converts HTTP Request to Matcher Map
func HTTPRequesToMap(req *http.Request) (map[string]interface{}, error) {
// HTTPRequestToMap Converts HTTP Request to Matcher Map
func HTTPRequestToMap(req *http.Request) (map[string]interface{}, error) {
m := make(map[string]interface{})
var headers string
for k, v := range req.Header {
Expand Down Expand Up @@ -224,3 +225,31 @@ func Walk(m map[string]any, callback func(k string, v any)) {
}
}
}

// Clear the map passed as parameter
func Clear[K comparable, V any](mm ...map[K]V) {
for _, m := range mm {
maps.Clear(m)
}
}

// SliceToMap returns a map having as keys the elements in
// even positions and as values the elements in odd positions.
// If the number of elements is odd the default value applies.
func SliceToMap[T comparable](s []T, dflt T) map[T]T {
result := map[T]T{}

for i := 0; i < len(s); i += 2 {
if i+1 < len(s) {
result[s[i]] = s[i+1]
} else {
result[s[i]] = dflt
}
}
return result
}

// IsEmpty checks if a map is empty.
func IsEmpty[K comparable, V any](m map[K]V) bool {
return len(m) == 0
}
149 changes: 137 additions & 12 deletions maps/mapsutil_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package mapsutil

import (
"crypto/tls"
"io"
"net/http"
"net/url"
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"
)
Expand All @@ -10,31 +16,89 @@ func TestMergeMaps(t *testing.T) {
m1Str := map[string]interface{}{"a": 1, "b": 2}
m2Str := map[string]interface{}{"b": 2, "c": 3}
rStr := map[string]interface{}{"a": 1, "b": 2, "c": 3}
rrStr := MergeMaps(m1Str, m2Str)
rrStr := Merge(m1Str, m2Str)
require.EqualValues(t, rStr, rrStr)

m1Int := map[int]interface{}{1: 1, 2: 2}
m2Int := map[int]interface{}{1: 1, 2: 2, 3: 3, 4: 4}
m3Int := map[int]interface{}{1: 1, 5: 5}
rInt := map[int]interface{}{1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
rrInt := MergeMaps(m1Int, m2Int, m3Int)
rrInt := Merge(m1Int, m2Int, m3Int)
require.EqualValues(t, rInt, rrInt)
}

var (
req = &http.Request{
Method: "POST",
URL: &url.URL{
Scheme: "http",
Host: "test.ts",
Path: "/",
},
Host: "test.ts",
Proto: "HTTP/1.1",
ProtoMajor: 2,
ProtoMinor: 1,
Header: http.Header{},
Body: io.NopCloser(strings.NewReader("test")),
ContentLength: 1000,
TransferEncoding: []string{""},
Close: true,
Trailer: http.Header{},
TLS: &tls.ConnectionState{},
}

resp = &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.1",
ProtoMajor: 2,
ProtoMinor: 1,
Header: http.Header{},
Body: io.NopCloser(strings.NewReader("test")),
ContentLength: 1000,
TransferEncoding: []string{""},
Close: true,
Uncompressed: false,
Trailer: http.Header{},
Request: &http.Request{},
TLS: &tls.ConnectionState{},
}
)

func TestHTTPToMap(t *testing.T) {
// not implemented
bufBody := new(strings.Builder)
// nolint:errcheck
io.Copy(bufBody, resp.Body)

bufHeaders := new(strings.Builder)
// nolint:errcheck
io.Copy(bufHeaders, resp.Body)

m := HTTPToMap(resp, bufBody.String(), bufHeaders.String(), time.Duration(2), "")

require.NotNil(t, m)
require.NotEmpty(t, m)
}

func TestDNSToMap(t *testing.T) {
// not implemented
}

func TestHTTPRequesToMap(t *testing.T) {
// not implemented
func TestHTTPRequestToMap(t *testing.T) {
m, err := HTTPRequestToMap(req)

require.Nil(t, err)
require.NotNil(t, m)
require.NotEmpty(t, m)
}

func TestHTTPResponseToMap(t *testing.T) {
// not implemented
m, err := HTTPResponseToMap(resp)

require.Nil(t, err)
require.NotNil(t, m)
require.NotEmpty(t, m)
}

func TestGetKeys(t *testing.T) {
Expand All @@ -45,17 +109,17 @@ func TestGetKeys(t *testing.T) {

t.Run("GetKeys(string)", func(t *testing.T) {
got := GetKeys(map[string]interface{}{"a": "a", "b": "b"})
require.EqualValues(t, []string{"a", "b"}, got)
require.ElementsMatch(t, []string{"a", "b"}, got)
})

t.Run("GetKeys(int)", func(t *testing.T) {
got := GetKeys(map[int]interface{}{1: "a", 2: "b"})
require.EqualValues(t, []int{1, 2}, got)
require.ElementsMatch(t, []int{1, 2}, got)
})

t.Run("GetKeys(bool)", func(t *testing.T) {
got := GetKeys(map[bool]interface{}{true: "a", false: "b"})
require.EqualValues(t, []bool{true, false}, got)
require.ElementsMatch(t, []bool{true, false}, got)
})
}

Expand All @@ -67,17 +131,17 @@ func TestGetValues(t *testing.T) {

t.Run("GetValues(string)", func(t *testing.T) {
got := GetValues(map[string]interface{}{"a": "a", "b": "b"})
require.EqualValues(t, []interface{}{"a", "b"}, got)
require.ElementsMatch(t, []interface{}{"a", "b"}, got)
})

t.Run("GetValues(int)", func(t *testing.T) {
got := GetValues(map[string]interface{}{"a": 1, "b": 2})
require.EqualValues(t, []interface{}{1, 2}, got)
require.ElementsMatch(t, []interface{}{1, 2}, got)
})

t.Run("GetValues(bool)", func(t *testing.T) {
got := GetValues(map[string]interface{}{"a": true, "b": false})
require.EqualValues(t, []interface{}{true, false}, got)
require.ElementsMatch(t, []interface{}{true, false}, got)
})
}

Expand All @@ -102,3 +166,64 @@ func TestDifference(t *testing.T) {
require.EqualValues(t, map[bool]interface{}{false: 2}, got)
})
}

func TestSliceToMap(t *testing.T) {
t.Run("SliceToMap(empty)", func(t *testing.T) {
got := SliceToMap([]string{}, "")
require.EqualValues(t, map[string]string{}, got)
})

t.Run("SliceToMap(string)", func(t *testing.T) {
got := SliceToMap([]string{"a", "b", "c", "d"}, "")
require.EqualValues(t, map[string]string{"a": "b", "c": "d"}, got)
})

t.Run("SliceToMap(string odd)", func(t *testing.T) {
got := SliceToMap([]string{"a", "b", "c"}, "")
require.EqualValues(t, map[string]string{"a": "b", "c": ""}, got)
})

t.Run("SliceToMap(int odd)", func(t *testing.T) {
got := SliceToMap([]int{1, 2, 3}, 0)
require.EqualValues(t, map[int]int{1: 2, 3: 0}, got)
})
}

func TestIsEmpty(t *testing.T) {
t.Run("IsEmpty(empty)", func(t *testing.T) {
got := IsEmpty(map[string]string{})
require.EqualValues(t, true, got)
})

t.Run("IsEmpty(string)", func(t *testing.T) {
got := IsEmpty(map[string]string{"a": "b"})
require.EqualValues(t, false, got)
})

t.Run("IsEmpty(int)", func(t *testing.T) {
got := IsEmpty(map[int]int{1: 2})
require.EqualValues(t, false, got)
})
}

func TestClear(t *testing.T) {
t.Run("Clear(nil)", func(t *testing.T) {
var m map[string]string
Clear(m)
require.Empty(t, m)
})

t.Run("Clear(m)", func(t *testing.T) {
m := map[string]string{"a": "a", "b": "b"}
Clear(m)
require.Empty(t, m)
})

t.Run("Clear(m1,m2)", func(t *testing.T) {
m1 := map[string]string{"a": "a", "b": "b"}
m2 := map[string]string{"a": "a", "b": "b"}
Clear(m1, m2)
require.Empty(t, m1)
require.Empty(t, m2)
})
}

0 comments on commit c62b9b7

Please sign in to comment.