...

Source file src/github.com/rogpeppe/go-internal/txtar/archive_test.go

Documentation: github.com/rogpeppe/go-internal/txtar

     1  // Copyright 2018 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 txtar
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"reflect"
    13  	"testing"
    14  )
    15  
    16  var tests = []struct {
    17  	name   string
    18  	text   string
    19  	parsed *Archive
    20  }{
    21  	// General test
    22  	{
    23  		name: "basic",
    24  		text: `comment1
    25  comment2
    26  -- file1 --
    27  File 1 text.
    28  -- foo ---
    29  More file 1 text.
    30  -- file 2 --
    31  File 2 text.
    32  -- empty --
    33  -- noNL --
    34  hello world`,
    35  		parsed: &Archive{
    36  			Comment: []byte("comment1\ncomment2\n"),
    37  			Files: []File{
    38  				{"file1", []byte("File 1 text.\n-- foo ---\nMore file 1 text.\n")},
    39  				{"file 2", []byte("File 2 text.\n")},
    40  				{"empty", []byte{}},
    41  				{"noNL", []byte("hello world\n")},
    42  			},
    43  		},
    44  	},
    45  	// Test CRLF input
    46  	{
    47  		name: "basicCRLF",
    48  		text: "blah\r\n-- hello --\r\nhello\r\n",
    49  		parsed: &Archive{
    50  			Comment: []byte("blah\r\n"),
    51  			Files: []File{
    52  				{"hello", []byte("hello\r\n")},
    53  			},
    54  		},
    55  	},
    56  }
    57  
    58  func Test(t *testing.T) {
    59  	for _, tt := range tests {
    60  		t.Run(tt.name, func(t *testing.T) {
    61  			a := Parse([]byte(tt.text))
    62  			if !reflect.DeepEqual(a, tt.parsed) {
    63  				t.Fatalf("Parse: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed))
    64  			}
    65  			text := Format(a)
    66  			a = Parse(text)
    67  			if !reflect.DeepEqual(a, tt.parsed) {
    68  				t.Fatalf("Parse after Format: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed))
    69  			}
    70  		})
    71  	}
    72  }
    73  
    74  func shortArchive(a *Archive) string {
    75  	var buf bytes.Buffer
    76  	fmt.Fprintf(&buf, "comment: %q\n", a.Comment)
    77  	for _, f := range a.Files {
    78  		fmt.Fprintf(&buf, "file %q: %q\n", f.Name, f.Data)
    79  	}
    80  	return buf.String()
    81  }
    82  
    83  func TestWrite(t *testing.T) {
    84  	td, err := ioutil.TempDir("", "")
    85  	if err != nil {
    86  		t.Fatalf("failed to create temp dir: %v", err)
    87  	}
    88  	defer os.RemoveAll(td)
    89  
    90  	good := &Archive{Files: []File{File{Name: "good.txt"}}}
    91  	if err := Write(good, td); err != nil {
    92  		t.Fatalf("expected no error; got %v", err)
    93  	}
    94  
    95  	badRel := &Archive{Files: []File{File{Name: "../bad.txt"}}}
    96  	want := `"../bad.txt": outside parent directory`
    97  	if err := Write(badRel, td); err == nil || err.Error() != want {
    98  		t.Fatalf("expected %v; got %v", want, err)
    99  	}
   100  
   101  	badAbs := &Archive{Files: []File{File{Name: "/bad.txt"}}}
   102  	want = `"/bad.txt": outside parent directory`
   103  	if err := Write(badAbs, td); err == nil || err.Error() != want {
   104  		t.Fatalf("expected %v; got %v", want, err)
   105  	}
   106  }
   107  
   108  var unquoteErrorTests = []struct {
   109  	testName    string
   110  	data        string
   111  	expectError string
   112  }{{
   113  	testName:    "no final newline",
   114  	data:        ">hello",
   115  	expectError: `data does not appear to be quoted`,
   116  }, {
   117  	testName:    "no initial >",
   118  	data:        "hello\n",
   119  	expectError: `data does not appear to be quoted`,
   120  }}
   121  
   122  func TestUnquote(t *testing.T) {
   123  	for _, test := range unquoteErrorTests {
   124  		t.Run(test.testName, func(t *testing.T) {
   125  			_, err := Unquote([]byte(test.data))
   126  			if err == nil {
   127  				t.Fatalf("unexpected success")
   128  			}
   129  			if err.Error() != test.expectError {
   130  				t.Fatalf("unexpected error; got %q want %q", err, test.expectError)
   131  			}
   132  		})
   133  	}
   134  }
   135  
   136  var quoteTests = []struct {
   137  	testName    string
   138  	data        string
   139  	expect      string
   140  	expectError string
   141  }{{
   142  	testName: "empty",
   143  	data:     "",
   144  	expect:   "",
   145  }, {
   146  	testName: "one line",
   147  	data:     "foo\n",
   148  	expect:   ">foo\n",
   149  }, {
   150  	testName: "several lines",
   151  	data:     "foo\nbar\n-- baz --\n",
   152  	expect:   ">foo\n>bar\n>-- baz --\n",
   153  }, {
   154  	testName:    "bad data",
   155  	data:        "foo\xff\n",
   156  	expectError: `data contains non-UTF-8 characters`,
   157  }, {
   158  	testName:    "no final newline",
   159  	data:        "foo",
   160  	expectError: `data has no final newline`,
   161  }}
   162  
   163  func TestQuote(t *testing.T) {
   164  	for _, test := range quoteTests {
   165  		t.Run(test.testName, func(t *testing.T) {
   166  			got, err := Quote([]byte(test.data))
   167  			if test.expectError != "" {
   168  				if err == nil {
   169  					t.Fatalf("unexpected success")
   170  				}
   171  				if err.Error() != test.expectError {
   172  					t.Fatalf("unexpected error; got %q want %q", err, test.expectError)
   173  				}
   174  				return
   175  			}
   176  			if err != nil {
   177  				t.Fatalf("quote error: %v", err)
   178  			}
   179  			if string(got) != test.expect {
   180  				t.Fatalf("unexpected result; got %q want %q", got, test.expect)
   181  			}
   182  			orig, err := Unquote(got)
   183  			if err != nil {
   184  				t.Fatal(err)
   185  			}
   186  			if string(orig) != test.data {
   187  				t.Fatalf("round trip failed; got %q want %q", orig, test.data)
   188  			}
   189  		})
   190  	}
   191  }
   192  

View as plain text