From 7eb07b9d2009d83b88735edfa8320555a1944ab8 Mon Sep 17 00:00:00 2001 From: microproofs Date: Tue, 28 Jan 2025 12:54:49 +0700 Subject: [PATCH] Adding tests and optimizing a function --- lib/intention_utils.ak | 83 ++-- lib/intention_utils.test.ak | 777 +++++++++++++++++++++++++++++++++++- 2 files changed, 818 insertions(+), 42 deletions(-) diff --git a/lib/intention_utils.ak b/lib/intention_utils.ak index 3a588f3..35239de 100644 --- a/lib/intention_utils.ak +++ b/lib/intention_utils.ak @@ -24,36 +24,43 @@ use utils.{dataify, must_have_key, ref_control_datum} /// Note this can only be used for output values since /// it can only handle positive values greater than 0 /// if used improperly then == comparisons will fail!!! +/// +/// Also note the first policy for the right must be >= to the last policy in the left +/// This also applies to the asset map as well pub fn fast_combine_output_value( left: Pairs, Data>, right: Pairs, Data>, ) { - when right is { - [] -> left - [Pair(k, _) as p, ..rest] -> - do_insert_right_output_val( - left, - builtin.un_b_data(k), - p, - rest, - fn(left_asset, right_asset) { - expect [Pair(right_key, _) as right_pair, ..ys] = - right_asset |> builtin.un_map_data - + when left is { + [] -> right + _ -> + when right is { + [] -> left + [Pair(k, _) as p, ..rest] -> do_insert_right_output_val( - builtin.un_map_data(left_asset), - builtin.un_b_data(right_key), - right_pair, - ys, - fn(left_int, right_int) { - dataify( - builtin.un_i_data(left_int) + builtin.un_i_data(right_int), + left, + builtin.un_b_data(k), + p, + rest, + fn(left_asset, right_asset) { + expect [Pair(right_key, _) as right_pair, ..ys] = + right_asset |> builtin.un_map_data + + do_insert_right_output_val( + builtin.un_map_data(left_asset), + builtin.un_b_data(right_key), + right_pair, + ys, + fn(left_int, right_int) { + dataify( + builtin.un_i_data(left_int) + builtin.un_i_data(right_int), + ) + }, ) + |> dataify }, ) - |> dataify - }, - ) + } } } @@ -64,28 +71,20 @@ fn do_insert_right_output_val( rest: Pairs, equals_func, ) -> Pairs { - when left is { - [] -> [p, ..rest] - [Pair(left_key, _) as left_pair, ..xs] -> + expect [left_pair, ..xs] = left + when xs is { + [] -> { + let Pair(left_key, _) = left_pair + if builtin.un_b_data(left_key) |> builtin.less_than_bytearray(k) { - [left_pair, ..do_insert_right_output_val(xs, k, p, rest, equals_func)] + [left_pair, p, ..rest] } else { - let next = - when rest is { - [] -> xs - [Pair(right_key, _) as right_pair, ..rest] -> - do_insert_right_output_val( - xs, - builtin.un_b_data(right_key), - right_pair, - rest, - equals_func, - ) - } - - [Pair(left_key, equals_func(left_pair.2nd, p.2nd)), ..next] + [Pair(left_key, equals_func(left_pair.2nd, p.2nd)), ..rest] } + } + + _ -> [left_pair, ..do_insert_right_output_val(xs, k, p, rest, equals_func)] } } @@ -172,6 +171,9 @@ fn value_compare( let leaving_lace, leaving_val <- assets_gone and { input_lace <= output_lace + leaving_lace, + // We use input_val as the anchor to ensure no funny business with outputs or value_leaving + // What I mean is both output_value and value_leaving must be positive and ordered for it to match + // inputs which are guaranteed to come in ordered input_val == fast_combine_natural_values(output_val, leaving_val), } } @@ -382,6 +384,7 @@ pub fn fold_intent_counts( expect [output, ..rest_outputs] = offset_outputs expect validate_out_nonce(user_stake, nonce_address, last_nonce, output) + rest_outputs } diff --git a/lib/intention_utils.test.ak b/lib/intention_utils.test.ak index 93e48eb..11037b4 100644 --- a/lib/intention_utils.test.ak +++ b/lib/intention_utils.test.ak @@ -1,4 +1,4 @@ -use intention_utils.{fast_combine_output_value} +use intention_utils.{fast_combine_natural_values, fast_combine_output_value} use utils.{dataify} test fast_combine_output_value_empty() { @@ -51,7 +51,7 @@ test fast_combine_output_value_same_policy() { fast_combine_output_value(left, right) == expected } -test fast_combine_output_value_multiple() { +test fast_combine_output_value_multiple_same_policy() fail { // Test combining multiple policies and assets let left = [ @@ -113,3 +113,776 @@ test fast_combine_output_value_multiple() { fast_combine_output_value(left, right) == expected } + +test fast_combine_output_value_one_same_policy() { + // Test combining multiple policies and assets + let left = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + ], + ), + ), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + + let right = + [ + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(600)), + Pair(dataify(#"dddd"), dataify(600)), + ], + ), + ), + Pair( + dataify(#"3333"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(600)), + Pair(dataify(#"dddd"), dataify(600)), + ], + ), + ), + ] + + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + ], + ), + ), + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(900)), + Pair(dataify(#"dddd"), dataify(600)), + ], + ), + ), + Pair( + dataify(#"3333"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(600)), + Pair(dataify(#"dddd"), dataify(600)), + ], + ), + ), + ] + + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_insert_middle_policy() fail { + // Tests inserting a policy between two existing policies in the left list + let left = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let right = + [Pair(dataify(#"3333"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let expected = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_right_policies_before_left() fail { + // Tests when right list contains policies that should be ordered before all left policies + let left = + [ + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + let right = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_asset_insert_middle() fail { + // Tests inserting an asset between two existing assets within the same policy + let left = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_asset_before_left() fail { + // Tests adding an asset with a key before existing assets in the same policy + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"cccc"), dataify(300))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_complex_merge() fail { + // Tests complex merging scenario with multiple policies and asset combinations + let left = + [ + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"bbbb"), dataify(200)), + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"eeee"), dataify(500)), + Pair(dataify(#"ffff"), dataify(700)), + ], + ), + ), + ] + let right = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(150)), + Pair(dataify(#"bbbb"), dataify(250)), + ], + ), + ), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"dddd"), dataify(350))])), + ] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(150)), + Pair(dataify(#"bbbb"), dataify(450)), + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"dddd"), dataify(350))])), + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"eeee"), dataify(500)), + Pair(dataify(#"ffff"), dataify(700)), + ], + ), + ), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_valid_policy_continuation() { + // Right starts with same policy as left's last (4444) with asset continuation + let left = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"cccc"), dataify(200))])), + ] + let right = + [ + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(300)), + // Matches left's last asset + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + let expected = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"cccc"), dataify(500)), + // 200 + 300 + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_asset_exact_match() { + // Same policy with right's first asset exactly matching left's last asset + let left = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + ], + ), + ), + ] + let right = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"bbbb"), dataify(300)), + // Exact match of left's last + Pair(dataify(#"cccc"), dataify(400)), + ], + ), + ), + ] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(500)), + // 200 + 300 + Pair(dataify(#"cccc"), dataify(400)), + ], + ), + ), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_right_higher_policy() { + // Right's first policy is higher than left's last policy + let left = + [Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let right = + [Pair(dataify(#"3333"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let expected = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_multiple_right_policies() { + // Multiple right policies all ≥ left's last policy + let left = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let right = + [ + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(200))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(500))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_output_value_same_policy_asset_growth() { + // Same policy with right adding new higher assets after left's last + let left = + [ + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(200)), + ], + ), + ), + ] + let right = + [ + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"eeee"), dataify(300)), + // Higher than left's last asset + Pair(dataify(#"ffff"), dataify(400)), + ], + ), + ), + ] + let expected = + [ + Pair( + dataify(#"4444"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(200)), + Pair(dataify(#"eeee"), dataify(300)), + Pair(dataify(#"ffff"), dataify(400)), + ], + ), + ), + ] + fast_combine_output_value(left, right) == expected +} + +test fast_combine_natural_values_empty_right() { + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let right = [] + fast_combine_natural_values(left, right) == left +} + +test fast_combine_natural_values_empty_left() { + let left = [] + let right = + [Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + fast_combine_natural_values(left, right) == right +} + +test fast_combine_natural_values_interleaved_policies() { + // Right policy should be inserted before left policy + let left = + [Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_same_policy_merge() fail { + // Should sum assets within same policy but values must respect dict ordering + let left = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let right = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(400))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(500))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_complex_insertion() fail { + // Mixed policy insertions and asset merges + let left = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + let right = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(500))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(700))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_asset_insertion() { + // New asset inserted before existing in same policy + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"cccc"), dataify(300))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + // Inserted before + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_multi_asset_merge() { + // Multiple asset merges in same policy + let left = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + let right = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"bbbb"), dataify(200)), + Pair(dataify(#"cccc"), dataify(400)), + ], + ), + ), + ] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + Pair(dataify(#"cccc"), dataify(700)), + ], + ), + ), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_unordered_policies() { + // Right policies should be sorted into correct positions + let left = + [ + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + let right = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + let expected = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_complex_insertion_valid() { + // Right list maintains policy order during insertion + let left = + [ + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + let right = + [ + // Right list must be ordered by policy ID + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(500))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(700))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_same_policy_merge_valid() { + // Right list maintains proper policy order + let left = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let right = + [ + // Right must be ordered by policy ID + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(400))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(500))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"bbbb"), dataify(200))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_mixed_order_insertion() { + // Demonstrates right list can have lower policies than left + let left = + [ + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + let right = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + // Lower than left + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + ] + let expected = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"3333"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + Pair(dataify(#"4444"), dataify([Pair(dataify(#"dddd"), dataify(400))])), + Pair(dataify(#"5555"), dataify([Pair(dataify(#"eeee"), dataify(500))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_same_asset_merge() { + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(200))]))] + let expected = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(300))]))] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_new_asset_insertion() { + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"cccc"), dataify(300))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + // Lower asset ID + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_asset_order_preservation() { + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let right = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))]))] + // Lower asset + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + ], + ), + ), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_cross_policy_assets() { + let left = + [Pair(dataify(#"1111"), dataify([Pair(dataify(#"bbbb"), dataify(200))]))] + let right = + [ + Pair(dataify(#"1111"), dataify([Pair(dataify(#"aaaa"), dataify(100))])), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"bbbb"), dataify(200)), + ], + ), + ), + Pair(dataify(#"2222"), dataify([Pair(dataify(#"cccc"), dataify(300))])), + ] + fast_combine_natural_values(left, right) == expected +} + +test fast_combine_natural_values_complex_asset_merge() { + let left = + [ + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"bbbb"), dataify(200)), + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + ] + let right = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(150)), + // New asset + Pair(dataify(#"bbbb"), dataify(500)), + ], + ), + ), + ] + // Existing asset + let expected = + [ + Pair( + dataify(#"1111"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(100)), + Pair(dataify(#"cccc"), dataify(300)), + ], + ), + ), + Pair( + dataify(#"2222"), + dataify( + [ + Pair(dataify(#"aaaa"), dataify(150)), + Pair(dataify(#"bbbb"), dataify(700)), + Pair(dataify(#"dddd"), dataify(400)), + ], + ), + ), + ] + fast_combine_natural_values(left, right) == expected +}