|
1 | 1 | #[feature("byte-span")] |
2 | | -use crate::byte_array::{ByteSpanTrait, ToByteSpanTrait}; |
3 | | -use crate::num::traits::Bounded; |
4 | | -use crate::test::test_utils::{assert_eq, assert_ne}; |
| 2 | +use core::byte_array::{ByteSpanTrait, ToByteSpanTrait}; |
| 3 | +use core::num::traits::Bounded; |
| 4 | +use core::test::test_utils::{assert_eq, assert_ne}; |
5 | 5 |
|
6 | 6 | #[test] |
7 | 7 | fn test_append_byte() { |
@@ -843,10 +843,221 @@ fn test_span_at_overflows() { |
843 | 843 | // Test overflow protection with large indices. |
844 | 844 | let ba: ByteArray = "test"; |
845 | 845 | let span = ba.span(); |
846 | | - |
847 | 846 | assert_eq!(span.get(Bounded::<usize>::MAX), None); |
848 | 847 |
|
849 | 848 | let sliced = ba.span().get(1..3).unwrap(); |
850 | 849 | assert_eq!(sliced.get(Bounded::<usize>::MAX - 1), None); |
851 | 850 | assert_eq!(sliced.get(Bounded::<usize>::MAX), None); |
852 | 851 | } |
| 852 | + |
| 853 | +#[test] |
| 854 | +fn test_byte_span_simple() { |
| 855 | + let empty: ByteArray = ""; |
| 856 | + let mut iter = empty.span().into_iter(); |
| 857 | + assert_eq!(iter.next(), None); |
| 858 | + |
| 859 | + let ba: ByteArray = "A"; |
| 860 | + let mut iter = ba.span().into_iter(); |
| 861 | + assert_eq!(iter.next(), Some('A')); |
| 862 | + assert_eq!(iter.next(), None); |
| 863 | + |
| 864 | + let ba: ByteArray = "ABC"; |
| 865 | + let mut iter = ba.span().into_iter(); |
| 866 | + assert_eq!(iter.next(), Some('A')); |
| 867 | + assert_eq!(iter.next(), Some('B')); |
| 868 | + assert_eq!(iter.next(), Some('C')); |
| 869 | + assert_eq!(iter.next(), None); |
| 870 | + assert_eq!(iter.next(), None, "Idempotent empty"); |
| 871 | +} |
| 872 | + |
| 873 | +#[test] |
| 874 | +fn test_byte_span_iterator_word_boundaries() { |
| 875 | + // Test 30, 31, 32 bytes (1 word boundary). |
| 876 | + let ba_30: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcd"; |
| 877 | + let mut iter = ba_30.span().into_iter(); |
| 878 | + for _ in 0_usize..29 { |
| 879 | + let _ = iter.next(); |
| 880 | + } |
| 881 | + assert_eq!(iter.next(), Some('d'), "30 bytes - last byte"); |
| 882 | + assert_eq!(iter.next(), None); |
| 883 | + |
| 884 | + let ba_31: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"; |
| 885 | + let mut iter = ba_31.span().into_iter(); |
| 886 | + assert_eq!(iter.next(), Some('A')); |
| 887 | + for _ in 1_usize..30 { |
| 888 | + let _ = iter.next(); |
| 889 | + } |
| 890 | + assert_eq!(iter.next(), Some('e'), "31 bytes - last byte"); |
| 891 | + assert_eq!(iter.next(), None); |
| 892 | + |
| 893 | + let ba_32: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"; |
| 894 | + let mut iter = ba_32.span().into_iter(); |
| 895 | + for _ in 0_usize..30 { |
| 896 | + let _ = iter.next(); |
| 897 | + } |
| 898 | + assert_eq!(iter.next(), Some('e'), "32 bytes - byte 30"); |
| 899 | + assert_eq!(iter.next(), Some('f'), "32 bytes - byte 31"); |
| 900 | + assert_eq!(iter.next(), None); |
| 901 | + |
| 902 | + // Test 62, 63, 64 bytes (2 word boundaries). |
| 903 | + let ba_62: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; |
| 904 | + let mut iter = ba_62.span().into_iter(); |
| 905 | + for _ in 0_usize..61 { |
| 906 | + let _ = iter.next(); |
| 907 | + } |
| 908 | + assert_eq!(iter.next(), Some('9'), "62 bytes - last byte"); |
| 909 | + assert_eq!(iter.next(), None); |
| 910 | + |
| 911 | + let ba_63: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!"; |
| 912 | + let mut iter = ba_63.span().into_iter(); |
| 913 | + for _ in 0_usize..62 { |
| 914 | + let _ = iter.next(); |
| 915 | + } |
| 916 | + assert_eq!(iter.next(), Some('!'), "63 bytes - last byte"); |
| 917 | + assert_eq!(iter.next(), None); |
| 918 | + |
| 919 | + let ba_64: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@"; |
| 920 | + let mut iter = ba_64.span().into_iter(); |
| 921 | + for _ in 0_usize..62 { |
| 922 | + let _ = iter.next(); |
| 923 | + } |
| 924 | + assert_eq!(iter.next(), Some('!'), "64 bytes - byte 62"); |
| 925 | + assert_eq!(iter.next(), Some('@'), "64 bytes - byte 63"); |
| 926 | + assert_eq!(iter.next(), None); |
| 927 | +} |
| 928 | + |
| 929 | +#[test] |
| 930 | +fn test_byte_span_iterator_multiple_words() { |
| 931 | + // Test with 3+ words to verify iteration works across multiple word boundaries. |
| 932 | + // 92 bytes: 31 + 31 + 30. |
| 933 | + let ba_92: ByteArray = |
| 934 | + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;':,.<>?/~`"; |
| 935 | + let span = ba_92.span(); |
| 936 | + let mut iter = span.into_iter(); |
| 937 | + // Verify we can iterate through all bytes. |
| 938 | + let mut count = 0; |
| 939 | + while let Some(_) = iter.next() { |
| 940 | + count += 1; |
| 941 | + } |
| 942 | + assert_eq!(count, 92, "should iterate all 92 bytes"); |
| 943 | + |
| 944 | + // Verify correctness at specific positions. |
| 945 | + let mut iter = span.into_iter(); |
| 946 | + assert_eq!(iter.next(), Some('A')); |
| 947 | + |
| 948 | + // Skip to last byte. |
| 949 | + for _ in 1_usize..91 { |
| 950 | + let _ = iter.next(); |
| 951 | + } |
| 952 | + assert_eq!(iter.next(), Some('`')); |
| 953 | + assert_eq!(iter.next(), None); |
| 954 | +} |
| 955 | + |
| 956 | +#[test] |
| 957 | +fn test_byte_span_iterator_for_loop_collect() { |
| 958 | + let small_ba: ByteArray = "Hello"; |
| 959 | + let span = small_ba.span(); |
| 960 | + |
| 961 | + let mut collected = Default::default(); |
| 962 | + let mut count = 0; |
| 963 | + for byte in span { |
| 964 | + collected.append_byte(byte); |
| 965 | + count += 1; |
| 966 | + } |
| 967 | + assert_eq!(collected, small_ba); |
| 968 | + assert_eq!(count, 5); |
| 969 | + assert_eq!(span.into_iter().collect(), small_ba); |
| 970 | + |
| 971 | + // Test with 2 words. |
| 972 | + let ba_40: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn"; |
| 973 | + collected = Default::default(); |
| 974 | + count = 0; |
| 975 | + for byte in ba_40.span() { |
| 976 | + collected.append_byte(byte); |
| 977 | + count += 1; |
| 978 | + } |
| 979 | + assert_eq!(collected, ba_40); |
| 980 | + assert_eq!(count, 40); |
| 981 | + assert_eq!(ba_40.span().into_iter().collect(), ba_40); |
| 982 | + |
| 983 | + // Test with 3 words. |
| 984 | + let ba_70: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"; |
| 985 | + collected = Default::default(); |
| 986 | + count = 0; |
| 987 | + for byte in ba_70.span() { |
| 988 | + collected.append_byte(byte); |
| 989 | + count += 1; |
| 990 | + } |
| 991 | + assert_eq!(collected, ba_70); |
| 992 | + assert_eq!(count, 70); |
| 993 | + assert_eq!(ba_70.span().into_iter().collect(), ba_70); |
| 994 | +} |
| 995 | + |
| 996 | +#[test] |
| 997 | +fn test_byte_span_iterator_slices() { |
| 998 | + // Slice within remainder word (< 31 bytes). |
| 999 | + let ba_13: ByteArray = "Hello Shmello"; |
| 1000 | + let span = ba_13.span().get(2..7).unwrap(); |
| 1001 | + |
| 1002 | + let mut iter = span.into_iter(); |
| 1003 | + assert_eq!(iter.next(), Some('l')); |
| 1004 | + assert_eq!(iter.next(), Some('l')); |
| 1005 | + assert_eq!(iter.next(), Some('o')); |
| 1006 | + assert_eq!(iter.next(), Some(' ')); |
| 1007 | + assert_eq!(iter.next(), Some('S')); |
| 1008 | + assert_eq!(iter.next(), None); |
| 1009 | + |
| 1010 | + // Iterate slice across 2 words (1 data + remainder). |
| 1011 | + let ba_33: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"; |
| 1012 | + let span = ba_33.span().get(27..32).unwrap(); |
| 1013 | + |
| 1014 | + let mut iter = span.into_iter(); |
| 1015 | + assert_eq!(iter.next(), Some('b')); |
| 1016 | + assert_eq!(iter.next(), Some('c')); |
| 1017 | + assert_eq!(iter.next(), Some('d')); |
| 1018 | + assert_eq!(iter.next(), Some('e')); |
| 1019 | + assert_eq!(iter.next(), Some('f')); |
| 1020 | + assert_eq!(iter.next(), None); |
| 1021 | + |
| 1022 | + // Iterate slice across 3 words. |
| 1023 | + let ba_66: ByteArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$"; |
| 1024 | + let span = ba_66.span().get(29..64).unwrap(); |
| 1025 | + |
| 1026 | + let mut iter = span.into_iter(); |
| 1027 | + assert_eq!(iter.next(), Some('d'), "First word"); |
| 1028 | + assert_eq!(iter.next(), Some('e')); |
| 1029 | + assert_eq!(iter.next(), Some('f'), "Second word"); |
| 1030 | + assert_eq!(iter.next(), Some('g')); |
| 1031 | + assert_eq!(iter.next(), Some('h')); |
| 1032 | + assert_eq!(iter.next(), Some('i')); |
| 1033 | + assert_eq!(iter.next(), Some('j')); |
| 1034 | + assert_eq!(iter.next(), Some('k')); |
| 1035 | + assert_eq!(iter.next(), Some('l')); |
| 1036 | + assert_eq!(iter.next(), Some('m')); |
| 1037 | + assert_eq!(iter.next(), Some('n')); |
| 1038 | + assert_eq!(iter.next(), Some('o')); |
| 1039 | + assert_eq!(iter.next(), Some('p')); |
| 1040 | + assert_eq!(iter.next(), Some('q')); |
| 1041 | + assert_eq!(iter.next(), Some('r')); |
| 1042 | + assert_eq!(iter.next(), Some('s')); |
| 1043 | + assert_eq!(iter.next(), Some('t')); |
| 1044 | + assert_eq!(iter.next(), Some('u')); |
| 1045 | + assert_eq!(iter.next(), Some('v')); |
| 1046 | + assert_eq!(iter.next(), Some('w')); |
| 1047 | + assert_eq!(iter.next(), Some('x')); |
| 1048 | + assert_eq!(iter.next(), Some('y')); |
| 1049 | + assert_eq!(iter.next(), Some('z')); |
| 1050 | + assert_eq!(iter.next(), Some('0')); |
| 1051 | + assert_eq!(iter.next(), Some('1')); |
| 1052 | + assert_eq!(iter.next(), Some('2')); |
| 1053 | + assert_eq!(iter.next(), Some('3')); |
| 1054 | + assert_eq!(iter.next(), Some('4')); |
| 1055 | + assert_eq!(iter.next(), Some('5')); |
| 1056 | + assert_eq!(iter.next(), Some('6')); |
| 1057 | + assert_eq!(iter.next(), Some('7')); |
| 1058 | + assert_eq!(iter.next(), Some('8')); |
| 1059 | + assert_eq!(iter.next(), Some('9')); |
| 1060 | + assert_eq!(iter.next(), Some('!'), "Remainder word"); |
| 1061 | + assert_eq!(iter.next(), Some('@')); |
| 1062 | + assert_eq!(iter.next(), None); |
| 1063 | +} |
0 commit comments