• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacks-network / stacks-core / 24140301216

08 Apr 2026 02:18PM UTC coverage: 46.817% (-38.9%) from 85.712%
24140301216

Pull #6959

github

279acf
web-flow
Merge efbee1783 into 882e27245
Pull Request #6959: Perf/cache epoch version in ClarityDatabase

66 of 149 new or added lines in 8 files covered. (44.3%)

85999 existing lines in 334 files now uncovered.

102056 of 217989 relevant lines covered (46.82%)

12315981.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/stackslib/src/chainstate/stacks/index/test/node_patch.rs
1
// Copyright (C) 2026 Stacks Open Internet Foundation
2
//
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// This program is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
15

16
//! MARF tests related to [`TrieNodePatch`] node type.
17

18
use std::io::Cursor;
19

20
use super::*;
21
use crate::codec::{Error as codec_error, StacksMessageCodec};
22

23
#[test]
UNCOV
24
fn trie_node_patch_try_from_nodetype_returns_none_when_no_diffs() {
×
UNCOV
25
    let node = TrieNodeType::Node4(TrieNode4::new(&[1]));
×
26

UNCOV
27
    let old_node_ptr = TriePtr::default();
×
UNCOV
28
    let old_node = &node;
×
UNCOV
29
    let new_node = &node;
×
UNCOV
30
    let result = TrieNodePatch::try_from_nodetype(old_node_ptr, old_node, new_node);
×
31

UNCOV
32
    assert!(
×
UNCOV
33
        result.is_none(),
×
34
        "None because the computed patch has no diffs"
35
    );
UNCOV
36
}
×
37

38
#[test]
UNCOV
39
fn trie_node_patch_try_from_patch_returns_none_when_no_diffs() {
×
UNCOV
40
    let old_patch_ptr = TriePtr::new(TrieNodeID::Node4 as u8, 0, 0);
×
UNCOV
41
    let old_patch = TrieNodePatch {
×
UNCOV
42
        ptr: old_patch_ptr.clone(),
×
UNCOV
43
        ptr_diff: vec![],
×
UNCOV
44
    };
×
UNCOV
45
    let new_node = TrieNodeType::Node4(TrieNode4::new(&[1]));
×
UNCOV
46
    let result = TrieNodePatch::try_from_patch(old_patch_ptr, &old_patch, &new_node);
×
47

UNCOV
48
    assert!(
×
UNCOV
49
        result.is_none(),
×
50
        "None because the computed patch has no diffs"
51
    );
UNCOV
52
}
×
53

54
#[test]
UNCOV
55
fn trie_node_patch_serialize_ok() {
×
UNCOV
56
    let patch_node = TrieNodePatch {
×
UNCOV
57
        ptr: TriePtr::new(1, 10, 0),
×
UNCOV
58
        ptr_diff: vec![TriePtr::new(1, 20, 0).clone(); 1],
×
UNCOV
59
    };
×
60

UNCOV
61
    let mut buffer = Cursor::new(Vec::new());
×
UNCOV
62
    patch_node
×
UNCOV
63
        .consensus_serialize(&mut buffer)
×
UNCOV
64
        .expect("serialization should be ok");
×
65

66
    // To fit in 1 byte, diff count is serialized 0-based (where 0 => 1 and 255 => 256)
UNCOV
67
    let diff_count = 0u8;
×
UNCOV
68
    assert_eq!(
×
UNCOV
69
        vec![6, 65, 10, 0, 0, 0, 0, diff_count, 65, 20, 0, 0, 0, 0],
×
UNCOV
70
        buffer.into_inner(),
×
71
    );
UNCOV
72
}
×
73

74
#[test]
UNCOV
75
fn trie_node_patch_serialize_fails_with_ptr_diffs_len_0() {
×
UNCOV
76
    let patch_node = TrieNodePatch {
×
UNCOV
77
        ptr: TriePtr::default(),
×
UNCOV
78
        ptr_diff: vec![],
×
UNCOV
79
    };
×
80

UNCOV
81
    let mut buffer = Cursor::new(Vec::new());
×
UNCOV
82
    let error = patch_node
×
UNCOV
83
        .consensus_serialize(&mut buffer)
×
UNCOV
84
        .expect_err("serialization should fail");
×
85

UNCOV
86
    assert!(
×
UNCOV
87
        matches!(&error, codec_error::SerializeError(msg) if msg.contains("len 0")),
×
88
        "instead got: {error}"
89
    );
UNCOV
90
}
×
91

