test_mathutils.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. from pytest import raises
  2. from boltons.mathutils import clamp, ceil, floor, Bits
  3. import math
  4. INF, NAN = float('inf'), float('nan')
  5. OPTIONS = [1618, 1378, 166, 1521, 2347, 2016, 879, 2123,
  6. 269.3, 1230, 66, 425.2, 250, 2399, 2314, 439,
  7. 247, 208, 379, 1861]
  8. OPTIONS_SORTED = sorted(OPTIONS)
  9. OUT_OF_RANGE_LOWER = 60
  10. OUT_OF_RANGE_UPPER = 2500
  11. VALID_LOWER = 247
  12. VALID_UPPER = 2314
  13. VALID_BETWEEN = 248.5
  14. def test_clamp_examples():
  15. """some examples for clamp()"""
  16. assert 0 == clamp(0, 0, 1) == clamp(-1, 0, 1)
  17. assert 0 == clamp(-1, lower=0)
  18. assert 1 == clamp(1, 0, 1) == clamp(5, 0, 1)
  19. assert 1 == clamp(5, upper=1)
  20. assert 0.5 == clamp(7, upper=0.5)
  21. assert 1 == clamp(7.7, upper=1)
  22. def test_clamp_transparent():
  23. """clamp(x) should equal x because both limits are omitted"""
  24. assert clamp(0) == 0
  25. assert clamp(1) == 1
  26. assert clamp(10**100) == 10**100
  27. assert clamp(INF) == INF
  28. assert clamp(-INF) == -INF
  29. assert math.isnan(clamp(NAN))
  30. def test_ceil_basic():
  31. assert ceil(VALID_LOWER, OPTIONS) == VALID_LOWER
  32. assert ceil(VALID_UPPER, OPTIONS) == VALID_UPPER
  33. assert ceil(VALID_BETWEEN, OPTIONS) == 250
  34. def test_ceil_sorted():
  35. assert ceil(VALID_LOWER, OPTIONS) == ceil(VALID_LOWER, OPTIONS_SORTED)
  36. assert ceil(VALID_UPPER, OPTIONS) == ceil(VALID_UPPER, OPTIONS_SORTED)
  37. assert ceil(VALID_BETWEEN, OPTIONS) == ceil(VALID_BETWEEN, OPTIONS_SORTED)
  38. def test_ceil_oor_lower():
  39. assert min(OPTIONS) == ceil(OUT_OF_RANGE_LOWER, OPTIONS)
  40. def test_ceil_oor_upper():
  41. with raises(ValueError):
  42. ceil(OUT_OF_RANGE_UPPER, OPTIONS)
  43. def test_floor_basic():
  44. assert floor(VALID_LOWER, OPTIONS) == VALID_LOWER
  45. assert floor(VALID_UPPER, OPTIONS) == VALID_UPPER
  46. assert floor(VALID_LOWER, OPTIONS) == 247
  47. def test_floor_sorted():
  48. assert floor(VALID_LOWER, OPTIONS) == floor(VALID_LOWER, OPTIONS_SORTED)
  49. assert floor(VALID_UPPER, OPTIONS) == floor(VALID_UPPER, OPTIONS_SORTED)
  50. assert floor(VALID_BETWEEN, OPTIONS) == floor(VALID_BETWEEN, OPTIONS_SORTED)
  51. def test_floor_oor_upper():
  52. assert max(OPTIONS) == floor(OUT_OF_RANGE_UPPER, OPTIONS)
  53. def test_floor_oor_lower():
  54. with raises(ValueError):
  55. floor(OUT_OF_RANGE_LOWER, OPTIONS)
  56. def test_bits():
  57. def chk(a, b):
  58. assert a == b, a
  59. chk(Bits('10')[:1], Bits('1'))
  60. chk(Bits('10')[1:], Bits('0'))
  61. chk(Bits('10')[0], True)
  62. chk(Bits('10')[1], False)
  63. chk(Bits('0000100')[4], True)
  64. chk(Bits('10').as_list(), [True, False])
  65. chk(Bits('10').as_int(), 2)
  66. chk(Bits('10').as_bin(), '10')
  67. chk(Bits('1111').as_hex(), '0F')
  68. chk(Bits('10'), Bits([True, False]))
  69. chk(Bits('10'), Bits(2))
  70. chk(Bits('01') | Bits('10'), Bits('11'))
  71. chk(Bits('01') & Bits('10'), Bits('00'))
  72. chk(Bits('11') >> 1, Bits('1'))
  73. chk(Bits('1') << 1, Bits('10'))
  74. assert Bits('0') != Bits('00')
  75. # test roundtrip as_/from_hex
  76. chk(Bits.from_hex(Bits('10101010').as_hex()),
  77. Bits('10101010'))
  78. # test roundtrip as_/from_bytes
  79. chk(
  80. Bits.from_bytes(Bits('10101010').as_bytes()),
  81. Bits('10101010'))
  82. # pile of roundtripping
  83. chk(Bits.from_int(
  84. Bits.from_bin(
  85. Bits.from_list(
  86. Bits('101').as_list()
  87. ).as_bin()
  88. ).as_int()
  89. ),
  90. Bits('101'))