I'm testing Go's support for Unicode, by declaring a type
type Эксперимент struct {
Строка string
}
in package испытание
, and attempting to import into a unit test. However, when I try this, I get an error.
Trace:
$ go test
# github.com/mcandre/mcandre/go/испытание_test
./испытание_test.go:10: undefined: Эксперимент
FAIL github.com/mcandre/mcandre/go/испытание [build failed]
Source:
https://github.com/mcandre/mcandre/tree/master/go/испытание
Am I capitalizing my public members correctly? go doc
shows my struct being listed publicly:
$ go doc
package испытание // import "github.com/mcandre/mcandre/go/испытание"
Package испытание demonstrates Unicode capabilities in Go source code.
type Эксперимент struct { ... }
func Испытание() Эксперимент
Maybe the Go compiler has a problem with Cyrillic runes in tokens?
Quoting from the Spec: Exported Identifiers:
An identifier is exported if [...] the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and [...]
There is nothing wrong with Cyrillic runes (Go handles them well), all characters in the Unicode class "Lu" (Letter, uppercased) are accepted, but when you import a package, you have to use the package name to construct qualified identifiers to refer to exported identifiers from the package.
Change this line in your test:
wanted := Эксперимент{Строка: "Испытание!"}
To this:
wanted := испытание.Эксперимент{Строка: "Испытание!"}
Once you do this it'll pass. Running go test
:
PASS
ok github.com/mcandre/mcandre/go/испытание 0.001s
See this related question for more information: Getting a use of package without selector error
You need to use qualified identifier because you used a different package for your test file. You may choose to use the same package, in which case you must not import the package (it would be an import cycle which is not allowed), and in which case you don't need to use a qualified identifier, you may use all exported and unexported identifiers of the package.
This is how the test file would look like with the same package:
package испытание
import (
"testing"
)
func TestИспытаниеReturnsИспытание(t *testing.T) {
wanted := Эксперимент{Строка: "Испытание!"}
observed := Испытание()
if observed != wanted {
t.Errorf("испытание.Испытание(): Wanted %s, got %s
", wanted, observed)
}
}
Using the same package name is called white-box testing, using a different package name is called black-box testing. You can read more about it here: Where to put shared code for tests in a Go package?
With the import declarations, you can also change the name you want to use to refer to the imported package's identifiers; you can even use a .
(dot) in place of the name, in which case you can omit the name from the qualified identifiers. For details, see this: Import struct from another package and file golang