92
#[test]
UNCOV
93
fn trie_node_patch_serialize_ok_with_ptr_diffs_len_256() {
×
UNCOV
94
    let patch_node = TrieNodePatch {
×
UNCOV
95
        ptr: TriePtr::default(),
×
UNCOV
96
        ptr_diff: vec![TriePtr::default(); 256],
×
UNCOV
97
    };
×
98

UNCOV
99
    let mut buffer = Cursor::new(Vec::new());
×
UNCOV
100
    let result = patch_node.consensus_serialize(&mut buffer);
×
UNCOV
101
    assert!(
×
UNCOV
102
        result.is_ok(),
×
103
        "Got Error: {}",
104
        result.unwrap_err().to_string()
×
105
    );
UNCOV
106
}
×
107

108
#[test]
UNCOV
109
fn trie_node_patch_serialize_fails_with_ptr_diffs_len_257() {
×
UNCOV
110
    let patch_node = TrieNodePatch {
×
UNCOV
111
        ptr: TriePtr::default(),
×
UNCOV
112
        ptr_diff: vec![TriePtr::default(); 257],
×
UNCOV
113
    };
×
114

UNCOV
115
    let mut buffer = Cursor::new(Vec::new());
×
UNCOV
116
    let error = patch_node
×
UNCOV
117
        .consensus_serialize(&mut buffer)
×
UNCOV
118
        .expect_err("serialization should fail");
×
119

UNCOV
120
    assert!(
×
UNCOV
121
        matches!(&error, codec_error::SerializeError(msg) if msg.contains("len 257")),
×
122
        "instead got: {error}"
123
    );
UNCOV
124
}
×
125

126
#[test]
UNCOV
127
fn trie_node_patch_deserialize_ok_with_ptr_diffs_len_1() {
×
128
    // To fit in 1 byte, diff count is serialized 0-based (where 0 => 1 and 255 => 256)
UNCOV
129
    let diff_count = 0u8;
×
UNCOV
130
    let mut buffer = Cursor::new(vec![6, 65, 10, 0, 0, 0, 0, diff_count, 65, 20, 0, 0, 0, 0]);
×
131

UNCOV
132
    let patch_node =
×
UNCOV
133
        TrieNodePatch::consensus_deserialize(&mut buffer).expect("deserialization should be ok");
×
134

UNCOV
135
    let expected = TrieNodePatch {
×
UNCOV
136
        ptr: TriePtr::new(1, 10, 0),
×
UNCOV
137
        ptr_diff: vec![TriePtr::new(1, 20, 0); 1],
×
UNCOV
138
    };
×
UNCOV
139
    assert_eq!(expected, patch_node);
×
UNCOV
140
}
×
141

142
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
143
///
144
/// ## Input
145
/// - `old_ptrs` is empty
146
/// - `new_ptrs` contains a single empty pointer
147
///
148
/// ## Expected behavior
149
/// - No differences are produced
150
#[test]
UNCOV
151
fn trie_node_patch_make_ptr_diff_case1() {
×
UNCOV
152
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
153
    let old_ptrs = [];
×
UNCOV
154
    let new_ptrs = [TriePtr::new(TrieNodeID::Empty as u8, 0x00, 0)];
×
155

UNCOV
156
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
157
    assert_eq!(0, diff.len());
×
UNCOV
158
}
×
159

160
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
161
///
162
/// ## Input
163
/// - `old_ptrs` is empty
164
/// - `new_ptrs` contains:
165
///   - one normal (non-backpointer) node
166
///   - one backpointer node
167
///
168
/// ## Expected behavior
169
/// - Both pointers are reported as differences
170
#[test]
UNCOV
171
fn trie_node_patch_make_ptr_diff_case2() {
×
UNCOV
172
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
173
    let old_ptrs = [];
×
UNCOV
174
    let new_ptrs = [
×
UNCOV
175
        TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0),
×
UNCOV
176
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x01, 0, 1),
×
UNCOV
177
    ];
×
178

UNCOV
179
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
180
    assert_eq!(2, diff.len());
×
UNCOV
181
    assert_eq!(TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0), diff[0]);
×
UNCOV
182
    assert_eq!(
×
UNCOV
183
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x01, 0, 1),
×
UNCOV
184
        diff[1]
