// 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 correctly encode a "non-nice" uuid (with first bit set) to // its known slug. The specific uuid was chosen since it has a slug which // contains both `-` and `_` characters. func TestEncode(t *testing.T) { // 10000000010011110011111111001000110111111100101101001011000001101000100111111011101011101111101011010101111000011000011101010100.... // <8 ><0 ><4 ><f ><3 ><f ><c ><8 ><d ><f ><c ><b ><4 ><b ><0 ><6 ><8 ><9 ><f ><b ><a ><e ><f ><a ><d ><5 ><e ><1 ><8 ><7 ><5 ><4 > // < g >< E >< 8 >< _ >< y >< N >< _ >< L >< S >< w >< a >< J >< - >< 6 >< 7 >< 6 >< 1 >< e >< G >< H >< V >< A > uuid_ := uuid.Parse("804f3fc8-dfcb-4b06-89fb-aefad5e18754") expectedSlug := "gE8_yN_LSwaJ-6761eGHVA" actualSlug := slugid.Encode(uuid_) if expectedSlug != actualSlug { t.Errorf("UUID not correctly encoded into slug: '" + expectedSlug + "' != '" + actualSlug + "'") } }
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 ExampleEncode() { fmt.Println(slugid.Encode(uuid.Parse("796220c0-c831-49f7-9743-7ea23db3b189"))) // Output: eWIgwMgxSfeXQ36iPbOxiQ }