github.phpd.cn/thought-machine/please@v12.2.0+incompatible/tools/jarcat/zip/writer_test.go (about)

     1  package zip
     2  
     3  import (
     4  	"archive/zip"
     5  	"bytes"
     6  	"fmt"
     7  	"io"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  var expectedModTime = time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)
    17  
    18  func TestAddZipFile(t *testing.T) {
    19  	// Have to write an actual file for zip.OpenReader to use later.
    20  	f := NewFile("add_zip_file_test.zip", false)
    21  	err := f.AddZipFile("tools/jarcat/zip/test_data/test.zip")
    22  	require.NoError(t, err)
    23  	f.Close()
    24  	assertExpected(t, "add_zip_file_test.zip", 0)
    25  }
    26  
    27  // getZipContents is a helper which returns a map of filename -> contents
    28  func getZipContents(zipfilePath string) (map[string][]byte, error) {
    29  	reader, err := zip.OpenReader(zipfilePath)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	defer reader.Close()
    34  	res := make(map[string][]byte, len(reader.File))
    35  	for _, file := range reader.File {
    36  		if file.FileInfo().IsDir() {
    37  			continue
    38  		}
    39  		fReader, err := file.Open()
    40  		if err != nil {
    41  			return nil, err
    42  		}
    43  		defer fReader.Close()
    44  		contents := make([]byte, file.FileInfo().Size())
    45  		if _, err := io.ReadFull(fReader, contents); err != nil {
    46  			return nil, err
    47  		}
    48  		res[file.FileInfo().Name()] = contents
    49  	}
    50  	return res, nil
    51  }
    52  
    53  func TestAddZipFileConcatenatesSpecialFiles(t *testing.T) {
    54  	t.Run("Scala Akka reference.conf", func(t *testing.T) {
    55  		r := require.New(t)
    56  		f := NewFile("zip_files_with_reference_conf.zip", false)
    57  
    58  		err := f.AddZipFile("tools/jarcat/zip/test_data_3/z1.zip")
    59  		r.NoError(err)
    60  		err = f.AddZipFile("tools/jarcat/zip/test_data_3/z2.zip")
    61  		r.NoError(err)
    62  		f.Close()
    63  
    64  		actualContents, err := getZipContents("zip_files_with_reference_conf.zip")
    65  		r.NoError(err)
    66  		z1Contents, err := getZipContents("tools/jarcat/zip/test_data_3/z1.zip")
    67  		r.NoError(err)
    68  		z2Contents, err := getZipContents("tools/jarcat/zip/test_data_3/z2.zip")
    69  		r.NoError(err)
    70  		expectedRefConf := append(z1Contents["reference.conf"], z2Contents["reference.conf"]...)
    71  		r.EqualValues(actualContents["reference.conf"], expectedRefConf)
    72  		// OTOH, z2's file1 should just be ignored because it's not a special
    73  		// case and z1 already added it
    74  		expectedNormalFile := z1Contents["file1"]
    75  		r.EqualValues(actualContents["file1"], expectedNormalFile)
    76  	})
    77  }
    78  
    79  func TestAddFiles(t *testing.T) {
    80  	f := NewFile("add_files_test.zip", false)
    81  	f.Suffix = []string{"zip"}
    82  	err := f.AddFiles("tools/jarcat/zip/test_data")
    83  	require.NoError(t, err)
    84  	err = f.AddFiles("tools/jarcat/zip/test_data_2")
    85  	require.NoError(t, err)
    86  	f.Close()
    87  	assertExpected(t, "add_files_test.zip", 0)
    88  }
    89  
    90  func assertExpected(t *testing.T, filename string, alignment int) {
    91  	r, err := zip.OpenReader(filename)
    92  	require.NoError(t, err)
    93  	defer r.Close()
    94  	files := []struct{ Name, Prefix string }{
    95  		{"build_step.go", "// Implementation of Step interface."},
    96  		{"incrementality.go", "// Utilities to help with incremental builds."},
    97  	}
    98  	for i, f := range r.File {
    99  		assert.Equal(t, f.Name, files[i].Name)
   100  		assert.Equal(t, expectedModTime, f.ModTime())
   101  
   102  		fr, err := f.Open()
   103  		require.NoError(t, err)
   104  		var buf bytes.Buffer
   105  		_, err = io.Copy(&buf, fr)
   106  		require.NoError(t, err)
   107  		assert.True(t, strings.HasPrefix(buf.String(), files[i].Prefix))
   108  		fr.Close()
   109  
   110  		if alignment > 0 {
   111  			offset, err := f.DataOffset()
   112  			assert.NoError(t, err)
   113  			assert.True(t, int(offset)%alignment == 0)
   114  		}
   115  	}
   116  }
   117  
   118  func TestAlignment(t *testing.T) {
   119  	for _, align := range []int{2, 4, 8, 12, 32} {
   120  		t.Run(fmt.Sprintf("%dByte", align), func(t *testing.T) {
   121  			filename := fmt.Sprintf("test_alignment_%d.zip", align)
   122  			f := NewFile(filename, false)
   123  			f.Align = align
   124  			err := f.AddFiles("tools/jarcat/zip/test_data_2")
   125  			require.NoError(t, err)
   126  			f.Close()
   127  			assertExpected(t, filename, align)
   128  		})
   129  	}
   130  }
   131  
   132  func TestStoreSuffix(t *testing.T) {
   133  	// This is a sort of Android-esque example (storing PNGs at 4-byte alignment)
   134  	f := NewFile("test_store_suffix.zip", false)
   135  	f.Suffix = []string{"zip"}
   136  	f.StoreSuffix = []string{"png"}
   137  	f.Align = 4
   138  	f.IncludeOther = true
   139  	err := f.AddFiles("tools/jarcat/zip/test_data")
   140  	require.NoError(t, err)
   141  	err = f.AddFiles("tools/jarcat/zip/test_data_2")
   142  	require.NoError(t, err)
   143  	f.Close()
   144  
   145  	r, err := zip.OpenReader("test_store_suffix.zip")
   146  	require.NoError(t, err)
   147  	defer r.Close()
   148  	assert.Equal(t, 3, len(r.File))
   149  	png := r.File[0]
   150  	assert.Equal(t, "tools/jarcat/zip/test_data/kitten.png", png.Name)
   151  	assert.Equal(t, zip.Store, png.Method)
   152  }