...

Source file src/golang.org/x/text/internal/gen/bitfield/bitfield_test.go

Documentation: golang.org/x/text/internal/gen/bitfield

     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 bitfield
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"os"
    11  	"testing"
    12  )
    13  
    14  type myUint8 uint8
    15  
    16  type test1 struct { // 28 bits
    17  	foo  uint16 `bitfield:",fob"`
    18  	Bar  int8   `bitfield:"5,baz"`
    19  	Foo  uint64
    20  	bar  myUint8 `bitfield:"3"`
    21  	Bool bool    `bitfield:""`
    22  	Baz  int8    `bitfield:"3"`
    23  }
    24  
    25  type test2 struct {
    26  	larger1 uint16 `bitfield:"32"`
    27  	larger2 uint16 `bitfield:"32"`
    28  }
    29  
    30  type tooManyBits struct {
    31  	u1 uint16 `bitfield:"12"`
    32  	u2 uint16 `bitfield:"12"`
    33  	u3 uint16 `bitfield:"12"`
    34  	u4 uint16 `bitfield:"12"`
    35  	u5 uint16 `bitfield:"12"`
    36  	u6 uint16 `bitfield:"12"`
    37  }
    38  
    39  type just64 struct {
    40  	foo uint64 `bitfield:""`
    41  }
    42  
    43  type toUint8 struct {
    44  	foo bool `bitfield:""`
    45  }
    46  
    47  type toUint16 struct {
    48  	foo int `bitfield:"9"`
    49  }
    50  
    51  type faultySize struct {
    52  	foo uint64 `bitfield:"a"`
    53  }
    54  
    55  type faultyType struct {
    56  	foo *int `bitfield:"5"`
    57  }
    58  
    59  var (
    60  	maxed = test1{
    61  		foo:  0xffff,
    62  		Bar:  0x1f,
    63  		Foo:  0xffff,
    64  		bar:  0x7,
    65  		Bool: true,
    66  		Baz:  0x7,
    67  	}
    68  	alternate1 = test1{
    69  		foo: 0xffff,
    70  		bar: 0x7,
    71  		Baz: 0x7,
    72  	}
    73  	alternate2 = test1{
    74  		Bar:  0x1f,
    75  		Bool: true,
    76  	}
    77  	overflow = test1{
    78  		Bar: 0x3f,
    79  	}
    80  	negative = test1{
    81  		Bar: -1,
    82  	}
    83  )
    84  
    85  func TestPack(t *testing.T) {
    86  	testCases := []struct {
    87  		desc  string
    88  		x     interface{}
    89  		nBits uint
    90  		out   uint64
    91  		ok    bool
    92  	}{
    93  		{"maxed out fields", maxed, 0, 0xfffffff0, true},
    94  		{"maxed using less bits", maxed, 28, 0x0fffffff, true},
    95  
    96  		{"alternate1", alternate1, 0, 0xffff0770, true},
    97  		{"alternate2", alternate2, 0, 0x0000f880, true},
    98  
    99  		{"just64", &just64{0x0f0f0f0f}, 00, 0xf0f0f0f, true},
   100  		{"just64", &just64{0x0f0f0f0f}, 64, 0xf0f0f0f, true},
   101  		{"just64", &just64{0xffffFFFF}, 64, 0xffffffff, true},
   102  		{"to uint8", &toUint8{true}, 0, 0x80, true},
   103  		{"to uint16", &toUint16{1}, 0, 0x0080, true},
   104  		// errors
   105  		{"overflow", overflow, 0, 0, false},
   106  		{"too many bits", &tooManyBits{}, 0, 0, false},
   107  		{"fault size", &faultySize{}, 0, 0, false},
   108  		{"fault type", &faultyType{}, 0, 0, false},
   109  		{"negative", negative, 0, 0, false},
   110  		{"not enough bits", maxed, 27, 0, false},
   111  	}
   112  	for _, tc := range testCases {
   113  		t.Run(fmt.Sprintf("%T/%s", tc.x, tc.desc), func(t *testing.T) {
   114  			v, err := Pack(tc.x, &Config{NumBits: tc.nBits})
   115  			if ok := err == nil; v != tc.out || ok != tc.ok {
   116  				t.Errorf("got %#x, %v; want %#x, %v (%v)", v, ok, tc.out, tc.ok, err)
   117  			}
   118  		})
   119  	}
   120  }
   121  
   122  func TestRoundtrip(t *testing.T) {
   123  	testCases := []struct {
   124  		x test1
   125  	}{
   126  		{maxed},
   127  		{alternate1},
   128  		{alternate2},
   129  	}
   130  	for _, tc := range testCases {
   131  		t.Run("", func(t *testing.T) {
   132  			v, err := Pack(tc.x, nil)
   133  			if err != nil {
   134  				t.Fatal(err)
   135  			}
   136  			want := tc.x
   137  			want.Foo = 0 // not stored
   138  			x := myInt(v)
   139  			got := test1{
   140  				foo:  x.fob(),
   141  				Bar:  x.baz(),
   142  				bar:  x.bar(),
   143  				Bool: x.Bool(),
   144  				Baz:  x.Baz(),
   145  			}
   146  			if got != want {
   147  				t.Errorf("\ngot  %#v\nwant %#v (%#x)", got, want, v)
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func TestGen(t *testing.T) {
   154  	testCases := []struct {
   155  		desc   string
   156  		x      interface{}
   157  		config *Config
   158  		ok     bool
   159  		out    string
   160  	}{{
   161  		desc: "test1",
   162  		x:    &test1{},
   163  		ok:   true,
   164  		out:  test1Gen,
   165  	}, {
   166  		desc:   "test1 with options",
   167  		x:      &test1{},
   168  		config: &Config{Package: "bitfield", TypeName: "myInt"},
   169  		ok:     true,
   170  		out:    mustRead("gen1_test.go"),
   171  	}, {
   172  		desc:   "test1 with alternative bits",
   173  		x:      &test1{},
   174  		config: &Config{NumBits: 28, Package: "bitfield", TypeName: "myInt2"},
   175  		ok:     true,
   176  		out:    mustRead("gen2_test.go"),
   177  	}, {
   178  		desc:   "failure",
   179  		x:      &test1{},
   180  		config: &Config{NumBits: 27}, // Too few bits.
   181  		ok:     false,
   182  		out:    "",
   183  	}}
   184  
   185  	for _, tc := range testCases {
   186  		t.Run(tc.desc, func(t *testing.T) {
   187  			w := &bytes.Buffer{}
   188  			err := Gen(w, tc.x, tc.config)
   189  			if ok := err == nil; ok != tc.ok {
   190  				t.Fatalf("got %v; want %v (%v)", ok, tc.ok, err)
   191  			}
   192  			got := w.String()
   193  			if got != tc.out {
   194  				t.Errorf("got:\n%s\nwant:\n%s", got, tc.out)
   195  			}
   196  		})
   197  	}
   198  }
   199  
   200  const test1Gen = `type test1 uint32
   201  
   202  func (t test1) fob() uint16 {
   203  	return uint16((t >> 16) & 0xffff)
   204  }
   205  
   206  func (t test1) baz() int8 {
   207  	return int8((t >> 11) & 0x1f)
   208  }
   209  
   210  func (t test1) bar() myUint8 {
   211  	return myUint8((t >> 8) & 0x7)
   212  }
   213  
   214  func (t test1) Bool() bool {
   215  	const bit = 1 << 7
   216  	return t&bit == bit
   217  }
   218  
   219  func (t test1) Baz() int8 {
   220  	return int8((t >> 4) & 0x7)
   221  }
   222  `
   223  
   224  func mustRead(filename string) string {
   225  	b, err := os.ReadFile(filename)
   226  	if err != nil {
   227  		panic(err)
   228  	}
   229  	return string(b)
   230  }
   231  

View as plain text