×
185
    );
UNCOV
186
}
×
187

188
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
189
///
190
/// ## Input
191
/// - `old_ptr` is **not** a backpointer
192
/// - `new_ptr` **is** a backpointer
193
/// - `new_ptr.back_block` matches `old_node_ptr.back_block`
194
/// - After normalization, `new_ptr` equals `old_ptr`
195
///
196
/// ## Expected behavior
197
/// - No differences are produced
198
#[test]
UNCOV
199
fn trie_node_patch_make_ptr_diff_case3() {
×
UNCOV
200
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
201
    let old_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0)];
×
UNCOV
202
    let new_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 0, 1)];
×
203

UNCOV
204
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
205
    assert_eq!(0, diff.len());
×
UNCOV
206
}
×
207

208
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
209
///
210
/// ## Input
211
/// - `old_ptr` is **not** a backpointer
212
/// - `new_ptr` **is** a backpointer
213
/// - `new_ptr.back_block` matches `old_node_ptr.back_block`
214
/// - After normalization, `new_ptr` does **not** equal `old_ptr`
215
///
216
/// ## Expected behavior
217
/// - The new pointer is reported as a difference
218
#[test]
UNCOV
219
fn trie_node_patch_make_ptr_diff_case4() {
×
UNCOV
220
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
221
    let old_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0)];
×
UNCOV
222
    let new_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 100, 1)];
×
223

UNCOV
224
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
225
    assert_eq!(1, diff.len());
×
UNCOV
226
    assert_eq!(
×
UNCOV
227
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 100, 1),
×
UNCOV
228
        diff[0]
×
229
    );
UNCOV
230
}
×
231

232
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
233
///
234
/// ## Input
235
/// - `old_ptr` is **not** a backpointer
236
/// - `new_ptr` **is** a backpointer
237
/// - `new_ptr.back_block` does **not** match `old_node_ptr.back_block`
238
/// - `new_ptr` does **not** equal `old_ptr`
239
///
240
/// ## Expected behavior
241
/// - The new pointer is reported as a difference
242
#[test]
UNCOV
243
fn trie_node_patch_make_ptr_diff_case5() {
×
UNCOV
244
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
245
    let old_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0)];
×
UNCOV
246
    let new_ptrs = [TriePtr::new_backptr(
×
UNCOV
247
        TrieNodeID::Node4 as u8,
×
UNCOV
248
        0x00,
×
UNCOV
249
        100,
×
UNCOV
250
        100,
×
UNCOV
251
    )];
×
252

UNCOV
253
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
254
    assert_eq!(1, diff.len());
×
UNCOV
255
    assert_eq!(
×
UNCOV
256
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 100, 100),
×
UNCOV
257
        diff[0]
×
258
    );
UNCOV
259
}
×
260

261
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
262
///
263
/// ## Input
264
/// - `old_ptr` **is** a backpointer
265
/// - `new_ptr` **is** a backpointer
266
/// - `new_ptr` equals `old_ptr`
267
///
268
/// ## Expected behavior
269
/// - No differences are produced
270
#[test]
UNCOV
271
fn trie_node_patch_make_ptr_diff_case6() {
×
UNCOV
272
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
273
    let old_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 0x00, 2)];
×
UNCOV
274
    let new_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 0x00, 2)];
×
275

UNCOV
276
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
277
    assert_eq!(0, diff.len());
×
UNCOV
278
}
×
279

280
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
281
///
282
/// ## Input
283
/// - `old_ptr` is **not** a backpointer
284
/// - `new_ptr` is **not** a backpointer
285
/// - `new_ptr` equals `old_ptr`
286
///
287
/// ## Expected behavior
288
/// - The pointer is reported as a difference
289
#[test]
UNCOV
290
fn trie_node_patch_make_ptr_diff_case7() {
×
UNCOV
291
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
292
    let old_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0x00)];
×
UNCOV
293
    let new_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0x00)];
×
294

UNCOV
295
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
296
    assert_eq!(1, diff.len());
×
UNCOV
297
    assert_eq!(TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0x00), diff[0]);
×
UNCOV
298
}
×
299

