Skip to content

Commit 29e693d

Browse files
committed
tests and parsing
1 parent e26027c commit 29e693d

File tree

4 files changed

+95
-21
lines changed

4 files changed

+95
-21
lines changed

file.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"os"
55

66
"github.com/mongodb/grip"
7+
"github.com/mongodb/grip/message"
78
"github.com/pkg/errors"
89
)
910

@@ -19,17 +20,24 @@ func FileExists(path string) bool {
1920
return !os.IsNotExist(err)
2021
}
2122

22-
// WriteFile provides a clearer interface for writing string data to a
23-
// file.
24-
func WriteFile(path string, data string) error {
23+
// WriteRawFile writes a sequence of byes to a new file created at the
24+
// specified path.
25+
func WriteRawFile(path string, data []byte) error {
2526
file, err := os.Create(path)
2627
if err != nil {
2728
return errors.Wrapf(err, "problem creating file '%s'", path)
2829
}
2930

30-
_, err = file.WriteString(data)
31+
n, err := file.Write(data)
3132
if err != nil {
32-
grip.Warning(errors.Wrapf(file.Close(), "problem closing file '%s' after error", path))
33+
grip.Warning(message.WrapError(errors.WithStack(file.Close()),
34+
message.Fields{
35+
"message": "problem closing file after error",
36+
"path": path,
37+
"bytes_written": n,
38+
"input_len": len(data),
39+
}))
40+
3341
return errors.Wrapf(err, "problem writing data to file '%s'", path)
3442
}
3543

@@ -39,3 +47,9 @@ func WriteFile(path string, data string) error {
3947

4048
return nil
4149
}
50+
51+
// WriteFile provides a clearer interface for writing string data to a
52+
// file.
53+
func WriteFile(path string, data string) error {
54+
return errors.WithStack(WriteRawFile(path, []byte(data)))
55+
}

parsing.go

+34-13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package utility
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io"
67
"io/ioutil"
78
"os"
@@ -10,24 +11,30 @@ import (
1011
yaml "gopkg.in/yaml.v2"
1112
)
1213

14+
// ReadYAML provides an alternate interface to yaml.Unmarshal that
15+
// reads data from an io.ReadCloser.
1316
func ReadYAML(r io.ReadCloser, target interface{}) error {
1417
defer r.Close()
15-
bytes, err := ioutil.ReadAll(r)
18+
data, err := ioutil.ReadAll(r)
1619
if err != nil {
1720
return errors.WithStack(err)
1821
}
19-
return errors.WithStack(yaml.Unmarshal(bytes, data))
22+
return errors.WithStack(yaml.Unmarshal(data, target))
2023
}
2124

25+
// ReadJSON provides an alternate interface to json.Unmarshal that
26+
// reads data from an io.ReadCloser.
2227
func ReadJSON(r io.ReadCloser, target interface{}) error {
2328
defer r.Close()
24-
bytes, err := ioutil.ReadAll(r)
29+
data, err := ioutil.ReadAll(r)
2530
if err != nil {
2631
return errors.WithStack(err)
2732
}
28-
return errors.WithStack(json.Unmarshal(bytes, data))
33+
return errors.WithStack(json.Unmarshal(data, target))
2934
}
3035

36+
// ReadYAMLFile parses yaml into the target argument from the file
37+
// located at the specifed path.
3138
func ReadYAMLFile(path string, target interface{}) error {
3239
if !FileExists(path) {
3340
return errors.Errorf("file '%s' does not exist", path)
@@ -38,9 +45,11 @@ func ReadYAMLFile(path string, target interface{}) error {
3845
return errors.Wrapf(err, "invalid file: %s", path)
3946
}
4047

41-
return errors.Wrap(ReadYAML(file, target), "problem reading yaml from '%s'", path)
48+
return errors.Wrapf(ReadYAML(file, target), "problem reading yaml from '%s'", path)
4249
}
4350

51+
// ReadJSONFile parses json into the target argument from the file
52+
// located at the specifed path.
4453
func ReadJSONFile(path string, target interface{}) error {
4554
if !FileExists(path) {
4655
return errors.Errorf("file '%s' does not exist", path)
@@ -51,27 +60,39 @@ func ReadJSONFile(path string, target interface{}) error {
5160
return errors.Wrapf(err, "invalid file: %s", path)
5261
}
5362

54-
return errors.Wrap(ReadYAML(file, target), "problem reading json from '%s'", path)
63+
return errors.Wrapf(ReadYAML(file, target), "problem reading json from '%s'", path)
5564
}
5665

57-
func WriteJSON(out io.Writer, data interface{}) error {
58-
out, err := json.Marshal(data)
66+
// PrintJSON marshals the data to a pretty-printed (indented) string
67+
// and then prints it to standard output.
68+
func PrintJSON(data interface{}) error {
69+
out, err := json.MarshalIndent(data, "", " ")
5970
if err != nil {
60-
return errors.Wrap(err, "problem writing JSON")
71+
return errors.Wrap(err, "problem writing data")
6172
}
6273

74+
fmt.Println(string(out))
6375
return nil
6476
}
6577

78+
// WriteJSONFile marshals the data into json and writes it into a file
79+
// at the specified path.
6680
func WriteJSONFile(fn string, data interface{}) error {
67-
file, err := os.Create(fn)
81+
payload, err := json.Marshal(data)
6882
if err != nil {
69-
return errors.Wrapf(err, "problem creating file '%s'", fn)
83+
return errors.Wrap(err, "problem constructing JSON")
7084
}
7185

72-
err = WriteJSON(file, data)
73-
if err != nil {
86+
return errors.WithStack(WriteRawFile(fn, payload))
87+
}
7488

89+
// WriteYAMLFile marshals the data into json and writes it into a file
90+
// at the specified path.
91+
func WriteYAMLFile(fn string, data interface{}) error {
92+
payload, err := yaml.Marshal(data)
93+
if err != nil {
94+
return errors.Wrap(err, "problem constructing YAML")
7595
}
7696

97+
return errors.WithStack(WriteRawFile(fn, payload))
7798
}

random.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ import (
55
"encoding/hex"
66
)
77

8-
// RandomString returns a cryptographically random string.
9-
func RandomString() string {
10-
b := make([]byte, 16)
8+
// MakeRandomString constructs a hex-encoded random string of a
9+
// specific length. The size reflects the number of random bytes, not
10+
// the length of the string.
11+
func MakeRandomString(size int) string {
12+
b := make([]byte, size)
1113
_, _ = rand.Read(b)
1214
return hex.EncodeToString(b)
15+
1316
}
17+
18+
// RandomString returns a hex-encoded cryptographically random string.
19+
// This function always returns 16bytes of randomness encoded in a 32
20+
// character string.
21+
func RandomString() string { return MakeRandomString(16) }

random_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package utility
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestRandom(t *testing.T) {
10+
t.Run("Legacy", func(t *testing.T) {
11+
r1 := RandomString()
12+
r2 := RandomString()
13+
assert.NotEqual(t, r1, r2)
14+
assert.Len(t, RandomString(), 32)
15+
})
16+
t.Run("Sized", func(t *testing.T) {
17+
assert.Len(t, MakeRandomString(32), 64)
18+
assert.Len(t, MakeRandomString(64), 128)
19+
assert.Len(t, MakeRandomString(2), 4)
20+
assert.Len(t, MakeRandomString(1), 2)
21+
assert.Len(t, MakeRandomString(3), 6)
22+
23+
for i := 1; i < 100; i++ {
24+
a := MakeRandomString(i)
25+
b := MakeRandomString(i)
26+
assert.Equal(t, len(a), len(b))
27+
assert.NotEqual(t, a, b)
28+
assert.Len(t, a, 2*i)
29+
}
30+
})
31+
}

0 commit comments

Comments
 (0)