dc4bc/qr/qr_test.go

129 lines
2.7 KiB
Go
Raw Normal View History

2020-09-01 08:06:37 -07:00
package qr
import (
"fmt"
2020-09-02 03:46:27 -07:00
encoder "github.com/skip2/go-qrcode"
"image"
2020-09-29 08:16:20 -07:00
"image/draw"
"image/gif"
2020-09-02 03:46:27 -07:00
"math/rand"
"os"
"reflect"
2020-09-01 08:06:37 -07:00
"testing"
)
2020-09-02 03:46:27 -07:00
type TestQrProcessor struct {
2020-09-29 08:16:20 -07:00
qr string
chunkSize int
2020-09-02 03:46:27 -07:00
}
func NewTestQRProcessor() *TestQrProcessor {
return &TestQrProcessor{}
}
func (p *TestQrProcessor) ReadQR() ([]byte, error) {
2020-09-29 08:16:20 -07:00
file, err := os.Open(p.qr)
2020-09-02 03:46:27 -07:00
if err != nil {
return nil, err
}
defer file.Close()
2020-09-29 08:16:20 -07:00
decodedGIF, err := gif.DecodeAll(file)
2020-09-02 03:46:27 -07:00
if err != nil {
return nil, err
}
2020-09-29 08:16:20 -07:00
chunks := make([]*chunk, 0)
decodedChunksCount := uint(0)
for _, frame := range decodedGIF.Image {
data, err := ReadDataFromQR(frame)
if err != nil {
continue
}
decodedChunk, err := decodeChunk(data)
if err != nil {
return nil, err
}
if cap(chunks) == 0 {
chunks = make([]*chunk, decodedChunk.Total)
}
if chunks[decodedChunk.Index] != nil {
continue
}
chunks[decodedChunk.Index] = decodedChunk
decodedChunksCount++
if decodedChunksCount == decodedChunk.Total {
break
}
2020-09-02 03:46:27 -07:00
}
2020-09-29 08:16:20 -07:00
data := make([]byte, 0)
for _, c := range chunks {
data = append(data, c.Data...)
}
if err = os.Remove(p.qr); err != nil {
2020-09-02 03:46:27 -07:00
return nil, err
}
return data, nil
}
func (p *TestQrProcessor) WriteQR(path string, data []byte) error {
2020-09-29 08:16:20 -07:00
chunks, err := DataToChunks(data, p.chunkSize)
2020-09-02 03:46:27 -07:00
if err != nil {
2020-09-29 08:16:20 -07:00
return fmt.Errorf("failed to divide data on chunks: %w", err)
2020-09-02 03:46:27 -07:00
}
2020-09-29 08:16:20 -07:00
outGif := &gif.GIF{}
for _, c := range chunks {
code, err := encoder.New(string(c), encoder.Medium)
if err != nil {
return fmt.Errorf("failed to create a QR code: %w", err)
}
frame := code.Image(512)
bounds := frame.Bounds()
palettedImage := image.NewPaletted(bounds, palette)
draw.Draw(palettedImage, palettedImage.Rect, frame, bounds.Min, draw.Src)
2020-09-02 03:46:27 -07:00
2020-09-29 08:16:20 -07:00
outGif.Image = append(outGif.Image, palettedImage)
outGif.Delay = append(outGif.Delay, 10)
}
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer f.Close()
if err := gif.EncodeAll(f, outGif); err != nil {
return fmt.Errorf("failed to encode qr gif: %w", err)
}
p.qr = path
2020-09-02 03:46:27 -07:00
return nil
}
func genBytes(n int) []byte {
data := make([]byte, n)
if _, err := rand.Read(data); err != nil {
return nil
}
return data
}
func TestReadDataFromQRChunks(t *testing.T) {
N := 5000
data := genBytes(N)
p := NewTestQRProcessor()
2020-09-29 08:16:20 -07:00
p.chunkSize = 128
2020-09-02 03:46:27 -07:00
2020-09-29 08:16:20 -07:00
if err := p.WriteQR("/tmp/test_gif.gif", data); err != nil {
t.Fatalf(err.Error())
2020-09-01 08:06:37 -07:00
}
2020-09-29 08:16:20 -07:00
recoveredDataFromQRChunks, err := p.ReadQR()
2020-09-01 08:06:37 -07:00
if err != nil {
2020-09-02 03:46:27 -07:00
t.Fatalf(err.Error())
}
if !reflect.DeepEqual(data, recoveredDataFromQRChunks) {
t.Fatal("recovered data from chunks and initial data are not equal!")
2020-09-01 08:06:37 -07:00
}
}