github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/go/token/serialize_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 token
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/gob"
    10  	"fmt"
    11  	"testing"
    12  )
    13  
    14  // equal returns nil if p and q describe the same file set;
    15  // otherwise it returns an error describing the discrepancy.
    16  func equal(p, q *FileSet) error {
    17  	if p == q {
    18  		// avoid deadlock if p == q
    19  		return nil
    20  	}
    21  
    22  	// not strictly needed for the test
    23  	p.mutex.Lock()
    24  	q.mutex.Lock()
    25  	defer q.mutex.Unlock()
    26  	defer p.mutex.Unlock()
    27  
    28  	if p.base != q.base {
    29  		return fmt.Errorf("different bases: %d != %d", p.base, q.base)
    30  	}
    31  
    32  	if len(p.files) != len(q.files) {
    33  		return fmt.Errorf("different number of files: %d != %d", len(p.files), len(q.files))
    34  	}
    35  
    36  	for i, f := range p.files {
    37  		g := q.files[i]
    38  		if f.set != p {
    39  			return fmt.Errorf("wrong fileset for %q", f.name)
    40  		}
    41  		if g.set != q {
    42  			return fmt.Errorf("wrong fileset for %q", g.name)
    43  		}
    44  		if f.name != g.name {
    45  			return fmt.Errorf("different filenames: %q != %q", f.name, g.name)
    46  		}
    47  		if f.base != g.base {
    48  			return fmt.Errorf("different base for %q: %d != %d", f.name, f.base, g.base)
    49  		}
    50  		if f.size != g.size {
    51  			return fmt.Errorf("different size for %q: %d != %d", f.name, f.size, g.size)
    52  		}
    53  		for j, l := range f.lines {
    54  			m := g.lines[j]
    55  			if l != m {
    56  				return fmt.Errorf("different offsets for %q", f.name)
    57  			}
    58  		}
    59  		for j, l := range f.infos {
    60  			m := g.infos[j]
    61  			if l.Offset != m.Offset || l.Filename != m.Filename || l.Line != m.Line {
    62  				return fmt.Errorf("different infos for %q", f.name)
    63  			}
    64  		}
    65  	}
    66  
    67  	// we don't care about .last - it's just a cache
    68  	return nil
    69  }
    70  
    71  func checkSerialize(t *testing.T, p *FileSet) {
    72  	var buf bytes.Buffer
    73  	encode := func(x interface{}) error {
    74  		return gob.NewEncoder(&buf).Encode(x)
    75  	}
    76  	if err := p.Write(encode); err != nil {
    77  		t.Errorf("writing fileset failed: %s", err)
    78  		return
    79  	}
    80  	q := NewFileSet()
    81  	decode := func(x interface{}) error {
    82  		return gob.NewDecoder(&buf).Decode(x)
    83  	}
    84  	if err := q.Read(decode); err != nil {
    85  		t.Errorf("reading fileset failed: %s", err)
    86  		return
    87  	}
    88  	if err := equal(p, q); err != nil {
    89  		t.Errorf("filesets not identical: %s", err)
    90  	}
    91  }
    92  
    93  func TestSerialization(t *testing.T) {
    94  	p := NewFileSet()
    95  	checkSerialize(t, p)
    96  	// add some files
    97  	for i := 0; i < 10; i++ {
    98  		f := p.AddFile(fmt.Sprintf("file%d", i), p.Base()+i, i*100)
    99  		checkSerialize(t, p)
   100  		// add some lines and alternative file infos
   101  		line := 1000
   102  		for offs := 0; offs < f.Size(); offs += 40 + i {
   103  			f.AddLine(offs)
   104  			if offs%7 == 0 {
   105  				f.AddLineInfo(offs, fmt.Sprintf("file%d", offs), line)
   106  				line += 33
   107  			}
   108  		}
   109  		checkSerialize(t, p)
   110  	}
   111  }