fix(lookup): QRZ Name is the first name, not first + surname
A log greets an operator; it does not address an envelope. "Robert Smith" filled the Name field with something no one would ever send on the air, and it is the first name that gets used when the contact is answered. So fname alone, with the surname kept only as a last resort for a record that has no first name at all — better a surname than an empty field. The nickname option now falls back to the first name too, which is what it should have done from the start. joinName went with it: nothing composed a name any more.
This commit is contained in:
+2
-2
@@ -5,12 +5,12 @@
|
||||
"en": [
|
||||
"Cluster: \"Hide worked\" no longer hides a spot that is a new prefix, county, grid or park in an entity already worked.",
|
||||
"DX Cluster: a spot lifetime can be set — 5, 10, 15 minutes or your own value — after which spots leave the list and the band maps.",
|
||||
"Call lookup: an option makes QRZ.com use the operator nickname as the name, falling back to the full name when none is published."
|
||||
"Call lookup: QRZ.com now fills Name with the first name only, and optionally with the operator nickname instead."
|
||||
],
|
||||
"fr": [
|
||||
"Cluster : « Masquer les contactés » ne masque plus un spot qui est un nouveau préfixe, comté, carré ou parc dans une contrée déjà faite.",
|
||||
"Cluster DX : on peut fixer une durée de vie des spots — 5, 10, 15 minutes ou une valeur libre — au-delà de laquelle ils quittent la liste et les band maps.",
|
||||
"Recherche d indicatif : une option fait utiliser à QRZ.com le surnom de l opérateur comme nom, avec repli sur le nom complet s il n y en a pas."
|
||||
"Recherche d indicatif : QRZ.com remplit désormais Nom avec le seul prénom, et au choix avec le surnom de l opérateur."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+15
-17
@@ -220,19 +220,6 @@ func composeQRZAddress(addr1, addr2, zip, country string) string {
|
||||
return strings.Join(parts, ", ")
|
||||
}
|
||||
|
||||
func joinName(first, last string) string {
|
||||
first = strings.TrimSpace(first)
|
||||
last = strings.TrimSpace(last)
|
||||
switch {
|
||||
case first != "" && last != "":
|
||||
return first + " " + last
|
||||
case first != "":
|
||||
return first
|
||||
default:
|
||||
return last
|
||||
}
|
||||
}
|
||||
|
||||
func firstNonEmpty(s ...string) string {
|
||||
for _, v := range s {
|
||||
v = strings.TrimSpace(v)
|
||||
@@ -245,14 +232,25 @@ func firstNonEmpty(s ...string) string {
|
||||
|
||||
// qrzName picks what goes in the log's Name field.
|
||||
//
|
||||
// The nickname is only taken when the operator asked for it AND QRZ has one —
|
||||
// a blank nickname must never blank the name, which is the whole reason this is
|
||||
// a fallback rather than a swap.
|
||||
// The FIRST name only. A log greets an operator, it does not address an
|
||||
// envelope: "Robert" is what goes out on the air, and "Robert Smith" filled the
|
||||
// field with something no one would ever send. The surname stays available in
|
||||
// the record; it simply is not the name of the contact.
|
||||
//
|
||||
// The nickname is taken ahead of it when the operator asked for that AND QRZ
|
||||
// has one — a blank nickname must never blank the name, which is the whole
|
||||
// reason this is a fallback rather than a swap.
|
||||
//
|
||||
// The surname is the last resort: a record with no first name at all is better
|
||||
// answered with a surname than with nothing.
|
||||
func qrzName(preferNickname bool, nickname, fname, name string) string {
|
||||
if preferNickname {
|
||||
if n := strings.TrimSpace(nickname); n != "" {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return joinName(fname, name)
|
||||
if f := strings.TrimSpace(fname); f != "" {
|
||||
return f
|
||||
}
|
||||
return strings.TrimSpace(name)
|
||||
}
|
||||
|
||||
@@ -2,30 +2,32 @@ package lookup
|
||||
|
||||
import "testing"
|
||||
|
||||
// The nickname is the name an operator goes BY on the air, and that is what
|
||||
// belongs in a log — "Bob", not "Robert J Smith". HamQTH's <nick> is already
|
||||
// used that way; this brings QRZ into line for operators who ask for it.
|
||||
// What goes in a log's Name field is the FIRST name. A log greets an operator;
|
||||
// it does not address an envelope. "Robert Smith" filled the field with
|
||||
// something no one would ever send on the air.
|
||||
//
|
||||
// The one thing it must never do is blank the name. A published nickname is
|
||||
// optional, so an empty one has to fall through to the registered name rather
|
||||
// than win by being "preferred".
|
||||
func TestQRZNamePrefersNicknameButFallsBack(t *testing.T) {
|
||||
// The nickname wins ahead of it when asked for — but a published nickname is
|
||||
// optional, so an empty one must fall through rather than blank the name. That
|
||||
// is the whole difference between a fallback and a swap.
|
||||
func TestQRZName(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
prefer bool
|
||||
nickname, fname, name string
|
||||
nickname, fname, last string
|
||||
want string
|
||||
}{
|
||||
{true, "Bob", "Robert", "Smith", "Bob"},
|
||||
{true, "", "Robert", "Smith", "Robert Smith"}, // no nickname published
|
||||
{true, " ", "Robert", "Smith", "Robert Smith"}, // blank is not a nickname
|
||||
{false, "Bob", "Robert", "Smith", "Robert Smith"}, // option off
|
||||
{true, "Bob", "", "", "Bob"},
|
||||
{false, "", "Robert", "", "Robert"},
|
||||
{true, "", "", "Smith", "Smith"},
|
||||
{"first name only, never the surname", false, "Bob", "Robert", "Smith", "Robert"},
|
||||
{"nickname when asked for", true, "Bob", "Robert", "Smith", "Bob"},
|
||||
{"no nickname published falls back to the FIRST name", true, "", "Robert", "Smith", "Robert"},
|
||||
{"a blank nickname is not a nickname", true, " ", "Robert", "Smith", "Robert"},
|
||||
{"option off ignores the nickname", false, "Bob", "Robert", "Smith", "Robert"},
|
||||
{"surname is the last resort, not the default", true, "", "", "Smith", "Smith"},
|
||||
{"nothing published at all", false, "", "", "", ""},
|
||||
{"nickname alone", true, "Bob", "", "", "Bob"},
|
||||
} {
|
||||
if got := qrzName(tc.prefer, tc.nickname, tc.fname, tc.name); got != tc.want {
|
||||
t.Errorf("qrzName(%v, %q, %q, %q) = %q, want %q",
|
||||
tc.prefer, tc.nickname, tc.fname, tc.name, got, tc.want)
|
||||
if got := qrzName(tc.prefer, tc.nickname, tc.fname, tc.last); got != tc.want {
|
||||
t.Errorf("%s: qrzName(%v, %q, %q, %q) = %q, want %q",
|
||||
tc.name, tc.prefer, tc.nickname, tc.fname, tc.last, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user