escape_test.go raw

   1  package text
   2  
   3  import (
   4  	"testing"
   5  
   6  	"next.orly.dev/pkg/lol/chk"
   7  	"lukechampine.com/frand"
   8  	"github.com/minio/sha256-simd"
   9  )
  10  
  11  func TestUnescapeByteString(t *testing.T) {
  12  	b := make([]byte, 256)
  13  	for i := range b {
  14  		b[i] = byte(i)
  15  	}
  16  	escaped := NostrEscape(nil, b)
  17  	unescaped := NostrUnescape(escaped)
  18  	if string(b) != string(unescaped) {
  19  		t.Log(b)
  20  		t.Log(unescaped)
  21  		t.FailNow()
  22  	}
  23  }
  24  
  25  func GenRandString(l int, src *frand.RNG) (str []byte) {
  26  	return src.Bytes(l)
  27  }
  28  
  29  var seed = sha256.Sum256(
  30  	[]byte(`
  31  The tao that can be told
  32  is not the eternal Tao
  33  The name that can be named
  34  is not the eternal Name
  35  
  36  The unnamable is the eternally real
  37  Naming is the origin of all particular things
  38  
  39  Free from desire, you realize the mystery
  40  Caught in desire, you see only the manifestations
  41  
  42  Yet mystery and manifestations arise from the same source
  43  This source is called darkness
  44  
  45  Darkness within darkness
  46  The gateway to all understanding
  47  `),
  48  )
  49  
  50  var src = frand.NewCustom(seed[:], 32, 12)
  51  
  52  func TestRandomEscapeByteString(t *testing.T) {
  53  	// this is a kind of fuzz test, does a massive number of iterations of
  54  	// random content that ensures the escaping is correct without creating a
  55  	// fixed set of test vectors.
  56  
  57  	for i := 0; i < 1000; i++ {
  58  		l := src.Intn(1<<8) + 32
  59  		s1 := GenRandString(l, src)
  60  		s2 := make([]byte, l)
  61  		orig := make([]byte, l)
  62  		copy(s2, s1)
  63  		copy(orig, s1)
  64  
  65  		// first we are checking our implementation comports to the one from go-nostr.
  66  		escapeStringVersion := NostrEscape([]byte{}, s1)
  67  		escapeJSONStringAndWrapVersion := NostrEscape(nil, s2)
  68  		if len(escapeJSONStringAndWrapVersion) != len(escapeStringVersion) {
  69  			t.Logf(
  70  				"escapeString\nlength: %d\n%s\n%v\n",
  71  				len(escapeStringVersion), string(escapeStringVersion),
  72  				escapeStringVersion,
  73  			)
  74  			t.Logf(
  75  				"escapJSONStringAndWrap\nlength: %d\n%s\n%v\n",
  76  				len(escapeJSONStringAndWrapVersion),
  77  				escapeJSONStringAndWrapVersion,
  78  				escapeJSONStringAndWrapVersion,
  79  			)
  80  			t.FailNow()
  81  		}
  82  		for i := range escapeStringVersion {
  83  			if i > len(escapeJSONStringAndWrapVersion) {
  84  				t.Fatal("escapeString version is shorter")
  85  			}
  86  			if escapeStringVersion[i] != escapeJSONStringAndWrapVersion[i] {
  87  				t.Logf(
  88  					"escapeString version differs at index %d from "+
  89  						"escapeJSONStringAndWrap version\n%s\n%s\n%v\n%v", i,
  90  					escapeStringVersion[i-4:],
  91  					escapeJSONStringAndWrapVersion[i-4:],
  92  					escapeStringVersion[i-4:],
  93  					escapeJSONStringAndWrapVersion[i-4:],
  94  				)
  95  				t.Logf(
  96  					"escapeString\nlength: %d %s\n",
  97  					len(escapeStringVersion), escapeStringVersion,
  98  				)
  99  				t.Logf(
 100  					"escapJSONStringAndWrap\nlength: %d %s\n",
 101  					len(escapeJSONStringAndWrapVersion),
 102  					escapeJSONStringAndWrapVersion,
 103  				)
 104  				t.Logf(
 105  					"got '%s' %d expected '%s' %d\n",
 106  					string(escapeJSONStringAndWrapVersion[i]),
 107  					escapeJSONStringAndWrapVersion[i],
 108  					string(escapeStringVersion[i]),
 109  					escapeStringVersion[i],
 110  				)
 111  				t.FailNow()
 112  			}
 113  		}
 114  
 115  		// next, unescape the output and see if it matches the original
 116  		unescaped := NostrUnescape(escapeJSONStringAndWrapVersion)
 117  		// t.Logf("unescaped: \n%s\noriginal:  \n%s", unescaped, orig)
 118  		if string(unescaped) != string(orig) {
 119  			t.Fatalf(
 120  				"\ngot      %d %v\nexpected %d %v\n",
 121  				len(unescaped),
 122  				unescaped,
 123  				len(orig),
 124  				orig,
 125  			)
 126  		}
 127  	}
 128  }
 129  
 130  func BenchmarkNostrEscapeNostrUnescape(b *testing.B) {
 131  	const size = 65536
 132  	b.Run(
 133  		"frand64k", func(b *testing.B) {
 134  			b.ReportAllocs()
 135  			in := make([]byte, size)
 136  			var err error
 137  			for i := 0; i < b.N; i++ {
 138  				if _, err = frand.Read(in); chk.E(err) {
 139  					b.Fatal(err)
 140  				}
 141  			}
 142  		},
 143  	)
 144  	b.Run(
 145  		"NostrEscape64k", func(b *testing.B) {
 146  			b.ReportAllocs()
 147  			in := make([]byte, size)
 148  			out := make([]byte, size*2)
 149  			var err error
 150  			for i := 0; i < b.N; i++ {
 151  				if _, err = frand.Read(in); chk.E(err) {
 152  					b.Fatal(err)
 153  				}
 154  				out = NostrEscape(out, in)
 155  				out = out[:0]
 156  			}
 157  		},
 158  	)
 159  	b.Run(
 160  		"NostrEscapeNostrUnescape64k", func(b *testing.B) {
 161  			b.ReportAllocs()
 162  			in := make([]byte, size)
 163  			out := make([]byte, size*2)
 164  			var err error
 165  			for i := 0; i < b.N; i++ {
 166  				if _, err = frand.Read(in); chk.E(err) {
 167  					b.Fatal(err)
 168  				}
 169  				out = NostrEscape(out, in)
 170  				in = in[:0]
 171  				out = NostrUnescape(out)
 172  				out = out[:0]
 173  			}
 174  		},
 175  	)
 176  	b.Run(
 177  		"frand32k", func(b *testing.B) {
 178  			b.ReportAllocs()
 179  			size := size / 2
 180  			in := make([]byte, size)
 181  			var err error
 182  			for i := 0; i < b.N; i++ {
 183  				if _, err = frand.Read(in); chk.E(err) {
 184  					b.Fatal(err)
 185  				}
 186  			}
 187  		},
 188  	)
 189  	b.Run(
 190  		"NostrEscape32k", func(b *testing.B) {
 191  			b.ReportAllocs()
 192  			size := size / 2
 193  			in := make([]byte, size)
 194  			out := make([]byte, size*2)
 195  			var err error
 196  			for i := 0; i < b.N; i++ {
 197  				if _, err = frand.Read(in); chk.E(err) {
 198  					b.Fatal(err)
 199  				}
 200  				out = NostrEscape(out, in)
 201  				out = out[:0]
 202  			}
 203  		},
 204  	)
 205  	b.Run(
 206  		"NostrEscapeNostrUnescape32k", func(b *testing.B) {
 207  			b.ReportAllocs()
 208  			size := size / 2
 209  			in := make([]byte, size)
 210  			out := make([]byte, size*2)
 211  			var err error
 212  			for i := 0; i < b.N; i++ {
 213  				if _, err = frand.Read(in); chk.E(err) {
 214  					b.Fatal(err)
 215  				}
 216  				out = NostrEscape(out, in)
 217  				in = in[:0]
 218  				out = NostrUnescape(out)
 219  				out = out[:0]
 220  			}
 221  		},
 222  	)
 223  	b.Run(
 224  		"frand16k", func(b *testing.B) {
 225  			b.ReportAllocs()
 226  			size := size / 4
 227  			in := make([]byte, size)
 228  			var err error
 229  			for i := 0; i < b.N; i++ {
 230  				if _, err = frand.Read(in); chk.E(err) {
 231  					b.Fatal(err)
 232  				}
 233  			}
 234  		},
 235  	)
 236  	b.Run(
 237  		"NostrEscape16k", func(b *testing.B) {
 238  			b.ReportAllocs()
 239  			size := size / 4
 240  			in := make([]byte, size)
 241  			out := make([]byte, size*2)
 242  			var err error
 243  			for i := 0; i < b.N; i++ {
 244  				if _, err = frand.Read(in); chk.E(err) {
 245  					b.Fatal(err)
 246  				}
 247  				out = NostrEscape(out, in)
 248  				out = out[:0]
 249  			}
 250  		},
 251  	)
 252  	b.Run(
 253  		"NostrEscapeNostrUnescape16k", func(b *testing.B) {
 254  			b.ReportAllocs()
 255  			size := size / 4
 256  			in := make([]byte, size)
 257  			out := make([]byte, size*2)
 258  			var err error
 259  			for i := 0; i < b.N; i++ {
 260  				if _, err = frand.Read(in); chk.E(err) {
 261  					b.Fatal(err)
 262  				}
 263  				out = NostrEscape(out, in)
 264  				in = in[:0]
 265  				out = NostrUnescape(out)
 266  				out = out[:0]
 267  			}
 268  		},
 269  	)
 270  	b.Run(
 271  		"frand8k", func(b *testing.B) {
 272  			b.ReportAllocs()
 273  			size := size / 8
 274  			in := make([]byte, size)
 275  			var err error
 276  			for i := 0; i < b.N; i++ {
 277  				if _, err = frand.Read(in); chk.E(err) {
 278  					b.Fatal(err)
 279  				}
 280  			}
 281  		},
 282  	)
 283  	b.Run(
 284  		"NostrEscape8k", func(b *testing.B) {
 285  			b.ReportAllocs()
 286  			size := size / 8
 287  			in := make([]byte, size)
 288  			out := make([]byte, size*2)
 289  			var err error
 290  			for i := 0; i < b.N; i++ {
 291  				if _, err = frand.Read(in); chk.E(err) {
 292  					b.Fatal(err)
 293  				}
 294  				out = NostrEscape(out, in)
 295  				out = out[:0]
 296  			}
 297  		},
 298  	)
 299  	b.Run(
 300  		"NostrEscapeNostrUnescape8k", func(b *testing.B) {
 301  			b.ReportAllocs()
 302  			size := size / 8
 303  			in := make([]byte, size)
 304  			out := make([]byte, size*2)
 305  			var err error
 306  			for i := 0; i < b.N; i++ {
 307  				if _, err = frand.Read(in); chk.E(err) {
 308  					b.Fatal(err)
 309  				}
 310  				out = NostrEscape(out, in)
 311  				in = in[:0]
 312  				out = NostrUnescape(out)
 313  				out = out[:0]
 314  			}
 315  		},
 316  	)
 317  	b.Run(
 318  		"frand4k", func(b *testing.B) {
 319  			b.ReportAllocs()
 320  			size := size / 16
 321  			in := make([]byte, size)
 322  			var err error
 323  			for i := 0; i < b.N; i++ {
 324  				if _, err = frand.Read(in); chk.E(err) {
 325  					b.Fatal(err)
 326  				}
 327  			}
 328  		},
 329  	)
 330  	b.Run(
 331  		"NostrEscape4k", func(b *testing.B) {
 332  			b.ReportAllocs()
 333  			size := size / 16
 334  			in := make([]byte, size)
 335  			out := make([]byte, size*2)
 336  			var err error
 337  			for i := 0; i < b.N; i++ {
 338  				if _, err = frand.Read(in); chk.E(err) {
 339  					b.Fatal(err)
 340  				}
 341  				out = NostrEscape(out, in)
 342  				out = out[:0]
 343  			}
 344  		},
 345  	)
 346  	b.Run(
 347  		"NostrEscapeNostrUnescape4k", func(b *testing.B) {
 348  			b.ReportAllocs()
 349  			size := size / 16
 350  			in := make([]byte, size)
 351  			out := make([]byte, size*2)
 352  			var err error
 353  			for i := 0; i < b.N; i++ {
 354  				if _, err = frand.Read(in); chk.E(err) {
 355  					b.Fatal(err)
 356  				}
 357  				out = NostrEscape(out, in)
 358  				in = in[:0]
 359  				out = NostrUnescape(out)
 360  				out = out[:0]
 361  			}
 362  		},
 363  	)
 364  	b.Run(
 365  		"frand2k", func(b *testing.B) {
 366  			b.ReportAllocs()
 367  			size := size / 32
 368  			in := make([]byte, size)
 369  			var err error
 370  			for i := 0; i < b.N; i++ {
 371  				if _, err = frand.Read(in); chk.E(err) {
 372  					b.Fatal(err)
 373  				}
 374  			}
 375  		},
 376  	)
 377  	b.Run(
 378  		"NostrEscape2k", func(b *testing.B) {
 379  			b.ReportAllocs()
 380  			size := size / 32
 381  			in := make([]byte, size)
 382  			out := make([]byte, size*2)
 383  			var err error
 384  			for i := 0; i < b.N; i++ {
 385  				if _, err = frand.Read(in); chk.E(err) {
 386  					b.Fatal(err)
 387  				}
 388  				out = NostrEscape(out, in)
 389  				out = out[:0]
 390  			}
 391  		},
 392  	)
 393  	b.Run(
 394  		"NostrEscapeNostrUnescape2k", func(b *testing.B) {
 395  			b.ReportAllocs()
 396  			size := size / 32
 397  			in := make([]byte, size)
 398  			out := make([]byte, size*2)
 399  			var err error
 400  			for i := 0; i < b.N; i++ {
 401  				if _, err = frand.Read(in); chk.E(err) {
 402  					b.Fatal(err)
 403  				}
 404  				out = NostrEscape(out, in)
 405  				in = in[:0]
 406  				out = NostrUnescape(out)
 407  				out = out[:0]
 408  			}
 409  		},
 410  	)
 411  	b.Run(
 412  		"frand1k", func(b *testing.B) {
 413  			b.ReportAllocs()
 414  			size := size / 64
 415  			in := make([]byte, size)
 416  			var err error
 417  			for i := 0; i < b.N; i++ {
 418  				if _, err = frand.Read(in); chk.E(err) {
 419  					b.Fatal(err)
 420  				}
 421  			}
 422  		},
 423  	)
 424  	b.Run(
 425  		"NostrEscape1k", func(b *testing.B) {
 426  			b.ReportAllocs()
 427  			size := size / 64
 428  			in := make([]byte, size)
 429  			out := make([]byte, size*2)
 430  			var err error
 431  			for i := 0; i < b.N; i++ {
 432  				if _, err = frand.Read(in); chk.E(err) {
 433  					b.Fatal(err)
 434  				}
 435  				out = NostrEscape(out, in)
 436  				out = out[:0]
 437  			}
 438  		},
 439  	)
 440  	b.Run(
 441  		"NostrEscapeNostrUnescape1k", func(b *testing.B) {
 442  			b.ReportAllocs()
 443  			size := size / 64
 444  			in := make([]byte, size)
 445  			out := make([]byte, size*2)
 446  			var err error
 447  			for i := 0; i < b.N; i++ {
 448  				if _, err = frand.Read(in); chk.E(err) {
 449  					b.Fatal(err)
 450  				}
 451  				out = NostrEscape(out, in)
 452  				in = in[:0]
 453  				out = NostrUnescape(out)
 454  				out = out[:0]
 455  			}
 456  		},
 457  	)
 458  }
 459