summaryrefslogtreecommitdiff
path: root/tests/uuid.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/uuid.go387
1 files changed, 371 insertions, 16 deletions
diff --git a/tests/uuid.go b/tests/uuid.go
index ad9cac4..912339a 100644
--- a/tests/uuid.go
+++ b/tests/uuid.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/hex"
"fmt"
+ "io"
"os"
"reflect"
"strings"
@@ -50,18 +51,24 @@ func assertEq(given any, expected any) {
}
-func test_NewFrom() {
- testStart("NewFrom()")
+
+func test_NewV4From() {
+ testStart("NewV4From()")
+
+ testing("we propagate the error when it happens", func() {
+ _, err := NewV4From(strings.NewReader(""))
+ assertEq(err, io.EOF)
+ })
testing("we get the same UUID from the same input", func() {
const s = "abcdefghijklmnop"
r1 := strings.NewReader(s)
- uuid1, err := NewFrom(r1)
+ uuid1, err := NewV4From(r1)
assertEq(err, nil)
r2 := strings.NewReader(s)
- uuid2, err := NewFrom(r2)
+ uuid2, err := NewV4From(r2)
assertEq(err, nil)
assertEq(uuid1, uuid2)
@@ -107,7 +114,7 @@ func test_NewFrom() {
}
r := bytes.NewReader(input)
- given, err := NewFrom(r)
+ given, err := NewV4From(r)
assertEq(err, nil)
assertEq(given, expected)
})
@@ -152,30 +159,166 @@ func test_NewFrom() {
}
r := bytes.NewReader(input)
- given, err := NewFrom(r)
+ given, err := NewV4From(r)
assertEq(err, nil)
assertEq(given, expected)
})
}
-func test_New() {
- testStart("New()")
+func test_NewV4() {
+ testStart("NewV4()")
testing("we can generate UUID values: ", func() {
- var uuid UUID = New()
- assertEq(len(uuid), 16)
+ var uuid UUID = NewV4()
+ assertEq(uuid == Nil, false)
+ assertEq(uuid == Max, false)
})
testing("panic when the randomReader fails", func() {
savedReader := randomReader
- randomReader = strings.NewReader("abc")
+ randomReader = strings.NewReader("")
+ defer func() {
+ r := recover()
+ assertEq(r, io.EOF)
+ randomReader = savedReader
+ }()
+
+ NewV4()
+ os.Exit(5)
+ })
+}
+
+func test_NewV7From() {
+ testStart("NewV7From()")
+
+ testing("reader error is propagated", func() {
+ nowFn := func() uint64 {
+ return 0
+ }
+
+ _, err := NewV7From(strings.NewReader(""), nowFn)
+ assertEq(err, io.EOF)
+ })
+
+ testing("we get the same UUID given the same input", func() {
+ const s = "abcdefgh"
+ nowFn := func() uint64 {
+ return 0
+ }
+
+ r1 := strings.NewReader(s)
+ uuid1, err := NewV7From(r1, nowFn)
+ assertEq(err, nil)
+
+ r2 := strings.NewReader(s)
+ uuid2, err := NewV7From(r2, nowFn)
+ assertEq(err, nil)
+
+ assertEq(uuid1, uuid2)
+ })
+
+ testing("the bytes are what the reader plus the time gives", func() {
+ randomInput := []byte{
+ 0x00,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ }
+
+ nowFn := func() uint64 {
+ return 0xffffffff00000000
+ }
+
+ expected := UUID{
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0x00,
+ 0x00,
+ 0x00 + 0x70,
+ 0x00,
+ 0x00 + 0x80,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ }
+
+ r := bytes.NewReader(randomInput)
+ given, err := NewV7From(r, nowFn)
+ assertEq(err, nil)
+ assertEq(given, expected)
+ })
+
+ testing("v7 and variant markers", func() {
+ randomInput := []byte{
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ }
+
+ nowFn := func() uint64 {
+ return 0x1111111111111111
+ }
+
+ expected := UUID{
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x71, // not 0x11
+ 0x11,
+ 0x91, // not 0x11
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ }
+
+ r := bytes.NewReader(randomInput)
+ given, err := NewV7From(r, nowFn)
+ assertEq(err, nil)
+ assertEq(given, expected)
+ })
+}
+
+func test_NewV7() {
+ testStart("NewV7()")
+
+ testing("we can generate UUID values: ", func() {
+ var uuid UUID = NewV7()
+ assertEq(uuid == Nil, false)
+ assertEq(uuid == Max, false)
+ })
+
+ testing("panic when reader fails", func() {
+ savedReader := randomReader
+ randomReader = strings.NewReader("")
defer func() {
r := recover()
- assertEq(r == nil, false)
+ assertEq(r, io.EOF)
randomReader = savedReader
}()
- New()
+ NewV7()
os.Exit(5)
})
}
@@ -224,7 +367,7 @@ func test_FromString() {
testing("UUID -> string -> UUID round trip", func() {
for i := 0; i < 100; i++ {
- uuid0 := New()
+ uuid0 := NewV4()
uuid1, err := FromString(uuid0.String())
assertEq(err, nil)
assertEq(uuid0, uuid1)
@@ -251,11 +394,223 @@ func test_FromString() {
})
}
+func test_usage() {
+ testStart("usage()")
+
+ testing("all it does is write to the given io.Writer", func() {
+ w := strings.Builder{}
+ usage("xxx", &w)
+
+ const expectedRaw = `
+ Usage:
+ xxx [-v (4|7)]
+ xxx STRING
+ `
+ expected := strings.Trim(
+ strings.ReplaceAll(expectedRaw, "\t", ""),
+ "\n",
+ ) + "\n"
+ assertEq(w.String(), expected)
+ })
+}
+
+func test_actionForSubargs() {
+ testStart("actionForSubargs()")
+
+ testing("we decide based only on length", func() {
+ assertEq(actionForSubargs([]string{}), actionType_generate)
+ assertEq(actionForSubargs([]string{""}), actionType_parse)
+ assertEq(actionForSubargs([]string{"id"}), actionType_parse)
+ })
+}
+
+func test_getopt() {
+ testStart("getopt()")
+
+ const usageRaw = `
+ Usage:
+ $0 [-v (4|7)]
+ $0 STRING
+ `
+ usage := strings.Trim(
+ strings.ReplaceAll(usageRaw, "\t", ""),
+ "\n",
+ ) + "\n"
+
+ testing("we supress the default error message", func() {
+ w := strings.Builder{}
+ argv := []string{"$0", "-h"}
+ _, rc := getopt(argv, &w)
+
+ assertEq(w.String(), usage)
+ assertEq(rc, 2)
+ })
+
+ testing("we get unsupported flag error", func() {
+ w := strings.Builder{}
+ argv := []string{"$0", "-Z"}
+ _, rc := getopt(argv, &w)
+
+ const message = "flag provided but not defined: -Z\n"
+ assertEq(w.String(), message + usage)
+ assertEq(rc, 2)
+ })
+
+ testing("we get incorrect use of flag error", func() {
+ w := strings.Builder{}
+ argv := []string{"$0", "-v"}
+ _, rc := getopt(argv, &w)
+
+ const message = "flag needs an argument: -v\n"
+ assertEq(w.String(), message + usage)
+ assertEq(rc, 2)
+ })
+
+ testing("we get bad flag value error", func() {
+ w := strings.Builder{}
+ argv := []string{"$0", "-v", "a"}
+ _, rc := getopt(argv, &w)
+
+ const message = "invalid value \"a\" for flag -v: parse error\n"
+ assertEq(w.String(), message + usage)
+ assertEq(rc, 2)
+ })
+
+ testing("the args has the picked version", func() {
+ var (
+ w1 = strings.Builder{}
+ w2 = strings.Builder{}
+ w3 = strings.Builder{}
+ )
+
+ argsIn1 := []string{"$0"}
+ argsIn2 := []string{"$0", "-v", "4"}
+ argsIn3 := []string{"$0", "-v", "7"}
+
+ args1, rc1 := getopt(argsIn1, &w1)
+ args2, rc2 := getopt(argsIn2, &w2)
+ args3, rc3 := getopt(argsIn3, &w3)
+
+ expected1 := argsT{
+ allArgs: []string{"$0"},
+ subArgs: []string{},
+ action: actionType_generate,
+ version: 4,
+ }
+ expected2 := argsT{
+ allArgs: []string{"$0", "-v", "4"},
+ subArgs: []string{},
+ action: actionType_generate,
+ version: 4,
+ }
+ expected3 := argsT{
+ allArgs: []string{"$0", "-v", "7"},
+ subArgs: []string{},
+ action: actionType_generate,
+ version: 7,
+ }
+
+ assertEq(w1.String(), "")
+ assertEq(w2.String(), "")
+ assertEq(w3.String(), "")
+ assertEq(rc1, 0)
+ assertEq(rc2, 0)
+ assertEq(rc3, 0)
+ assertEq(args1, expected1)
+ assertEq(args2, expected2)
+ assertEq(args3, expected3)
+ })
+
+ testing("the args has the picked action", func() {
+ var (
+ w1 = strings.Builder{}
+ w2 = strings.Builder{}
+ )
+
+ argsIn1 := []string{"$0", "the-string"}
+ argsIn2 := []string{"$0", "-v", "7", "the-string"}
+
+ args1, rc1 := getopt(argsIn1, &w1)
+ args2, rc2 := getopt(argsIn2, &w2)
+
+ expected1 := argsT{
+ allArgs: []string{"$0", "the-string"},
+ subArgs: []string{"the-string"},
+ action: actionType_parse,
+ version: 4,
+ }
+ expected2 := argsT{
+ allArgs: []string{"$0", "-v", "7", "the-string"},
+ subArgs: []string{"the-string"},
+ action: actionType_parse,
+ version: 7,
+ }
+
+ assertEq(w1.String(), "")
+ assertEq(w2.String(), "")
+ assertEq(rc1, 0)
+ assertEq(rc2, 0)
+ assertEq(args1, expected1)
+ assertEq(args2, expected2)
+ })
+}
+
+func test_run() {
+ testStart("run()")
+
+ testing("generating IDs gives us 0 rc", func() {
+ out1 := strings.Builder{}
+ out2 := strings.Builder{}
+ args1 := argsT{
+ action: actionType_generate,
+ version: 4,
+ }
+ args2 := argsT{
+ action: actionType_generate,
+ version: 7,
+ }
+
+ rc1 := run(args1, nil, &out1, nil)
+ rc2 := run(args2, nil, &out2, nil)
+
+ assertEq(rc1, 0)
+ assertEq(rc2, 0)
+ assertEq(len(out1.String()), encodedLength + len("\n"))
+ assertEq(len(out2.String()), encodedLength + len("\n"))
+ })
+
+ testing("parsing varies based on ID validity", func() {
+ const id = "ggggggg-ggggg-gggg-gggg-gggggggggggg"
+ err1 := strings.Builder{}
+ args1 := argsT{
+ action: actionType_parse,
+ subArgs: []string{ id },
+ }
+ args2 := argsT{
+ action: actionType_parse,
+ subArgs: []string{New().String()},
+ }
+
+ rc1 := run(args1, nil, nil, &err1)
+ rc2 := run(args2, nil, nil, nil)
+
+ assertEq(rc1, 3)
+ assertEq(rc2, 0)
+ assertEq(err1.String(), "uuid: Bad char in string\n")
+ })
+}
+
func MainTest() {
- test_NewFrom()
- test_New()
+ test_NewV4From()
+ test_NewV4()
+ test_NewV7From()
+ test_NewV7()
test_String()
test_FromString()
+ test_usage()
+ test_actionForSubargs()
+ test_getopt()
+ test_run()
}