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