...
Run Format

Source file src/compress/lzw/writer_test.go

Documentation: compress/lzw

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

View as plain text