...
Run Format

Source file src/compress/lzw/writer_test.go

Documentation: compress/lzw

  // Copyright 2011 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package lzw
  
  import (
  	"fmt"
  	"internal/testenv"
  	"io"
  	"io/ioutil"
  	"math"
  	"os"
  	"runtime"
  	"testing"
  )
  
  var filenames = []string{
  	"../testdata/gettysburg.txt",
  	"../testdata/e.txt",
  	"../testdata/pi.txt",
  }
  
  // testFile tests that compressing and then decompressing the given file with
  // the given options yields equivalent bytes to the original file.
  func testFile(t *testing.T, fn string, order Order, litWidth int) {
  	// Read the file, as golden output.
  	golden, err := os.Open(fn)
  	if err != nil {
  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
  		return
  	}
  	defer golden.Close()
  
  	// Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
  	raw, err := os.Open(fn)
  	if err != nil {
  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
  		return
  	}
  
  	piper, pipew := io.Pipe()
  	defer piper.Close()
  	go func() {
  		defer raw.Close()
  		defer pipew.Close()
  		lzww := NewWriter(pipew, order, litWidth)
  		defer lzww.Close()
  		var b [4096]byte
  		for {
  			n, err0 := raw.Read(b[:])
  			if err0 != nil && err0 != io.EOF {
  				t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
  				return
  			}
  			_, err1 := lzww.Write(b[:n])
  			if err1 != nil {
  				t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
  				return
  			}
  			if err0 == io.EOF {
  				break
  			}
  		}
  	}()
  	lzwr := NewReader(piper, order, litWidth)
  	defer lzwr.Close()
  
  	// Compare the two.
  	b0, err0 := ioutil.ReadAll(golden)
  	b1, err1 := ioutil.ReadAll(lzwr)
  	if err0 != nil {
  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
  		return
  	}
  	if err1 != nil {
  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
  		return
  	}
  	if len(b1) != len(b0) {
  		t.Errorf("%s (order=%d litWidth=%d): length mismatch %d != %d", fn, order, litWidth, len(b1), len(b0))
  		return
  	}
  	for i := 0; i < len(b0); i++ {
  		if b1[i] != b0[i] {
  			t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x != 0x%02x\n", fn, order, litWidth, i, b1[i], b0[i])
  			return
  		}
  	}
  }
  
  func TestWriter(t *testing.T) {
  	for _, filename := range filenames {
  		for _, order := range [...]Order{LSB, MSB} {
  			// The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits.
  			for litWidth := 6; litWidth <= 8; litWidth++ {
  				if filename == "../testdata/gettysburg.txt" && litWidth == 6 {
  					continue
  				}
  				testFile(t, filename, order, litWidth)
  			}
  		}
  		if testing.Short() && testenv.Builder() == "" {
  			break
  		}
  	}
  }
  
  func TestWriterReturnValues(t *testing.T) {
  	w := NewWriter(ioutil.Discard, LSB, 8)
  	n, err := w.Write([]byte("asdf"))
  	if n != 4 || err != nil {
  		t.Errorf("got %d, %v, want 4, nil", n, err)
  	}
  }
  
  func TestSmallLitWidth(t *testing.T) {
  	w := NewWriter(ioutil.Discard, LSB, 2)
  	if _, err := w.Write([]byte{0x03}); err != nil {
  		t.Fatalf("write a byte < 1<<2: %v", err)
  	}
  	if _, err := w.Write([]byte{0x04}); err == nil {
  		t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
  	}
  }
  
  func BenchmarkEncoder(b *testing.B) {
  	buf, err := ioutil.ReadFile("../testdata/e.txt")
  	if err != nil {
  		b.Fatal(err)
  	}
  	if len(buf) == 0 {
  		b.Fatalf("test file has no data")
  	}
  
  	for e := 4; e <= 6; e++ {
  		n := int(math.Pow10(e))
  		buf0 := buf
  		buf1 := make([]byte, n)
  		for i := 0; i < n; i += len(buf0) {
  			if len(buf0) > n-i {
  				buf0 = buf0[:n-i]
  			}
  			copy(buf1[i:], buf0)
  		}
  		buf0 = nil
  		runtime.GC()
  		b.Run(fmt.Sprint("1e", e), func(b *testing.B) {
  			b.SetBytes(int64(n))
  			for i := 0; i < b.N; i++ {
  				w := NewWriter(ioutil.Discard, LSB, 8)
  				w.Write(buf1)
  				w.Close()
  			}
  		})
  	}
  }
  

View as plain text