@@ -1120,6 +1120,10 @@ def test_compare_equal_and_numeric_parsers():
11201120 assert calc ._parse_numeric_exact ("0x10" ) == 16
11211121 assert calc ._parse_numeric_exact ("10" ) == 10
11221122 assert calc ._parse_numeric_exact ("1.5" ) == Decimal ("1.5" )
1123+ assert calc ._parse_numeric_exact ("1e6" ) == Decimal ("1e6" )
1124+ assert calc ._parse_numeric_exact ("1e8" ) == Decimal ("1e8" )
1125+ assert calc ._parse_numeric_exact ("2.5e3" ) == Decimal ("2.5e3" )
1126+ assert calc ._parse_numeric_exact ("deadbeef" ) == 0xDEADBEEF
11231127 with pytest .raises (ValueError ):
11241128 calc ._parse_numeric_exact ("" )
11251129
@@ -1132,16 +1136,58 @@ def test_compare_equal_and_numeric_parsers():
11321136def test_compare_numbers_and_math_operations ():
11331137 assert calc .compare_numbers (["10" , "<" , "20" ]) == "true"
11341138 assert calc .compare_numbers (["10" , ">" , "20" ]) == "false"
1139+ assert calc .compare_numbers (["1e8" , ">" , "1000000" ]) == "true"
1140+ assert calc .compare_numbers (["1e6" , "<=" , "1000000" ]) == "true"
11351141 with pytest .raises (ValueError ):
11361142 calc .compare_numbers (["10" , "!=" , "20" ])
11371143
11381144 assert calc .math_operation (["10" , "+" , "5" ]) == "15"
11391145 assert calc .math_operation (["10" , "-" , "5" ]) == "5"
11401146 assert calc .math_operation (["10" , "*" , "5" ]) == "50"
11411147 assert calc .math_operation (["3" , "/" , "2" ]) == "1.5"
1148+ assert calc .math_operation (["1e8" , "+" , "1" ]) == "100000001"
1149+ assert calc .math_operation (["1e6" , "*" , "2" ]) == "2000000"
11421150 with pytest .raises (ValueError ):
11431151 calc .math_operation (["1" , "/" , "0" ])
11441152
1153+ @pytest .mark .parametrize ("raw" , [
1154+ "1e" , "e10" , "1E" , "E10" , "1e1e" ,
1155+ "0b10" , "0B10" ,
1156+ # special Decimal values that must be rejected
1157+ "NaN" , "nan" , "Infinity" , "-Infinity" , "sNaN" ,
1158+ # underscore-separated numeric literals
1159+ "_10" , "1__0" , "1_" ,
1160+ # trailing dots – looks like a decimal but the fractional part is absent
1161+ "123." , "0." ,
1162+ # malformed scientific notation: trailing dot before the exponent
1163+ "1.e6" , "0.e3" ,
1164+ ])
1165+ def test_parse_numeric_exact_rejects_malformed (raw ):
1166+ with pytest .raises (ValueError ):
1167+ calc ._parse_numeric_exact (raw )
1168+
1169+
1170+ @pytest .mark .parametrize ("raw,expected" , [
1171+ ("fe1" , 0xfe1 ),
1172+ ("a1e4" , 0xa1e4 ),
1173+ ("b3e2f" , 0xb3e2f ),
1174+ (".5e3" , Decimal (".5e3" )),
1175+ ("+1e6" , Decimal ("+1e6" )),
1176+ ("-0.5" , Decimal ("-0.5" )),
1177+ ("0e0" , Decimal ("0e0" )),
1178+ ("0X1F" , 0x1F ),
1179+ ("0xDEAD" , 0xDEAD ),
1180+ ])
1181+ def test_parse_numeric_exact_accepts_valid (raw , expected ):
1182+ assert calc ._parse_numeric_exact (raw ) == expected
1183+
1184+
1185+ def test_parse_numeric_exact_malformed_propagates_to_api ():
1186+ with pytest .raises (ValueError ):
1187+ calc .compare_numbers (["1e" , "<" , "31" ])
1188+ with pytest .raises (ValueError ):
1189+ calc .math_operation (["e10" , "+" , "1" ])
1190+
11451191
11461192def test_hash160_and_sha256_address_helpers ():
11471193 p2pkh = calc .hash160_to_p2pkh_address (GENESIS_HASH160 )
0 commit comments