// Test that 10000 v4 slugs are unchanged after decoding and then encoding them. func TestSlugDecodeEncode(t *testing.T) { for i := 0; i < 10000; i++ { slug1 := slugid.V4() uuid_ := slugid.Decode(slug1) slug2 := slugid.Encode(uuid_) if slug1 != slug2 { t.Errorf("Decode and encode isn't identity: '%s' != '%s'", slug1, slug2) } } }
// Test that 10000 v4 uuids are unchanged after encoding and then decoding them func TestUuidEncodeDecode(t *testing.T) { for i := 0; i < 10000; i++ { uuid1 := uuid.NewRandom() slug := slugid.Encode(uuid1) uuid2 := slugid.Decode(slug) if uuid1.String() != uuid2.String() { t.Errorf("Encode and decode isn't identity: '%s' != '%s'", uuid1, uuid2) } } }
// Test that we can decode a "non-nice" slug (first bit of uuid is set) that // begins with `-` func TestDecode(t *testing.T) { // 11111011111011111011111011111011111011111011111001000011111011111011111111111111111111111111111111111111111111111111111111111101.... // <f ><b ><e ><f ><b ><e ><f ><b ><e ><f ><b ><e ><4 ><3 ><e ><f ><b ><f ><f ><f ><f ><f ><f ><f ><f ><f ><f ><f ><f ><f ><f ><d > // < - >< - >< - >< - >< - >< - >< - >< - >< Q >< - >< - >< - >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< _ >< Q > slug := "--------Q--__________Q" expectedUuid := uuid.Parse("fbefbefb-efbe-43ef-bfff-fffffffffffd") actualUuid := slugid.Decode(slug) if expectedUuid.String() != actualUuid.String() { t.Errorf("Slug not correctly decoded into uuid: '%s' != '%s'", expectedUuid, actualUuid) } }
func main() { arguments, err := docopt.Parse(usage, nil, true, version, false, true) if err != nil { fmt.Println("Error parsing command line arguments!") panic(err) } // fmt.Printf("args: %s\n", arguments) // 'slug encode' and 'slug decode' (without further args) can be // misinterpreted as being 'slug COUNT'. Don't exit 0 since e.g. 'slug -n // encode' should return error, just fix the parsing. if c := arguments["COUNT"]; c != nil { if c == "encode" || c == "decode" { arguments[c.(string)] = true arguments["COUNT"] = nil } } switch { case arguments["-v"]: fmt.Println(version) case arguments["decode"]: x := arguments["SLUGID"] // utility function to handle returning bad exit codes for invalid slugs decode := func(slug string) { uuid_ := slugid.Decode(slug) if uuid_ != nil { fmt.Println(uuid_.String()) } else { fmt.Fprintf(os.Stderr, "slug: ERROR: Cannot decode invalid slug '%v' into a UUID\n", slug) os.Exit(64) } } if (x != nil && len(x.([]string)) == 1 && x.([]string)[0] == "-") || arguments["-"].(bool) { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { decode(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "slug: ERROR: Problem reading standard input during slug decoding:", err) os.Exit(65) } return } for _, slug := range x.([]string) { decode(slug) } case arguments["encode"]: x := arguments["UUID"] // utility function to handle returning bad exit codes for invalid uuids encode := func(uuidStr string) { uuid_ := uuid.Parse(uuidStr) if uuid_ != nil { slug := slugid.Encode(uuid_) fmt.Println(slug) } else { fmt.Fprintf(os.Stderr, "slug: ERROR: Cannot encode invalid uuid '%v' into a slug\n", uuidStr) os.Exit(66) } } if (x != nil && len(x.([]string)) == 1 && x.([]string)[0] == "-") || arguments["-"].(bool) { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { encode(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "slug: ERROR: Problem reading standard input during slug encoding:", err) os.Exit(67) } return } for _, slug := range x.([]string) { encode(slug) } default: count := 1 if c := arguments["COUNT"]; c != nil { var err error = nil count, err = strconv.Atoi(c.(string)) if err != nil { fmt.Fprintf(os.Stderr, "slug: ERROR: Invalid value '%v' passed in for command line option COUNT, since COUNT must be a number. Run `slug --help` for more details.\n", c) os.Exit(68) } // it is not possible for count < 0 since tokens beginning with '-' // are treated as command line options and failure would have // occured, therefore we do not need to handle this failure case } var generator func() string switch { case arguments["-r"], arguments["--v4"]: generator = slugid.V4 default: generator = slugid.Nice } for i := 0; i < count; i++ { fmt.Println(generator()) } } }
func TestDecodeInvalidSlug(t *testing.T) { uuid_ := slugid.Decode("not really a slug") if uuid_ != nil { t.Errorf("Decoding an invalid slug should return nil, but returned %s.", uuid_) } }
func ExampleDecode() { fmt.Printf("%s\n", slugid.Decode("eWIgwMgxSfeXQ36iPbOxiQ")) // Output: 796220c0-c831-49f7-9743-7ea23db3b189 }