11import { SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE , SolanaError } from '@solana/errors' ;
22
3- import { FixedSizeCodec } from '../codec' ;
43import { offsetCodec } from '../offset-codec' ;
5- import { b , getMockCodec as getBaseMockCodec } from './__setup__' ;
6-
7- function getMockCodec ( { innerSize, totalSize } : { innerSize : number ; totalSize : number } ) {
8- const mockCodec = getBaseMockCodec ( { size : totalSize } ) ;
9- mockCodec . write . mockImplementation ( ( _value , _bytes , offset ) => offset + innerSize ) ;
10- mockCodec . read . mockImplementation ( ( bytes , offset ) => [ bytes , offset + innerSize ] ) ;
11- return mockCodec as typeof mockCodec & { fixedSize : number } ;
12- }
13-
14- function expectNewPreOffset (
15- codec : FixedSizeCodec < unknown > ,
16- mockCodec : FixedSizeCodec < unknown > ,
17- preOffset : number ,
18- expectedNewPreOffset : number ,
19- ) {
20- const bytes = new Uint8Array ( Array . from ( { length : codec . fixedSize } , ( ) => 0 ) ) ;
21- codec . write ( null , bytes , preOffset ) ;
22- expect ( mockCodec . write ) . toHaveBeenCalledWith ( null , bytes , expectedNewPreOffset ) ;
23- codec . read ( bytes , preOffset ) [ 1 ] ;
24- expect ( mockCodec . read ) . toHaveBeenCalledWith ( bytes , expectedNewPreOffset ) ;
25- }
26-
27- function expectNewPostOffset ( codec : FixedSizeCodec < unknown > , preOffset : number , expectedNewPostOffset : number ) {
28- const bytes = new Uint8Array ( Array . from ( { length : codec . fixedSize } , ( ) => 0 ) ) ;
29- expect ( codec . write ( null , bytes , preOffset ) ) . toBe ( expectedNewPostOffset ) ;
30- expect ( codec . read ( bytes , preOffset ) [ 1 ] ) . toBe ( expectedNewPostOffset ) ;
31- }
4+ import { b , expectNewPostOffset , expectNewPreOffset , getMockCodec } from './__setup__' ;
325
336describe ( 'offsetCodec' , ( ) => {
347 describe ( 'with relative offsets' , ( ) => {
358 it ( 'keeps the same pre-offset' , ( ) => {
36- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
9+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
3710 const codec = offsetCodec ( mockCodec , { preOffset : ( { preOffset } ) => preOffset } ) ;
3811 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 3 ) ;
3912 // Before: 0x000000[pre=3]ffffffff000000
4013 // After: 0x000000[pre=3]ffffffff000000
4114 } ) ;
4215
4316 it ( 'keeps the same post-offset' , ( ) => {
44- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
17+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
4518 const codec = offsetCodec ( mockCodec , { postOffset : ( { postOffset } ) => postOffset } ) ;
4619 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 7 ) ;
4720 // Before: 0x000000[pre=3]ffffffff[post=7]000000
4821 // After: 0x000000[pre=3]ffffffff[post=7]000000
4922 } ) ;
5023
5124 it ( 'doubles the pre-offset' , ( ) => {
52- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
25+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
5326 const codec = offsetCodec ( mockCodec , { preOffset : ( { preOffset } ) => preOffset * 2 } ) ;
5427 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 6 ) ;
5528 // Before: 0x000000[pre=3]ffffffff000000
5629 // After: 0x000000000000[pre=6]ffffffff
5730 } ) ;
5831
5932 it ( 'doubles the post-offset' , ( ) => {
60- const mockCodec = getMockCodec ( { innerSize : 1 , totalSize : 10 } ) ;
33+ const mockCodec = getMockCodec ( { innerSize : 1 , size : 10 } ) ;
6134 const codec = offsetCodec ( mockCodec , { postOffset : ( { postOffset } ) => postOffset * 2 } ) ;
6235 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 8 ) ;
6336 // Before: 0x000000[pre=3]ff[post=4]000000000000
6437 // After: 0x000000[pre=3]ff00000000[post=8]0000
6538 } ) ;
6639
6740 it ( 'goes forwards and restores the original offset' , ( ) => {
68- const mockCodec = getMockCodec ( { innerSize : 2 , totalSize : 10 } ) ;
41+ const mockCodec = getMockCodec ( { innerSize : 2 , size : 10 } ) ;
6942 const codec = offsetCodec ( mockCodec , {
7043 postOffset : ( { preOffset } ) => preOffset ,
7144 preOffset : ( { preOffset } ) => preOffset + 2 ,
@@ -77,7 +50,7 @@ describe('offsetCodec', () => {
7750 } ) ;
7851
7952 it ( 'goes backwards and restores the original offset' , ( ) => {
80- const mockCodec = getMockCodec ( { innerSize : 2 , totalSize : 10 } ) ;
53+ const mockCodec = getMockCodec ( { innerSize : 2 , size : 10 } ) ;
8154 const codec = offsetCodec ( mockCodec , {
8255 postOffset : ( { preOffset } ) => preOffset ,
8356 preOffset : ( { preOffset } ) => preOffset - 3 ,
@@ -91,15 +64,15 @@ describe('offsetCodec', () => {
9164
9265 describe ( 'with absolute offsets' , ( ) => {
9366 it ( 'sets an absolute pre-offset' , ( ) => {
94- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
67+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
9568 const codec = offsetCodec ( mockCodec , { preOffset : ( ) => 6 } ) ;
9669 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 6 ) ;
9770 // Before: 0x000000[pre=3]ffffffff000000
9871 // After: 0x000000000000[pre=6]ffffffff
9972 } ) ;
10073
10174 it ( 'sets an absolute post-offset' , ( ) => {
102- const mockCodec = getMockCodec ( { innerSize : 1 , totalSize : 10 } ) ;
75+ const mockCodec = getMockCodec ( { innerSize : 1 , size : 10 } ) ;
10376 const codec = offsetCodec ( mockCodec , { postOffset : ( ) => 8 } ) ;
10477 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 8 ) ;
10578 // Before: 0x000000[pre=3]ff[post=4]000000000000
@@ -109,15 +82,15 @@ describe('offsetCodec', () => {
10982
11083 describe ( 'with wrapped relative offsets' , ( ) => {
11184 it ( 'uses the provided pre-offset as-is if within the byte range' , ( ) => {
112- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
85+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
11386 const codec = offsetCodec ( mockCodec , { preOffset : ( { preOffset, wrapBytes } ) => wrapBytes ( preOffset + 2 ) } ) ;
11487 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 5 ) ;
11588 // Before: 0x000000[pre=3]ffffffff000000
11689 // After: 0x0000000000[pre=5]ffffffff00
11790 } ) ;
11891
11992 it ( 'uses the provided post-offset as-is if within the byte range' , ( ) => {
120- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
93+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
12194 const codec = offsetCodec ( mockCodec , {
12295 postOffset : ( { postOffset, wrapBytes } ) => wrapBytes ( postOffset + 2 ) ,
12396 } ) ;
@@ -127,7 +100,7 @@ describe('offsetCodec', () => {
127100 } ) ;
128101
129102 it ( 'wraps the pre-offset if it is below the byte range' , ( ) => {
130- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
103+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
131104 const codec = offsetCodec ( mockCodec , {
132105 preOffset : ( { preOffset, wrapBytes } ) => wrapBytes ( preOffset - 12 ) ,
133106 } ) ;
@@ -137,7 +110,7 @@ describe('offsetCodec', () => {
137110 } ) ;
138111
139112 it ( 'wraps the post-offset if it is below the byte range' , ( ) => {
140- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
113+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
141114 const codec = offsetCodec ( mockCodec , {
142115 postOffset : ( { postOffset, wrapBytes } ) => wrapBytes ( postOffset - 12 ) ,
143116 } ) ;
@@ -147,7 +120,7 @@ describe('offsetCodec', () => {
147120 } ) ;
148121
149122 it ( 'wraps the pre-offset if it is above the byte range' , ( ) => {
150- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
123+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
151124 const codec = offsetCodec ( mockCodec , {
152125 preOffset : ( { preOffset, wrapBytes } ) => wrapBytes ( preOffset + 12 ) ,
153126 } ) ;
@@ -157,7 +130,7 @@ describe('offsetCodec', () => {
157130 } ) ;
158131
159132 it ( 'wraps the post-offset if it is above the byte range' , ( ) => {
160- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
133+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
161134 const codec = offsetCodec ( mockCodec , {
162135 postOffset : ( { postOffset, wrapBytes } ) => wrapBytes ( postOffset + 12 ) ,
163136 } ) ;
@@ -167,7 +140,7 @@ describe('offsetCodec', () => {
167140 } ) ;
168141
169142 it ( 'always uses a zero offset if the byte array is empty' , ( ) => {
170- const mockCodec = getMockCodec ( { innerSize : 0 , totalSize : 0 } ) ;
143+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 0 } ) ;
171144 const codec = offsetCodec ( mockCodec , {
172145 postOffset : ( { postOffset, wrapBytes } ) => wrapBytes ( postOffset - 42 ) ,
173146 preOffset : ( { preOffset, wrapBytes } ) => wrapBytes ( preOffset + 42 ) ,
@@ -181,55 +154,55 @@ describe('offsetCodec', () => {
181154
182155 describe ( 'with wrapped absolute offsets' , ( ) => {
183156 it ( 'uses the provided pre-offset as-is if within the byte range' , ( ) => {
184- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
157+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
185158 const codec = offsetCodec ( mockCodec , { preOffset : ( { wrapBytes } ) => wrapBytes ( 5 ) } ) ;
186159 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 5 ) ;
187160 // Before: 0x000000[pre=3]ffffffff000000
188161 // After: 0x0000000000[pre=5]ffffffff00
189162 } ) ;
190163
191164 it ( 'uses the provided post-offset as-is if within the byte range' , ( ) => {
192- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
165+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
193166 const codec = offsetCodec ( mockCodec , { postOffset : ( { wrapBytes } ) => wrapBytes ( 9 ) } ) ;
194167 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 9 ) ;
195168 // Before: 0x000000[pre=3]ffffffff[post=7]000000
196169 // After: 0x000000[pre=3]ffffffff0000[post=9]00
197170 } ) ;
198171
199172 it ( 'wraps the pre-offset if it is below the byte range' , ( ) => {
200- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
173+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
201174 const codec = offsetCodec ( mockCodec , { preOffset : ( { wrapBytes } ) => wrapBytes ( - 19 ) } ) ;
202175 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 1 ) ;
203176 // Before: 0x000000[pre=3]ffffffff000000
204177 // After: 0x00[pre=1]ffffffff0000000000
205178 } ) ;
206179
207180 it ( 'wraps the post-offset if it is below the byte range' , ( ) => {
208- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
181+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
209182 const codec = offsetCodec ( mockCodec , { postOffset : ( { wrapBytes } ) => wrapBytes ( - 15 ) } ) ;
210183 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 5 ) ;
211184 // Before: 0x000000[pre=3]ffffffff[post=7]000000
212185 // After: 0x000000[pre=3]ffff[post=5]ffff000000
213186 } ) ;
214187
215188 it ( 'wraps the pre-offset if it is above the byte range' , ( ) => {
216- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
189+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
217190 const codec = offsetCodec ( mockCodec , { preOffset : ( { wrapBytes } ) => wrapBytes ( 105 ) } ) ;
218191 expectNewPreOffset ( codec , mockCodec , /* preOffset */ 3 , /* newPreOffset */ 5 ) ;
219192 // Before: 0x000000[pre=3]ffffffff000000
220193 // After: 0x0000000000[pre=5]ffffffff00
221194 } ) ;
222195
223196 it ( 'wraps the post-offset if it is above the byte range' , ( ) => {
224- const mockCodec = getMockCodec ( { innerSize : 4 , totalSize : 10 } ) ;
197+ const mockCodec = getMockCodec ( { innerSize : 4 , size : 10 } ) ;
225198 const codec = offsetCodec ( mockCodec , { postOffset : ( { wrapBytes } ) => wrapBytes ( 109 ) } ) ;
226199 expectNewPostOffset ( codec , /* preOffset */ 3 , /* newPostOffset */ 9 ) ;
227200 // Before: 0x000000[pre=3]ffffffff[post=7]000000
228201 // After: 0x000000[pre=3]ffffffff0000[post=9]00
229202 } ) ;
230203
231204 it ( 'always uses a zero offset if the byte array is empty' , ( ) => {
232- const mockCodec = getMockCodec ( { innerSize : 0 , totalSize : 0 } ) ;
205+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 0 } ) ;
233206 const codec = offsetCodec ( mockCodec , {
234207 postOffset : ( { wrapBytes } ) => wrapBytes ( - 42 ) ,
235208 preOffset : ( { wrapBytes } ) => wrapBytes ( 42 ) ,
@@ -243,7 +216,7 @@ describe('offsetCodec', () => {
243216
244217 describe ( 'with offset overflow' , ( ) => {
245218 it ( 'throws an error if the pre-offset is negatif' , ( ) => {
246- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
219+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
247220 const codec = offsetCodec ( mockCodec , { preOffset : ( ) => - 1 } ) ;
248221 expect ( ( ) => codec . encode ( 42 ) ) . toThrow (
249222 new SolanaError ( SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE , {
@@ -262,7 +235,7 @@ describe('offsetCodec', () => {
262235 } ) ;
263236
264237 it ( 'throws an error if the pre-offset is above the byte array length' , ( ) => {
265- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
238+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
266239 const codec = offsetCodec ( mockCodec , { preOffset : ( ) => 11 } ) ;
267240 expect ( ( ) => codec . encode ( 42 ) ) . toThrow (
268241 new SolanaError ( SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE , {
@@ -281,14 +254,14 @@ describe('offsetCodec', () => {
281254 } ) ;
282255
283256 it ( 'does not throw an error if the pre-offset is equal to the byte array length' , ( ) => {
284- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
257+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
285258 const codec = offsetCodec ( mockCodec , { preOffset : ( ) => 10 } ) ;
286259 expect ( ( ) => codec . encode ( 42 ) ) . not . toThrow ( ) ;
287260 expect ( ( ) => codec . decode ( b ( '00' . repeat ( 10 ) ) ) ) . not . toThrow ( ) ;
288261 } ) ;
289262
290263 it ( 'throws an error if the post-offset is negatif' , ( ) => {
291- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
264+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
292265 const codec = offsetCodec ( mockCodec , { postOffset : ( ) => - 1 } ) ;
293266 expect ( ( ) => codec . encode ( 42 ) ) . toThrow (
294267 new SolanaError ( SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE , {
@@ -307,7 +280,7 @@ describe('offsetCodec', () => {
307280 } ) ;
308281
309282 it ( 'throws an error if the post-offset is above the byte array length' , ( ) => {
310- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
283+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
311284 const codec = offsetCodec ( mockCodec , { postOffset : ( ) => 11 } ) ;
312285 expect ( ( ) => codec . encode ( 42 ) ) . toThrow (
313286 new SolanaError ( SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE , {
@@ -326,7 +299,7 @@ describe('offsetCodec', () => {
326299 } ) ;
327300
328301 it ( 'does not throw an error if the post-offset is equal to the byte array length' , ( ) => {
329- const mockCodec = getBaseMockCodec ( { size : 10 } ) ;
302+ const mockCodec = getMockCodec ( { innerSize : 0 , size : 10 } ) ;
330303 const codec = offsetCodec ( mockCodec , { postOffset : ( ) => 10 } ) ;
331304 expect ( ( ) => codec . encode ( 42 ) ) . not . toThrow ( ) ;
332305 expect ( ( ) => codec . decode ( b ( '00' . repeat ( 10 ) ) ) ) . not . toThrow ( ) ;
0 commit comments