golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.98k stars 17.67k forks source link

x/text/message/catalog: unclear how to implement Dictionary #59330

Open mrwonko opened 1 year ago

mrwonko commented 1 year ago

The documentation for catalog.Dictionary says

returns a message compiled with catmsg.Compile

But catmsg is an internal package that I can't use.

According to https://medium.com/@oborin/localization-in-go-with-enclosing-packages-6fe2efb85a15, I should prefix my message with "\x02", but there's no explanation why that is. As far as I can tell that corresponds to handler catmsg.msgRaw, and seems to work, but since it is undocumented I'm afraid that could stop working any day.

Let me take a step back and explain why I'm interested in this. My actual goal is to write unit tests for translated text that are independent of the actual translations, so they do not break if translations change. My understanding is that I can't mock message.Printer using an interface, as gotext relies on the exact type to extract the translation keys from the source code, so I have decided to instead use a custom Catalog that returns keys unchanged.

This appears to work, but I'd like a guarantee that it will continue to do so.

package main

import (
    "golang.org/x/text/language"
    "golang.org/x/text/message"
    "golang.org/x/text/message/catalog"
)

type debugDictionary struct{}

var _ catalog.Dictionary = debugDictionary{}

func (debugDictionary) Lookup(key string) (data string, ok bool) {
    // this magic \x02 makes me uneasy
    return fmt.Sprintf("\x02<%s>", key), true
}

func ExampleLocalization() {
    cat, err := catalog.NewFromMap(map[string]catalog.Dictionary{
        "en": debugDictionary{},
    })
    if err != nil {
        panic(err)
    }
    p := message.NewPrinter(language.English, message.Catalog(cat))
    p.Printf("foo")
    fmt.Println()
    p.Printf("unknownUser %s", "test")
    // Output:
    // <foo>
    // <unknownUser test>
}
mknyszek commented 1 year ago

CC @mpvl via https://dev.golang.org/owners