300
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
301
///
302
/// ## Input
303
/// - `old_ptrs` contains a non-empty pointer
304
/// - `new_ptrs` contains a single empty pointer
305
///
306
/// ## Expected behavior
307
/// - No differences are produced
308
///
309
/// ## Note
310
/// In real scenarios, a Trie node with only empty pointers won't exist,
311
/// as nodes are created only when at least one child is present.
312
/// This test exists purely to exercise `make_ptr_diff` with such an input,
313
/// ensuring all code paths are covered and behavior is well-defined.
314
#[test]
UNCOV
315
fn trie_node_patch_make_ptr_diff_case8() {
×
UNCOV
316
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
317
    let old_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0)];
×
UNCOV
318
    let new_ptrs = [TriePtr::new(TrieNodeID::Empty as u8, 0x00, 0)];
×
319

UNCOV
320
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
321
    assert_eq!(0, diff.len());
×
UNCOV
322
}
×
323

324
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
325
///
326
/// ## Input
327
/// - `old_ptr` **is** a backpointer
328
/// - `new_ptr` is **not** a backpointer
329
/// - Both pointers refer to the same logical node
330
///
331
/// ## Expected behavior
332
/// - The new pointer is reported as a difference
333
#[test]
UNCOV
334
fn trie_node_patch_make_ptr_diff_case9() {
×
UNCOV
335
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
336
    let old_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 42, 2)];
×
UNCOV
337
    let new_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 42)];
×
338

UNCOV
339
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
340
    assert_eq!(1, diff.len());
×
UNCOV
341
    assert_eq!(TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 42), diff[0]);
×
UNCOV
342
}
×
343

344
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
345
///
346
/// ## Input
347
/// - `old_ptr` **is** a backpointer
348
/// - `new_ptr` is **not** a backpointer
349
/// - `new_ptr` does **not** equal `old_ptr`
350
///
351
/// ## Expected behavior
352
/// - The new pointer is reported as a difference
353
#[test]
UNCOV
354
fn trie_node_patch_make_ptr_diff_case10() {
×
UNCOV
355
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
356
    let old_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 10, 2)];
×
UNCOV
357
    let new_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 99)];
×
358

UNCOV
359
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
360
    assert_eq!(1, diff.len());
×
UNCOV
361
    assert_eq!(TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 99), diff[0]);
×
UNCOV
362
}
×
363

364
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
365
///
366
/// ## Input
367
/// - `old_ptr` **is** a backpointer
368
/// - `new_ptr` **is** a backpointer
369
/// - `new_ptr.back_block` matches `old_node_ptr.back_block`
370
/// - `new_ptr` does **not** equal `old_ptr`
371
///
372
/// ## Expected behavior
373
/// - The new pointer is reported as a difference
374
#[test]
UNCOV
375
fn trie_node_patch_make_ptr_diff_case11() {
×
UNCOV
376
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
377
    let old_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 10, 1)];
×
UNCOV
378
    let new_ptrs = [TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 20, 1)];
×
379

UNCOV
380
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
381
    assert_eq!(1, diff.len());
×
UNCOV
382
    assert_eq!(
×
UNCOV
383
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 20, 1),
×
UNCOV
384
        diff[0]
×
385
    );
UNCOV
386
}
×
387

388
/// [`TrieNodePatch::make_ptr_diff`] in the following scenario:
389
///
390
/// ## Input
391
/// - `old_ptrs` contains multiple pointers with the same `chr`
392
/// - The last pointer with that `chr` overwrites the previous one
393
/// - `new_ptr` matches the last `old_ptr`
394
///
395
/// ## Expected behavior
396
/// - No differences are produced
397
///
398
/// ## Note
399
/// In real scenarios, a Trie node has at most one pointer per `chr` value.
400
/// This test exists purely to exercise `make_ptr_diff` with such an input,
401
/// ensuring all code paths are covered and behavior is well-defined.
402
#[test]
UNCOV
403
fn trie_node_patch_make_ptr_diff_case12() {
×
UNCOV
404
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
UNCOV
405
    let old_ptrs = [
×
UNCOV
406
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 10),
×
UNCOV
407
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 20),
×
UNCOV
408
    ];
×
UNCOV
409
    let new_ptrs = [TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 20)];
×
410

UNCOV
411
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
UNCOV
412
    assert_eq!(1, diff.len());
×
UNCOV
413
    assert_eq!(TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 20), diff[0]);
×
UNCOV
414
}
×
415

