github.com/aloncn/graphics-go@v0.0.1/src/compress/lzw/writer_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lzw
     6  
     7  import (
     8  	"internal/testenv"
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  	"runtime"
    13  	"testing"
    14  )
    15  
    16  var filenames = []string{
    17  	"../testdata/gettysburg.txt",
    18  	"../testdata/e.txt",
    19  	"../testdata/pi.txt",
    20  }
    21  
    22  // testFile tests that compressing and then decompressing the given file with
    23  // the given options yields equivalent bytes to the original file.
    24  func testFile(t *testing.T, fn string, order Order, litWidth int) {
    25  	// Read the file, as golden output.
    26  	golden, err := os.Open(fn)
    27  	if err != nil {
    28  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
    29  		return
    30  	}
    31  	defer golden.Close()
    32  
    33  	// Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
    34  	raw, err := os.Open(fn)
    35  	if err != nil {
    36  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
    37  		return
    38  	}
    39  
    40  	piper, pipew := io.Pipe()
    41  	defer piper.Close()
    42  	go func() {
    43  		defer raw.Close()
    44  		defer pipew.Close()
    45  		lzww := NewWriter(pipew, order, litWidth)
    46  		defer lzww.Close()
    47  		var b [4096]byte
    48  		for {
    49  			n, err0 := raw.Read(b[:])
    50  			if err0 != nil && err0 != io.EOF {
    51  				t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
    52  				return
    53  			}
    54  			_, err1 := lzww.Write(b[:n])
    55  			if err1 != nil {
    56  				t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
    57  				return
    58  			}
    59  			if err0 == io.EOF {
    60  				break
    61  			}
    62  		}
    63  	}()
    64  	lzwr := NewReader(piper, order, litWidth)
    65  	defer lzwr.Close()
    66  
    67  	// Compare the two.
    68  	b0, err0 := ioutil.ReadAll(golden)
    69  	b1, err1 := ioutil.ReadAll(lzwr)
    70  	if err0 != nil {
    71  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
    72  		return
    73  	}
    74  	if err1 != nil {
    75  		t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
    76  		return
    77  	}
    78  	if len(b1) != len(b0) {
    79  		t.Errorf("%s (order=%d litWidth=%d): length mismatch %d != %d", fn, order, litWidth, len(b1), len(b0))
    80  		return
    81  	}
    82  	for i := 0; i < len(b0); i++ {
    83  		if b1[i] != b0[i] {
    84  			t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x != 0x%02x\n", fn, order, litWidth, i, b1[i], b0[i])
    85  			return
    86  		}
    87  	}
    88  }
    89  
    90  func TestWriter(t *testing.T) {
    91  	for _, filename := range filenames {
    92  		for _, order := range [...]Order{LSB, MSB} {
    93  			// The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits.
    94  			for litWidth := 6; litWidth <= 8; litWidth++ {
    95  				if filename == "../testdata/gettysburg.txt" && litWidth == 6 {
    96  					continue
    97  				}
    98  				testFile(t, filename, order, litWidth)
    99  			}
   100  		}
   101  		if testing.Short() && testenv.Builder() == "" {
   102  			break
   103  		}
   104  	}
   105  }
   106  
   107  func TestWriterReturnValues(t *testing.T) {
   108  	w := NewWriter(ioutil.Discard, LSB, 8)
   109  	n, err := w.Write([]byte("asdf"))
   110  	if n != 4 || err != nil {
   111  		t.Errorf("got %d, %v, want 4, nil", n, err)
   112  	}
   113  }
   114  
   115  func TestSmallLitWidth(t *testing.T) {
   116  	w := NewWriter(ioutil.Discard, LSB, 2)
   117  	if _, err := w.Write([]byte{0x03}); err != nil {
   118  		t.Fatalf("write a byte < 1<<2: %v", err)
   119  	}
   120  	if _, err := w.Write([]byte{0x04}); err == nil {
   121  		t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
   122  	}
   123  }
   124  
   125  func benchmarkEncoder(b *testing.B, n int) {
   126  	b.StopTimer()
   127  	b.SetBytes(int64(n))
   128  	buf0, err := ioutil.ReadFile("../testdata/e.txt")
   129  	if err != nil {
   130  		b.Fatal(err)
   131  	}
   132  	if len(buf0) == 0 {
   133  		b.Fatalf("test file has no data")
   134  	}
   135  	buf1 := make([]byte, n)
   136  	for i := 0; i < n; i += len(buf0) {
   137  		if len(buf0) > n-i {
   138  			buf0 = buf0[:n-i]
   139  		}
   140  		copy(buf1[i:], buf0)
   141  	}
   142  	buf0 = nil
   143  	runtime.GC()
   144  	b.StartTimer()
   145  	for i := 0; i < b.N; i++ {
   146  		w := NewWriter(ioutil.Discard, LSB, 8)
   147  		w.Write(buf1)
   148  		w.Close()
   149  	}
   150  }
   151  
   152  func BenchmarkEncoder1e4(b *testing.B) {
   153  	benchmarkEncoder(b, 1e4)
   154  }
   155  
   156  func BenchmarkEncoder1e5(b *testing.B) {
   157  	benchmarkEncoder(b, 1e5)
   158  }
   159  
   160  func BenchmarkEncoder1e6(b *testing.B) {
   161  	benchmarkEncoder(b, 1e6)
   162  }