github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/misc/logos/misc_test.go (about)

     1  package logos
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/gnolang/gno/tm2/pkg/random"
    10  )
    11  
    12  // Tests whether widthOf() and nextCharacter() do the same thing.
    13  func TestStringWidthSlow(t *testing.T) {
    14  	t.Skip("test failing")
    15  	for n := 1; n < 4; n++ {
    16  		bz := make([]byte, n)
    17  		for {
    18  			width1 := widthOf(string(bz))
    19  			width2 := widthOfSlow(string(bz))
    20  			if width1 == 0 {
    21  				if isRepeatedWZJ(bz) {
    22  					// these bytes encode one or more U+200D WZJ as UTF8.
    23  				} else {
    24  					require.Fail(t, fmt.Sprintf("unexpected zero width string for bytes %X", bz))
    25  				}
    26  			} else {
    27  				require.True(t, 0 < width1, "got zero width for bytes %X", bz)
    28  			}
    29  			require.Equal(t, width1, width2)
    30  			if !incBuffer(bz) {
    31  				break
    32  			}
    33  		}
    34  	}
    35  }
    36  
    37  // Same as above but for longer pseudo-random strings.
    38  func TestStringWidthRandom(t *testing.T) {
    39  	max := 10 * 1024 * 1024
    40  	for i := 0; i < max; i++ {
    41  		if i%(max/80) == 0 {
    42  			fmt.Print(".")
    43  		}
    44  		bz := random.RandBytes(12)
    45  		width1 := widthOf(string(bz))
    46  		width2 := widthOfSlow(string(bz))
    47  		if width1 == 0 {
    48  			if isRepeatedWZJ(bz) {
    49  				// these bytes encode one or more U+200D WZJ as UTF8.
    50  			} else {
    51  				require.Fail(t, "unexpected zero width string")
    52  			}
    53  		} else {
    54  			require.True(t, 0 < width1, "got zero width for bytes %X", bz)
    55  		}
    56  		require.Equal(t, width1, width2,
    57  			"want %d but got %d the slow way: %X",
    58  			width1, width2, bz)
    59  	}
    60  }
    61  
    62  // For debugging.
    63  func TestStringWidthDummy(t *testing.T) {
    64  	bz := []byte{0x0C, 0x5B, 0x0D, 0xCF, 0xC5, 0xE2, 0x80, 0x8D, 0xC1, 0x32, 0x69, 0x41}
    65  	width1 := widthOf(string(bz))
    66  	width2 := widthOfSlow(string(bz))
    67  	if width1 == 0 {
    68  		if isRepeatedWZJ(bz) {
    69  			// these bytes encode one or more U+200D WZJ as UTF8.
    70  		} else {
    71  			require.Fail(t, "unexpected zero width string")
    72  		}
    73  	} else {
    74  		require.True(t, 0 < width1, "got zero width for bytes %X", bz)
    75  	}
    76  	require.Equal(t, width1, width2,
    77  		"want %d but got %d the slow way: %X",
    78  		width1, width2, bz)
    79  }
    80  
    81  // For debugging.
    82  func TestStringWidthDummy2(t *testing.T) {
    83  	t.Skip("test failing")
    84  	// NOTE: this is broken in the OSX terminal.  This should print a USA flag
    85  	// and have width 2, or possibly default to two block letters "U" and "S",
    86  	// but my terminal prints a flag of width 1.
    87  	bz := []byte("\U0001f1fa\U0001f1f8")
    88  	width1 := widthOf(string(bz))
    89  	width2 := widthOfSlow(string(bz))
    90  	require.Equal(t, 1, width1)
    91  	require.Equal(t, width1, width2,
    92  		"want %d but got %d the slow way: %X",
    93  		width1, width2, bz)
    94  }
    95  
    96  func isRepeatedWZJ(bz []byte) bool {
    97  	if len(bz)%3 != 0 {
    98  		return false
    99  	}
   100  	// this is U+200D is UTF8.
   101  	for i := 0; i < len(bz); i += 3 {
   102  		if bz[i] != 0xE2 {
   103  			return false
   104  		}
   105  		if bz[i+1] != 0x80 {
   106  			return false
   107  		}
   108  		if bz[i+2] != 0x8D {
   109  			return false
   110  		}
   111  	}
   112  	return true
   113  }
   114  
   115  // get the width of a string using nextCharacter().
   116  func widthOfSlow(s string) (w int) {
   117  	rz := toRunes(s)
   118  	for 0 < len(rz) {
   119  		_, w2, n := nextCharacter(rz)
   120  		if n == 0 {
   121  			panic("should not happen")
   122  		}
   123  		w += w2
   124  		rz = rz[n:]
   125  	}
   126  	return
   127  }
   128  
   129  //----------------------------------------
   130  // incBuffer for testing
   131  
   132  // If overflow, bz becomes zero and returns false.
   133  func incBuffer(bz []byte) bool {
   134  	for i := 0; i < len(bz); i++ {
   135  		if bz[i] == 0xFF {
   136  			bz[i] = 0x00
   137  		} else {
   138  			bz[i]++
   139  			return true
   140  		}
   141  	}
   142  	return false
   143  }
   144  
   145  func TestIncBuffer1(t *testing.T) {
   146  	bz := []byte{0x00}
   147  	for i := 0; i < (1<<(1*8))-1; i++ {
   148  		require.Equal(t, true, incBuffer(bz))
   149  		require.Equal(t, byte(i+1), bz[0])
   150  	}
   151  	require.Equal(t, false, incBuffer(bz))
   152  	require.Equal(t, byte(0x00), bz[0])
   153  }
   154  
   155  func TestIncBuffer2(t *testing.T) {
   156  	bz := []byte{0x00, 0x00}
   157  	for i := 0; i < (1<<(2*8))-1; i++ {
   158  		require.Equal(t, true, incBuffer(bz))
   159  		require.Equal(t, byte(((i+1)>>0)%256), bz[0])
   160  		require.Equal(t, byte(((i+1)>>8)%256), bz[1])
   161  	}
   162  	require.Equal(t, []byte{0xFF, 0xFF}, bz)
   163  	require.Equal(t, false, incBuffer(bz))
   164  	require.Equal(t, byte(0x00), bz[0])
   165  	require.Equal(t, byte(0x00), bz[1])
   166  }