github.com/jmigpin/editor@v1.6.0/core/godebug/debug/stringify_test.go (about)

     1  package debug
     2  
     3  import (
     4  	"regexp"
     5  	"testing"
     6  	"unsafe"
     7  )
     8  
     9  func TestStringify(t *testing.T) {
    10  	a := int(1)
    11  	runTest1(t, a, "1")
    12  
    13  	b := int(1)
    14  	//runTest1(t, &b, "@0x.*")
    15  	runTest1(t, &b, "&1")
    16  
    17  	var c *int
    18  	runTest1(t, c, "nil")
    19  	runTest1(t, &c, "&nil")
    20  }
    21  
    22  func TestStringifyPtr2(t *testing.T) {
    23  	type St1 struct {
    24  		a int
    25  		B int
    26  	}
    27  	var a St1
    28  	runTest1(t, &a, "&St1{0 0}")
    29  	//runTest1(t, &a, "&{0 0}")
    30  }
    31  
    32  func TestStringifyPtr3(t *testing.T) {
    33  	type St1 struct {
    34  		a int
    35  		B int
    36  	}
    37  	var v1 *St1
    38  	runTest1(t, v1, "nil")
    39  
    40  	v2 := &St1{2, 3}
    41  	runTest1(t, v2, "&St1{2 3}")
    42  	//runTest1(t, v2, "&{2 3}")
    43  
    44  	v3 := &v2
    45  	//runTest1(t, &v3, "@0x.*")
    46  	runTest1(t, &v3, "&&&St1{2 3}")
    47  	//runTest1(t, &v3, "&&&{2 3}")
    48  }
    49  
    50  func TestStringifyUintptr(t *testing.T) {
    51  	type Handle uintptr
    52  	a := Handle(0)
    53  	runTest1(t, a, "0x0")
    54  	b := Handle(1)
    55  	runTest1(t, b, "0x1")
    56  }
    57  
    58  func TestStringifyMap(t *testing.T) {
    59  	//a := map[string]int{"a": 1, "b": 2}
    60  	//runTest1(t, a, "map[\"a\":1 \"b\":2]") // TODO: key order
    61  }
    62  
    63  func TestStringifySlice(t *testing.T) {
    64  	type S1 struct {
    65  		a int
    66  		B int
    67  	}
    68  	a := []*S1{{1, 2}, {3, 4}, {5, 6}}
    69  	runTest1(t, a, "[&{1 2} &{3 4} &{5 6}]")
    70  	runTest1(t, a[1:1], "[]")
    71  	runTest1(t, a[1:2], "[&{3 4}]")
    72  
    73  	b := []*S1{nil, nil}
    74  	runTest1(t, b, "[nil nil]")
    75  }
    76  
    77  func TestStringifySlice2(t *testing.T) {
    78  	type S1 struct {
    79  		a int
    80  		B int
    81  		c interface{}
    82  	}
    83  	a := []*S1{{1, 2, 10}, {3, 4, true}}
    84  	runTest1(t, a, "[&{1 2 10} &{3 4 true}]")
    85  
    86  	type S2 struct{ b bool }
    87  	b := []*S1{{1, 2, S2{true}}, {3, 4, &S2{false}}}
    88  	//runTest1(t, b, "@\\[&{1 2 S2{true}} &{3 4 0x.*]")
    89  	//runTest2(t, b, "@\\[&{1 2 S2{true}} &{3 4 0x.*]", 150, 5)
    90  	runTest2(t, b, "@\\[&{1 2 S2{true}} &{3 4 &S2{...}}]", 100, 5)
    91  	runTest2(t, b, "[&{1 2 S2{true}} &{3 4 &S2{false}}]", 50, 10)
    92  
    93  	c := []*S1{{c: &S1{c: &S2{true}}}}
    94  	//runTest1(t, c, "@\\[&{0 0 0x.*}]")
    95  	runTest2(t, c, "[&{0 0 &S1{...}}]", 100, 4)
    96  	runTest2(t, c, "[&{0 0 &S1{0 0 &S2{true}}}]", 50, 10)
    97  }
    98  
    99  func TestStringifyArray(t *testing.T) {
   100  	type S1 struct {
   101  		a int
   102  		B int
   103  	}
   104  	a := [...]*S1{{1, 2}, {3, 4}, {5, 6}}
   105  	runTest1(t, a, "[&{1 2} &{3 4} &{5 6}]")
   106  }
   107  
   108  func TestStringifyInterface(t *testing.T) {
   109  	type S1 struct {
   110  		a int
   111  		B int
   112  		c interface{}
   113  	}
   114  	var a interface{} = &S1{1, 2, 3}
   115  	runTest1(t, a, "&S1{1 2 3}")
   116  	runTest1(t, &a, "&&S1{1 2 3}")
   117  	var c = &S1{1, 2, 3}
   118  	runTest1(t, c, "&S1{1 2 3}")
   119  
   120  	var b interface{} = &a
   121  	runTest1(t, b, "&&S1{1 2 3}")
   122  }
   123  
   124  func TestStringifyChan(t *testing.T) {
   125  	a := make(chan int)
   126  	runTest1(t, a, "@0x.*")
   127  	var b chan int
   128  	runTest1(t, &b, "&0x0")
   129  	var c *chan int
   130  	runTest1(t, c, "nil")
   131  	var d *chan int
   132  	runTest1(t, &d, "&nil")
   133  }
   134  
   135  func TestStringifyUnsafePointer(t *testing.T) {
   136  	a := 5
   137  	b := unsafe.Pointer(&a)
   138  	runTest1(t, b, "@0x.*")
   139  }
   140  
   141  func TestStringifyBytes(t *testing.T) {
   142  	a := []byte("abc")
   143  	runTest1(t, a, "[97 98 99]")
   144  
   145  	a2 := []byte{}
   146  	runTest1(t, a2, "[]")
   147  
   148  	b := []byte{1, 2, 3, 'a'}
   149  	runTest1(t, b, "[1 2 3 97]")
   150  	//runTest2(t, b, "[1 2 ...]", 2, 3)
   151  	runTest2(t, b, "[1 2 ...]", 4, 3)
   152  
   153  	type S1 struct {
   154  		a []byte
   155  	}
   156  	c := &S1{[]byte{1, 2, 3}}
   157  	runTest1(t, c, "&S1{[1 2 3]}")
   158  
   159  	//d := []byte{1, 2, 3}
   160  	//println(d)
   161  	//fmt.Printf("%v\n", d)
   162  	//fmt.Printf("%s\n", d)
   163  }
   164  
   165  func TestStringifyBytes2(t *testing.T) {
   166  	b := []byte{'a', 'b', 'c'}
   167  	for i := 0; i < 10; i++ {
   168  		b = append(b, b...)
   169  	}
   170  	runTest3(t, b, "\"abcabcabc...\"", 10, 5, true)
   171  }
   172  
   173  func TestStringifyBytes3(t *testing.T) {
   174  	type t1 struct {
   175  		b []byte
   176  	}
   177  	v1 := &t1{}
   178  	runTest3(t, v1, "&t1{\"\"}", 100, 55, true)
   179  
   180  	v2 := &t1{b: []byte("abc")}
   181  	runTest3(t, v2, "&t1{\"abc\"}", 100, 55, true)
   182  }
   183  
   184  func TestStringifyBytes4(t *testing.T) {
   185  	type t3 []byte
   186  	type t2 struct {
   187  		t3 t3
   188  	}
   189  	type t1 struct {
   190  		b  []byte
   191  		t2 t2
   192  	}
   193  	v1 := &t1{}
   194  	runTest3(t, v1, "&t1{\"\" {\"\"}}", 100, 55, true)
   195  }
   196  
   197  func TestStringifyString(t *testing.T) {
   198  	b := []byte{'a', 'b', 'c'}
   199  	for i := 0; i < 10; i++ {
   200  		b = append(b, b...)
   201  	}
   202  	c := string(b)
   203  	runTest2(t, c, "\"abcabcabc...\"", 10, 5)
   204  }
   205  
   206  func TestStringifyRunes(t *testing.T) {
   207  	b := []byte{'a', 'b', 'c'}
   208  	for i := 0; i < 10; i++ {
   209  		b = append(b, b...)
   210  	}
   211  	c := []rune(string(b))
   212  	runTest3(t, c, "\"abcabcabc...\"", 10, 5, true)
   213  }
   214  
   215  func TestStringifyNilReceiver(t *testing.T) {
   216  	var p *Dummy1
   217  	runTest1(t, p, "nil")
   218  
   219  	a := uintptr(0)
   220  	var b *Dummy1 = (*Dummy1)(unsafe.Pointer(a))
   221  	runTest1(t, b, "nil")
   222  
   223  	a = uintptr(1)
   224  	b = (*Dummy1)(unsafe.Pointer(a))
   225  	//runTest1(t, b, "(PANIC:String())")
   226  	runTest1(t, b, "&Dummy1{\"\"PANIC}")
   227  }
   228  
   229  func TestStringifyStringError(t *testing.T) {
   230  	v1 := &Dummy1{"aa"}
   231  	runTest1(t, v1, "&Dummy1{\"aa\"}")
   232  
   233  	v2 := &Dummy2{"bb"}
   234  	runTest1(t, v2, "&Dummy2{\"bb\"}")
   235  }
   236  
   237  func TestStringifyNil(t *testing.T) {
   238  	a := interface{}(nil)
   239  	runTest1(t, a, "nil")
   240  	runTest1(t, &a, "&nil")
   241  }
   242  
   243  //----------
   244  
   245  //func TestSliceCut(t *testing.T) {
   246  //	b1 := []interface{}{}
   247  //	for i := 0; i < 50; i++ {
   248  //		b1 = append(b1, i)
   249  //	}
   250  //	t.Logf("%0.5v\n", b1) // not trimmed
   251  //	t.Logf("%0.5q\n", b1)
   252  //	t.Logf("%0.5x\n", b1)
   253  //	t.Logf("%0.5s\n", b1)
   254  //	t.Logf("%0.2v\n", true)
   255  //}
   256  
   257  //----------
   258  
   259  func runTest1(t *testing.T, v interface{}, out string) {
   260  	t.Helper()
   261  	runTest2(t, v, out, 0, 0)
   262  }
   263  func runTest2(t *testing.T, v interface{}, out string, max, maxDepth int) {
   264  	t.Helper()
   265  	runTest3(t, v, out, max, maxDepth, false)
   266  }
   267  func runTest3(t *testing.T, v interface{}, out string, max, maxDepth int, sbr bool) {
   268  	t.Helper()
   269  	s2 := ""
   270  	if max == 0 && maxDepth == 0 {
   271  		// use production values
   272  		s2 = stringifyV3(v)
   273  	} else {
   274  		p := newPrint3(max, maxDepth, sbr)
   275  		p.do(v)
   276  		s2 = p.ToString()
   277  	}
   278  
   279  	// support regular expression match if starting with @
   280  	res := false
   281  	if len(out) > 0 && out[0] == '@' {
   282  		out = out[1:]
   283  		m, err := regexp.MatchString("^"+out+"$", s2)
   284  		if err != nil {
   285  			panic(err)
   286  		}
   287  		res = m
   288  	} else {
   289  		res = s2 == out
   290  	}
   291  
   292  	if !res {
   293  		t.Fatalf("got %q expecting %q", s2, out)
   294  	}
   295  }
   296  
   297  //----------
   298  
   299  type Dummy1 struct{ s string }
   300  
   301  func (d *Dummy1) String() string { return d.s }
   302  
   303  type Dummy2 struct{ s string }
   304  
   305  func (d *Dummy2) Error() string { return d.s }