416
/// Aggregated test of [`TrieNodePatch::make_ptr_diff`] combining all singular scenarios.
417
///
418
/// ## Input
419
/// - `old_ptrs` contains a mix of:
420
///   - non-backpointers
421
///   - backpointers
422
///   - duplicate `chr` entries (last one wins)
423
/// - `new_ptrs` contains a mix of:
424
///   - empty pointers
425
///   - normalized backpointers
426
///   - mismatching backpointers
427
///   - matching and non-matching non-backpointers
428
///
429
/// ## Expected behavior
430
/// - Only pointers that semantically differ from their corresponding old pointers
431
///   are included in the diff
432
#[test]
UNCOV
433
fn trie_node_patch_make_ptr_diff_all_in_one() {
×
UNCOV
434
    let old_node_ptr = TriePtr::new_backptr(TrieNodeID::Patch as u8, 0x00, 0, 1);
×
435

UNCOV
436
    let old_ptrs = [
×
UNCOV
437
        // Case 3 / 4 / 5
×
UNCOV
438
        TriePtr::new(TrieNodeID::Node4 as u8, 0x00, 0),
×
UNCOV
439
        // Case 6 / 9 / 10
×
UNCOV
440
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x01, 10, 2),
×
UNCOV
441
        // Case 7
×
UNCOV
442
        TriePtr::new(TrieNodeID::Node4 as u8, 0x02, 20),
×
UNCOV
443
        // Case 12: duplicate chr, first (overwritten)
×
UNCOV
444
        TriePtr::new(TrieNodeID::Node4 as u8, 0x03, 30),
×
UNCOV
445
        // Case 12: duplicate chr, second (effective)
×
UNCOV
446
        TriePtr::new(TrieNodeID::Node4 as u8, 0x03, 40),
×
UNCOV
447
    ];
×
448

UNCOV
449
    let new_ptrs = [
×
UNCOV
450
        // Case 1 / 8: empty pointer (ignored)
×
UNCOV
451
        TriePtr::new(TrieNodeID::Empty as u8, 0xFF, 0),
×
UNCOV
452
        // Case 3: normalized backptr equals old_ptr (no diff)
×
UNCOV
453
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 0, 1),
×
UNCOV
454
        // Case 4: normalized backptr != old_ptr (diff)
×
UNCOV
455
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 100, 1),
×
UNCOV
456
        // Case 9: old backptr, new non-backptr, same target (diff)
×
UNCOV
457
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 10),
×
UNCOV
458
        // Case 10: old backptr, new non-backptr, different target (diff)
×
UNCOV
459
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 99),
×
UNCOV
460
        // Case 7: both non-backptr equal (diff)
×
UNCOV
461
        TriePtr::new(TrieNodeID::Node4 as u8, 0x02, 20),
×
UNCOV
462
        // Case 11: both backptr, unequal, same back_block (diff)
×
UNCOV
463
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x02, 200, 1),
×
UNCOV
464
        // Case 12: duplicate chr, matches last old_ptr (diff)
×
UNCOV
465
        TriePtr::new(TrieNodeID::Node4 as u8, 0x03, 40),
×
UNCOV
466
        // Case 2: new_ptr with no corresponding old_ptr (diff)
×
UNCOV
467
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x04, 0, 1),
×
UNCOV
468
    ];
×
469

UNCOV
470
    let diff = TrieNodePatch::make_ptr_diff_for_test(&old_node_ptr, &old_ptrs, &new_ptrs);
×
471

UNCOV
472
    let expected = vec![
×
473
        // Case 4
UNCOV
474
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x00, 100, 1),
×
475
        // Case 9
UNCOV
476
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 10),
×
477
        // Case 10
UNCOV
478
        TriePtr::new(TrieNodeID::Node4 as u8, 0x01, 99),
×
479
        // Case 7
UNCOV
480
        TriePtr::new(TrieNodeID::Node4 as u8, 0x02, 20),
×
481
        // Case 11
UNCOV
482
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x02, 200, 1),
×
483
        // Case 12
UNCOV
484
        TriePtr::new(TrieNodeID::Node4 as u8, 0x03, 40),
×
485
        // Case 2
UNCOV
486
        TriePtr::new_backptr(TrieNodeID::Node4 as u8, 0x04, 0, 1),
×
487
    ];
488

UNCOV
489
    assert_eq!(diff, expected);
×
UNCOV
490
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc