goscript 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/cmd/go_js_wasm_exec/main.go +1 -1
- package/cmd/go_js_wasm_exec/main_test.go +1 -1
- package/cmd/goscript/cmd-compile.go +9 -1
- package/cmd/goscript/cmd-test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +44 -0
- package/cmd/goscript/deps.go +1 -1
- package/cmd/goscript-wasm/main.go +2 -2
- package/compiler/compile-request.go +19 -0
- package/compiler/compile_bench_test.go +121 -0
- package/compiler/compliance_test.go +17 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/result.go +1 -1
- package/compiler/gotest/runner.go +2 -2
- package/compiler/gotest/runner_test.go +4 -7
- package/compiler/index.test.ts +28 -0
- package/compiler/index.ts +32 -16
- package/compiler/lowering.go +1238 -194
- package/compiler/lowering_bench_test.go +4 -0
- package/compiler/override-facts.go +1 -1
- package/compiler/package-graph.go +92 -0
- package/compiler/package-graph_test.go +113 -0
- package/compiler/runtime-contract.go +1 -1
- package/compiler/semantic-model.go +32 -0
- package/compiler/skeleton_test.go +241 -15
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +1 -1
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +26 -15
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/database/sql/driver/index.d.ts +165 -0
- package/dist/gs/database/sql/driver/index.js +432 -0
- package/dist/gs/database/sql/driver/index.js.map +1 -0
- package/dist/gs/encoding/binary/index.d.ts +71 -0
- package/dist/gs/encoding/binary/index.js +778 -0
- package/dist/gs/encoding/binary/index.js.map +1 -0
- package/dist/gs/fmt/fmt.js +156 -57
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
- package/dist/gs/github.com/pkg/errors/index.js +1 -1
- package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
- package/dist/gs/github.com/pkg/errors/stack.js +26 -61
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +6 -1
- package/dist/gs/runtime/runtime.js +15 -8
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.d.ts +8 -5
- package/dist/gs/runtime/trace/index.js +324 -23
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +2 -1
- package/dist/gs/slices/slices.js +9 -3
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/search.gs.d.ts +3 -1
- package/dist/gs/sort/search.gs.js +18 -53
- package/dist/gs/sort/search.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +1 -1
- package/dist/gs/sync/sync.js +3 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/time/time.d.ts +22 -29
- package/dist/gs/time/time.js +111 -32
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unsafe/unsafe.d.ts +3 -2
- package/dist/gs/unsafe/unsafe.js.map +1 -1
- package/go.mod +7 -5
- package/go.sum +12 -26
- package/gs/database/sql/driver/index.test.ts +88 -0
- package/gs/database/sql/driver/index.ts +675 -0
- package/gs/database/sql/driver/meta.json +3 -0
- package/gs/database/sql/driver/parity.json +144 -0
- package/gs/encoding/binary/index.test.ts +239 -0
- package/gs/encoding/binary/index.ts +999 -0
- package/gs/encoding/binary/meta.json +9 -0
- package/gs/encoding/binary/parity.json +72 -0
- package/gs/fmt/fmt.test.ts +28 -0
- package/gs/fmt/fmt.ts +198 -61
- package/gs/fmt/meta.json +2 -1
- package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
- package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
- package/gs/github.com/pkg/errors/errors.ts +1 -2
- package/gs/github.com/pkg/errors/index.ts +2 -1
- package/gs/github.com/pkg/errors/stack.ts +34 -62
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
- package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
- package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
- package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
- package/gs/runtime/runtime.test.ts +16 -0
- package/gs/runtime/runtime.ts +17 -9
- package/gs/runtime/trace/index.test.ts +113 -14
- package/gs/runtime/trace/index.ts +384 -34
- package/gs/runtime/trace/meta.json +1 -0
- package/gs/slices/slices.test.ts +24 -1
- package/gs/slices/slices.ts +14 -4
- package/gs/sort/meta.json +1 -0
- package/gs/sort/search.gs.ts +20 -5
- package/gs/sync/sync.ts +4 -1
- package/gs/time/time.test.ts +79 -2
- package/gs/time/time.ts +133 -33
- package/gs/unsafe/unsafe.ts +4 -2
- package/package.json +2 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { AnyOverlap, InexactOverlap } from './index.js'
|
|
4
|
+
|
|
5
|
+
describe('crypto/internal/alias override', () => {
|
|
6
|
+
test('reports no overlap for distinct backings', () => {
|
|
7
|
+
const x = new Uint8Array([1, 2, 3, 4])
|
|
8
|
+
const y = new Uint8Array([1, 2, 3, 4])
|
|
9
|
+
expect(AnyOverlap(x, y)).toBe(false)
|
|
10
|
+
expect(InexactOverlap(x, y)).toBe(false)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('reports no overlap when either slice is empty', () => {
|
|
14
|
+
const buf = new Uint8Array(8)
|
|
15
|
+
expect(AnyOverlap(buf, new Uint8Array(0))).toBe(false)
|
|
16
|
+
expect(AnyOverlap(new Uint8Array(0), buf)).toBe(false)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('detects overlap of views over a shared backing', () => {
|
|
20
|
+
const buf = new Uint8Array(8)
|
|
21
|
+
const head = buf.subarray(0, 4)
|
|
22
|
+
const tail = buf.subarray(4, 8)
|
|
23
|
+
const straddle = buf.subarray(2, 6)
|
|
24
|
+
// Disjoint halves of the same buffer do not overlap.
|
|
25
|
+
expect(AnyOverlap(head, tail)).toBe(false)
|
|
26
|
+
// A straddling view overlaps both halves.
|
|
27
|
+
expect(AnyOverlap(head, straddle)).toBe(true)
|
|
28
|
+
expect(AnyOverlap(tail, straddle)).toBe(true)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('InexactOverlap ignores exactly aligned identical starts', () => {
|
|
32
|
+
const buf = new Uint8Array(8)
|
|
33
|
+
const a = buf.subarray(0, 4)
|
|
34
|
+
const b = buf.subarray(0, 4)
|
|
35
|
+
// Same start address: exact overlap, so InexactOverlap is false.
|
|
36
|
+
expect(InexactOverlap(a, b)).toBe(false)
|
|
37
|
+
// But AnyOverlap still reports the shared memory.
|
|
38
|
+
expect(AnyOverlap(a, b)).toBe(true)
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
|
|
3
|
+
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
|
4
|
+
// corresponding) index. The memory beyond the slice length is ignored.
|
|
5
|
+
//
|
|
6
|
+
// This mirrors the upstream pointer comparison without reflect or unsafe by
|
|
7
|
+
// using GoScript synthetic byte addresses. Those addresses are stride separated
|
|
8
|
+
// per backing array, so slices over distinct backings can never compare as
|
|
9
|
+
// overlapping and slices over a shared backing compare by element offset, which
|
|
10
|
+
// reproduces the Go semantics the crypto cipher modes rely on.
|
|
11
|
+
export function AnyOverlap(x: $.Bytes, y: $.Bytes): boolean {
|
|
12
|
+
const xLen = $.len(x)
|
|
13
|
+
const yLen = $.len(y)
|
|
14
|
+
if (xLen === 0 || yLen === 0) {
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
const xFirst = $.indexByteAddress(x, 0, 1)
|
|
18
|
+
const xLast = $.indexByteAddress(x, xLen - 1, 1)
|
|
19
|
+
const yFirst = $.indexByteAddress(y, 0, 1)
|
|
20
|
+
const yLast = $.indexByteAddress(y, yLen - 1, 1)
|
|
21
|
+
return xFirst <= yLast && yFirst <= xLast
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
|
25
|
+
// index. The memory beyond the slice length is ignored. Note that x and y can
|
|
26
|
+
// have different lengths and still not have any inexact overlap.
|
|
27
|
+
//
|
|
28
|
+
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
|
29
|
+
// AEAD, Block, BlockMode and Stream interfaces.
|
|
30
|
+
export function InexactOverlap(x: $.Bytes, y: $.Bytes): boolean {
|
|
31
|
+
const xLen = $.len(x)
|
|
32
|
+
const yLen = $.len(y)
|
|
33
|
+
if (xLen === 0 || yLen === 0) {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
36
|
+
if ($.indexByteAddress(x, 0, 1) === $.indexByteAddress(y, 0, 1)) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
return AnyOverlap(x, y)
|
|
40
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
|
|
3
5
|
import {
|
|
4
6
|
Compiler,
|
|
5
7
|
FuncForPC,
|
|
8
|
+
MemStats,
|
|
9
|
+
ReadMemStats,
|
|
6
10
|
ReadTrace,
|
|
7
11
|
SetFinalizer,
|
|
8
12
|
StartTrace,
|
|
@@ -25,4 +29,16 @@ describe('runtime override', () => {
|
|
|
25
29
|
expect(() => SetFinalizer(obj, () => {})).not.toThrow()
|
|
26
30
|
expect(() => SetFinalizer(obj, null)).not.toThrow()
|
|
27
31
|
})
|
|
32
|
+
|
|
33
|
+
it('exposes heap and stack MemStats fields', () => {
|
|
34
|
+
const stats = new MemStats()
|
|
35
|
+
|
|
36
|
+
ReadMemStats($.varRef(stats))
|
|
37
|
+
|
|
38
|
+
expect(stats.HeapAlloc).toBe(stats.Alloc)
|
|
39
|
+
expect(stats.HeapSys).toBe(stats.Sys)
|
|
40
|
+
expect(stats.HeapInuse).toBe(stats.Alloc)
|
|
41
|
+
expect(stats.StackInuse).toBe(0)
|
|
42
|
+
expect(stats.StackSys).toBe(0)
|
|
43
|
+
})
|
|
28
44
|
})
|
package/gs/runtime/runtime.ts
CHANGED
|
@@ -170,6 +170,11 @@ export class MemStats {
|
|
|
170
170
|
public Alloc: number = 0 // bytes allocated and not yet freed
|
|
171
171
|
public TotalAlloc: number = 0 // bytes allocated (even if freed)
|
|
172
172
|
public Sys: number = 0 // bytes obtained from system
|
|
173
|
+
public HeapAlloc: number = 0 // bytes allocated and not yet freed on the heap
|
|
174
|
+
public HeapSys: number = 0 // bytes obtained from system for the heap
|
|
175
|
+
public HeapInuse: number = 0 // bytes in in-use heap spans
|
|
176
|
+
public StackInuse: number = 0 // bytes in stack spans
|
|
177
|
+
public StackSys: number = 0 // bytes obtained from system for stacks
|
|
173
178
|
public Lookups: number = 0 // number of pointer lookups
|
|
174
179
|
public Mallocs: number = 0 // number of mallocs
|
|
175
180
|
public Frees: number = 0 // number of frees
|
|
@@ -181,25 +186,28 @@ export class MemStats {
|
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
private updateMemoryStats(): void {
|
|
184
|
-
|
|
185
|
-
if (typeof performance !== 'undefined' && (performance as any).memory) {
|
|
186
|
-
const mem = (performance as any).memory
|
|
187
|
-
this.Alloc = mem.usedJSHeapSize || 0
|
|
188
|
-
this.Sys = mem.totalJSHeapSize || 0
|
|
189
|
-
this.TotalAlloc = this.Alloc // Simplified
|
|
190
|
-
}
|
|
189
|
+
updateMemoryStats(this)
|
|
191
190
|
}
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
// ReadMemStats populates m with memory allocator statistics
|
|
195
|
-
export function ReadMemStats(m: MemStats): void {
|
|
196
|
-
|
|
194
|
+
export function ReadMemStats(m: MemStats | $.VarRef<MemStats> | null): void {
|
|
195
|
+
m = $.pointerValue<MemStats>(m)
|
|
196
|
+
updateMemoryStats(m)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function updateMemoryStats(m: MemStats): void {
|
|
197
200
|
if (typeof performance !== 'undefined' && (performance as any).memory) {
|
|
198
201
|
const mem = (performance as any).memory
|
|
199
202
|
m.Alloc = mem.usedJSHeapSize || 0
|
|
200
203
|
m.Sys = mem.totalJSHeapSize || 0
|
|
201
204
|
m.TotalAlloc = m.Alloc // Simplified
|
|
202
205
|
}
|
|
206
|
+
m.HeapAlloc = m.Alloc
|
|
207
|
+
m.HeapSys = m.Sys
|
|
208
|
+
m.HeapInuse = m.Alloc
|
|
209
|
+
m.StackInuse = 0
|
|
210
|
+
m.StackSys = 0
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
// Error interface for runtime errors
|
|
@@ -12,8 +12,69 @@ import {
|
|
|
12
12
|
WithRegion,
|
|
13
13
|
} from './index.js'
|
|
14
14
|
|
|
15
|
+
function captureWriter(): { chunks: Uint8Array[]; bytes(): Uint8Array } {
|
|
16
|
+
const chunks: Uint8Array[] = []
|
|
17
|
+
return {
|
|
18
|
+
chunks,
|
|
19
|
+
bytes(): Uint8Array {
|
|
20
|
+
const total = chunks.reduce((n, c) => n + c.length, 0)
|
|
21
|
+
const out = new Uint8Array(total)
|
|
22
|
+
let off = 0
|
|
23
|
+
for (const c of chunks) {
|
|
24
|
+
out.set(c, off)
|
|
25
|
+
off += c.length
|
|
26
|
+
}
|
|
27
|
+
return out
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const writerOf = (chunks: Uint8Array[]) => ({
|
|
33
|
+
Write(p: Uint8Array): [number, null] {
|
|
34
|
+
chunks.push(new Uint8Array(p))
|
|
35
|
+
return [p.length, null]
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// maxBatchSize mirrors the trace v2 reader limit (tracev2.MaxBatchSize, 64<<10).
|
|
40
|
+
// A batch whose declared data length exceeds this is rejected with "invalid
|
|
41
|
+
// batch size", so the encoder must split large captures across batches.
|
|
42
|
+
const maxBatchSize = 64 * 1024
|
|
43
|
+
|
|
44
|
+
// batchSizes walks the trace v2 stream past the 16-byte header and returns the
|
|
45
|
+
// declared data length of every EvEventBatch frame. Each frame is the batch
|
|
46
|
+
// kind byte (1), then uvarints for generation, M id, base timestamp, and data
|
|
47
|
+
// length, then the data block.
|
|
48
|
+
function batchSizes(bytes: Uint8Array): number[] {
|
|
49
|
+
const sizes: number[] = []
|
|
50
|
+
let i = 16 // header: "go 1.22 trace\x00\x00\x00"
|
|
51
|
+
const readUvarint = (): number => {
|
|
52
|
+
let value = 0
|
|
53
|
+
let shift = 0
|
|
54
|
+
for (;;) {
|
|
55
|
+
const b = bytes[i++]
|
|
56
|
+
value += (b & 0x7f) * 2 ** shift
|
|
57
|
+
if ((b & 0x80) === 0) {
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
shift += 7
|
|
61
|
+
}
|
|
62
|
+
return value
|
|
63
|
+
}
|
|
64
|
+
while (i < bytes.length) {
|
|
65
|
+
i++ // EvEventBatch kind byte
|
|
66
|
+
readUvarint() // generation
|
|
67
|
+
readUvarint() // M id
|
|
68
|
+
readUvarint() // base timestamp
|
|
69
|
+
const size = readUvarint()
|
|
70
|
+
sizes.push(size)
|
|
71
|
+
i += size
|
|
72
|
+
}
|
|
73
|
+
return sizes
|
|
74
|
+
}
|
|
75
|
+
|
|
15
76
|
describe('runtime/trace override', () => {
|
|
16
|
-
it('creates no-op tasks
|
|
77
|
+
it('creates no-op tasks when tracing is disabled', () => {
|
|
17
78
|
const [ctx, task] = NewTask(null, 'task')
|
|
18
79
|
|
|
19
80
|
expect(ctx).not.toBeNull()
|
|
@@ -23,7 +84,7 @@ describe('runtime/trace override', () => {
|
|
|
23
84
|
expect(IsEnabled()).toBe(false)
|
|
24
85
|
})
|
|
25
86
|
|
|
26
|
-
it('runs
|
|
87
|
+
it('runs regions', () => {
|
|
27
88
|
const [ctx] = NewTask(context.Background(), 'task')
|
|
28
89
|
const called = { value: false }
|
|
29
90
|
|
|
@@ -35,21 +96,59 @@ describe('runtime/trace override', () => {
|
|
|
35
96
|
expect(called.value).toBe(true)
|
|
36
97
|
})
|
|
37
98
|
|
|
38
|
-
it('
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
99
|
+
it('rejects a nil trace writer', () => {
|
|
100
|
+
expect(Start(null)?.Error()).toBe('runtime/trace: nil trace writer')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('emits a trace v2 stream for user tasks', () => {
|
|
104
|
+
const capture = captureWriter()
|
|
105
|
+
|
|
106
|
+
expect(Start(writerOf(capture.chunks))).toBeNull()
|
|
107
|
+
expect(IsEnabled()).toBe(true)
|
|
108
|
+
|
|
109
|
+
const [ctx, task] = NewTask(context.Background(), 'proof-task')
|
|
110
|
+
WithRegion(ctx, 'proof-region', () => {
|
|
111
|
+
Log(ctx, 'proof-key', 'proof-value')
|
|
112
|
+
})
|
|
113
|
+
task.End()
|
|
114
|
+
|
|
115
|
+
Stop()
|
|
116
|
+
expect(IsEnabled()).toBe(false)
|
|
117
|
+
|
|
118
|
+
const bytes = capture.bytes()
|
|
119
|
+
expect(bytes.length).toBeGreaterThan(0)
|
|
120
|
+
|
|
121
|
+
const header = new TextDecoder().decode(bytes.slice(0, 13))
|
|
122
|
+
expect(header).toBe('go 1.22 trace')
|
|
123
|
+
|
|
124
|
+
// The interned task and region names appear in the string batch.
|
|
125
|
+
const text = new TextDecoder('latin1').decode(bytes)
|
|
126
|
+
expect(text).toContain('proof-task')
|
|
127
|
+
expect(text).toContain('proof-region')
|
|
128
|
+
expect(text).toContain('proof-value')
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('splits a large capture into batches under the size limit', () => {
|
|
132
|
+
const capture = captureWriter()
|
|
133
|
+
|
|
134
|
+
expect(Start(writerOf(capture.chunks))).toBeNull()
|
|
135
|
+
|
|
136
|
+
// Record enough distinct tasks and logs to overflow the single-batch ceiling
|
|
137
|
+
// in both the string dictionary and the event stream.
|
|
138
|
+
const eventCount = 4000
|
|
139
|
+
for (let i = 0; i < eventCount; i++) {
|
|
140
|
+
const [ctx, task] = NewTask(context.Background(), `multibatch-task-${i}`)
|
|
141
|
+
Log(ctx, 'multibatch-key', `multibatch-message-${i}`)
|
|
142
|
+
task.End()
|
|
45
143
|
}
|
|
46
144
|
|
|
47
|
-
expect(Start(writer)?.Error()).toBe(
|
|
48
|
-
'runtime/trace: execution tracing is unsupported in GoScript',
|
|
49
|
-
)
|
|
50
|
-
Log(context.Background(), 'category', 'message')
|
|
51
145
|
Stop()
|
|
52
146
|
|
|
53
|
-
|
|
147
|
+
const sizes = batchSizes(capture.bytes())
|
|
148
|
+
// Frequency, plus several string and event batches.
|
|
149
|
+
expect(sizes.length).toBeGreaterThan(3)
|
|
150
|
+
for (const size of sizes) {
|
|
151
|
+
expect(size).toBeLessThanOrEqual(maxBatchSize)
|
|
152
|
+
}
|
|
54
153
|
})
|
|
55
154
|
})
|