Skip to content

Commit

Permalink
test: dictzip test
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Lewis <ianmlewis@gmail.com>
  • Loading branch information
ianlewis committed Nov 4, 2024
1 parent 8fb3bc1 commit b2234fb
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 45 deletions.
10 changes: 7 additions & 3 deletions dict/dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ type ReaderAtCloser interface {

// Options are options for the dict data.
type Options struct {
// SameTypeSequence is an option that indicates that each word in the .dict
// file will have the same sequence of data types. This is equivalent to
// the sametypesequence option from the .ifo file..
//
// See: https://github.com/huzheng001/stardict-3/blob/master/dict/doc/StarDictFileFormat
SameTypeSequence []DataType
}

Expand Down Expand Up @@ -227,9 +232,8 @@ func NewFromIfoPath(ifoPath string, options *Options) (*Dict, error) {
f: f,
}

dictExt := filepath.Ext(f.Name())
//nolint:gocritic // strings.EqualFold should not be used here.
if strings.ToLower(dictExt) == ".dz" {
dictExt := strings.ToLower(filepath.Ext(f.Name()))
if dictExt == ".dz" {
r.dz, err = dictzip.NewReader(f)
if err != nil {
return nil, fmt.Errorf("opening dictzip: %w", err)
Expand Down
96 changes: 60 additions & 36 deletions dict/dict_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package dict_test
import (
"io"
"os"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -216,7 +215,7 @@ func TestDict_Word(t *testing.T) {
}
defer os.Remove(f.Name())

_, err = f.Write(testutil.MakeDict(test.dict, test.sametypesequence))
_, err = f.Write(testutil.MakeDict(t, test.dict, test.sametypesequence))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -250,16 +249,17 @@ func TestDict_NewFromIfoPath(t *testing.T) {
t.Parallel()

tests := []struct {
name string
extension string
dict []*dict.Word
index *idx.Word
expected *dict.Word
sametypesequence []dict.DataType
name string
options *testutil.MakeDictOptions
dict []*dict.Word
index *idx.Word
expected *dict.Word
}{
{
name: "utf",
extension: ".dict",
name: "utf",
options: &testutil.MakeDictOptions{
Ext: ".dict",
},
dict: []*dict.Word{
{
Data: []*dict.Data{
Expand All @@ -285,10 +285,12 @@ func TestDict_NewFromIfoPath(t *testing.T) {
},
},
{
name: "utf sametype",
extension: ".DICT",
sametypesequence: []dict.DataType{
dict.UTFTextType,
name: "utf sametype",
options: &testutil.MakeDictOptions{
Ext: ".DICT",
SameTypeSequence: []dict.DataType{
dict.UTFTextType,
},
},
dict: []*dict.Word{
{
Expand All @@ -315,8 +317,10 @@ func TestDict_NewFromIfoPath(t *testing.T) {
},
},
{
name: "file type",
extension: ".dict",
name: "file type",
options: &testutil.MakeDictOptions{
Ext: ".dict",
},
dict: []*dict.Word{
{
Data: []*dict.Data{
Expand All @@ -342,10 +346,12 @@ func TestDict_NewFromIfoPath(t *testing.T) {
},
},
{
name: "file sametype",
extension: ".dict",
sametypesequence: []dict.DataType{
dict.WavType,
name: "file sametype",
options: &testutil.MakeDictOptions{
Ext: ".dict",
SameTypeSequence: []dict.DataType{
dict.WavType,
},
},
dict: []*dict.Word{
{
Expand All @@ -371,30 +377,48 @@ func TestDict_NewFromIfoPath(t *testing.T) {
},
},
},
{
name: "dictzip",
options: &testutil.MakeDictOptions{
Ext: ".dict.dz",
DictZip: true,
},
dict: []*dict.Word{
{
Data: []*dict.Data{
{
Type: dict.UTFTextType,
Data: []byte("hoge"),
},
},
},
},
index: &idx.Word{
Word: "hoge",
Offset: uint64(0),
Size: uint32(6),
},
expected: &dict.Word{
Data: []*dict.Data{
{
Type: dict.UTFTextType,
Data: []byte("hoge"),
},
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()

f, err := os.CreateTemp("", "stardict.*"+test.extension)
if err != nil {
t.Fatal(err)
}
defer os.Remove(f.Name())
path := testutil.MakeTempDict(t, test.dict, test.options)
defer os.Remove(path)
ifoPath := strings.TrimSuffix(path, test.options.Ext) + ".ifo"

_, err = f.Write(testutil.MakeDict(test.dict, test.sametypesequence))
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}

ifoPath := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name())) + ".ifo"
d, err := dict.NewFromIfoPath(ifoPath, &dict.Options{
SameTypeSequence: test.sametypesequence,
SameTypeSequence: test.options.SameTypeSequence,
})
if err != nil {
t.Fatal(err)
Expand Down
57 changes: 54 additions & 3 deletions internal/testutil/dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,66 @@
package testutil

import (
"bytes"
"encoding/binary"
"fmt"
"math"
"os"
"testing"

"github.com/pebbe/dictzip"

"github.com/ianlewis/go-stardict/dict"
)

type MakeDictOptions struct {
// Ext is the .dict file's extension (e.g. .dict).
Ext string

// DictZip indicates that the dict file should be compressed with DictZip.
DictZip bool

// SameTypeSequence is the sametypesequence option.
SameTypeSequence []dict.DataType
}

// MakeTempDict creates a temporary .dict file and returns the path to the file.
func MakeTempDict(t *testing.T, words []*dict.Word, opts *MakeDictOptions) string {
t.Helper()

f, err := os.CreateTemp("", "stardict.*"+opts.Ext)
if err != nil {
t.Fatal(err)
}

d := MakeDict(t, words, opts.SameTypeSequence)

if opts.DictZip {
// Just get the file name.
path := f.Name()
f.Close()

fmt.Println(path)
err := dictzip.Write(bytes.NewReader(d), path, 9)

Check failure on line 58 in internal/testutil/dict.go

View workflow job for this annotation

GitHub Actions / golangci-lint

shadow: declaration of "err" shadows declaration at line 45 (govet)
if err != nil {
t.Fatal(err)
}

return path
} else {

Check warning on line 64 in internal/testutil/dict.go

View workflow job for this annotation

GitHub Actions / golangci-lint

indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (revive)
defer f.Close()

_, err = f.Write(d)
if err != nil {
t.Fatal(err)
}

return f.Name()
}
}

// MakeDict creates a test .dict file.
func MakeDict(words []*dict.Word, sametypesequence []dict.DataType) []byte {
func MakeDict(t *testing.T, words []*dict.Word, sametypesequence []dict.DataType) []byte {

Check failure on line 77 in internal/testutil/dict.go

View workflow job for this annotation

GitHub Actions / golangci-lint

test helper function should start from t.Helper() (thelper)
b := []byte{}
for _, w := range words {
for i, d := range w.Data {
Expand All @@ -38,7 +89,7 @@ func MakeDict(words []*dict.Word, sametypesequence []dict.DataType) []byte {
sizeBytes := make([]byte, 4)
dataLen := len(d.Data)
if dataLen > math.MaxUint32 {
panic(fmt.Sprintf("word data too long: %d", dataLen))
t.Fatalf("word data too long: %d", dataLen)
}
binary.BigEndian.PutUint32(sizeBytes, uint32(dataLen))
b = append(b, sizeBytes...)
Expand All @@ -57,7 +108,7 @@ func MakeDict(words []*dict.Word, sametypesequence []dict.DataType) []byte {
sizeBytes := make([]byte, 4)
dataLen := len(d.Data)
if dataLen > math.MaxUint32 {
panic(fmt.Sprintf("word data too long: %d", dataLen))
t.Fatalf("word data too long: %d", dataLen)
}
binary.BigEndian.PutUint32(sizeBytes, uint32(dataLen))
b = append(b, sizeBytes...)
Expand Down
8 changes: 5 additions & 3 deletions stardict_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ type testDict struct {
}

// writeDict writes out a test dictionary set of files.
func writeDict(d testDict) string {
func writeDict(t *testing.T, d testDict) string {
t.Helper()

path, err := os.MkdirTemp("", "stardict")
if err != nil {
panic(err)
Expand All @@ -43,7 +45,7 @@ func writeDict(d testDict) string {
if err := os.WriteFile(filepath.Join(path, "dictionary.idx"), testutil.MakeIndex(d.idx, 32), 0o600); err != nil {
panic(err)
}
if err := os.WriteFile(filepath.Join(path, "dictionary.dict"), testutil.MakeDict(d.dict, nil), 0o600); err != nil {
if err := os.WriteFile(filepath.Join(path, "dictionary.dict"), testutil.MakeDict(t, d.dict, nil), 0o600); err != nil {
panic(err)
}

Expand Down Expand Up @@ -94,7 +96,7 @@ idxfilesize=6`,
t.Parallel()

for _, td := range test.dicts {
path := writeDict(td)
path := writeDict(t, td)
defer os.RemoveAll(path)

s, err := Open(filepath.Join(path, "dictionary.ifo"))
Expand Down

0 comments on commit b2234fb

Please # to comment.