Add deduceConstraint test

There's still work needed here for the autoconverter in legacy, but at
least we're now reasonably well-assured that it's working correctly for
bzr's weird guid revs.
diff --git a/cfg/config.go b/cfg/config.go
index f0e1248..d600ac3 100644
--- a/cfg/config.go
+++ b/cfg/config.go
@@ -495,7 +495,8 @@
 		return c
 	}
 
-	if len(s) == 40 {
+	slen := len(s)
+	if slen == 40 {
 		if _, err = hex.DecodeString(s); err == nil {
 			// Whether or not it's intended to be a SHA1 digest, this is a
 			// valid byte sequence for that, so go with Revision. This
@@ -509,9 +510,14 @@
 	if strings.Count(s, "-") >= 2 {
 		// Work from the back to avoid potential confusion from the email
 		i3 := strings.LastIndex(s, "-")
-		if _, err = hex.DecodeString(s[i3:]); err == nil {
+		// Skip if - is last char, otherwise this would panic on bounds err
+		if slen == i3+1 {
+			return gps.NewVersion(s)
+		}
+
+		if _, err = hex.DecodeString(s[i3+1:]); err == nil {
 			i2 := strings.LastIndex(s[:i3], "-")
-			if _, err = strconv.ParseUint(s[i2:i3], 10, 64); err != nil {
+			if _, err = strconv.ParseUint(s[i2+1:i3], 10, 64); err == nil {
 				// Getting this far means it'd pretty much be nuts if it's not a
 				// bzr rev, so don't bother parsing the email.
 				return gps.Revision(s)
diff --git a/cfg/config_test.go b/cfg/config_test.go
index db563dd..bbdfc48 100644
--- a/cfg/config_test.go
+++ b/cfg/config_test.go
@@ -282,13 +282,13 @@
 			}
 		}
 	}
+
 	if !found {
 		t.Error("Unable to find github.com/Masterminds/convert")
 	}
 	if !found2 {
 		t.Error("Unable to find github.com/Masterminds/structable")
 	}
-
 }
 
 func TestConfigFromYaml(t *testing.T) {
@@ -356,3 +356,47 @@
 		t.Error("Unable to parse owners from yaml")
 	}
 }
+
+func TestDeduceConstraint(t *testing.T) {
+	// First, valid semver
+	c := deduceConstraint("v1.0.0")
+	if c.(gps.Version).Type() != "semver" {
+		t.Errorf("Got unexpected version type when passing valid semver string: %T %s", c, c)
+	}
+
+	// Now, 20 hex-encoded bytes (which should be assumed to be a SHA1 digest)
+	revin := "a9949121a2e2192ca92fa6dddfeaaa4a4412d955"
+	c = deduceConstraint(revin)
+	if c != gps.Revision(revin) {
+		t.Errorf("Got unexpected version type/val when passing hex-encoded SHA1 digest: %T %s", c, c)
+	}
+
+	// Now, the weird bzr guid
+	bzrguid := "john@smith.org-20051026185030-93c7cad63ee570df"
+	c = deduceConstraint(bzrguid)
+	if c != gps.Revision(bzrguid) {
+		t.Errorf("Expected revision with valid bzr guid, got: %T %s", c, c)
+	}
+
+	// Check fails if the bzr rev is malformed or weirdly formed
+	//
+	// chopping off a char should make the hex decode check fail
+	c = deduceConstraint(bzrguid[:len(bzrguid)-1])
+	if c != gps.NewVersion(bzrguid[:len(bzrguid)-1]) {
+		t.Errorf("Expected plain version when bzr guid has truncated tail hex bits: %T %s", c, c)
+	}
+
+	// Extra dash in email doesn't mess us up
+	bzrguid2 := "john-smith@smith.org-20051026185030-93c7cad63ee570df"
+	c = deduceConstraint(bzrguid2)
+	if c != gps.Revision(bzrguid2) {
+		t.Errorf("Expected revision when passing bzr guid has extra dash in email, got: %T %s", c, c)
+	}
+
+	// Non-numeric char in middle section bites it
+	bzrguid3 := "john-smith@smith.org-2005102a6185030-93c7cad63ee570df"
+	c = deduceConstraint(bzrguid3)
+	if c != gps.NewVersion(bzrguid3) {
+		t.Errorf("Expected plain version when bzr guid has invalid second section, got: %T %s", c, c)
+	}
+}