1. import unittest, random
  2. import triangulo
  3.  
  4. class TrianguloGoodInput(unittest.TestCase):
  5.     three_sides = [
  6.         ({"A":100, "B":100, "C":100}, {"A":100, "B":100, "C":100, "a":60, "b":60, "c":60}),
  7.         ({"A":100, "B":70.71067811865, "C":70.71067811865}, {"A":100, "B":70.71067811865, "C":70.71067811865, "a":90, "b":45, "c":45}),
  8.         ({'A': 100, 'B': 173.20508075688775, 'C': 200}, {'a': 30, 'A': 100, 'c': 90.0, 'b': 60, 'B': 173.20508075688775, 'C': 200.00000000000003}),
  9.     ]
  10.  
  11.     two_sides_one_angle_overlapping = [
  12.         ({"A":100, "B":100, "b":60}, {"A":100, "B":100, "C":100, "a":60, "b":60, "c":60}),
  13.         ({"A":100, "C":70.71067811865, "c":45}, {"A":100, "B":70.71067811865, "C":70.71067811865, "a":90, "b":45, "c":45}),
  14.         ({'a': 30, 'A': 100, 'C': 200}, {'a': 30, 'A': 100, 'c': 89.999999146226358, 'b': 60.000000853773642, 'B': 173.20508224700384, 'C': 200}),
  15.     ]
  16.  
  17.     two_sides_one_angle_non_overlapping = [
  18.         ({"A":100, "B":100, "c":60}, {"A":100, "B":100, "C":100, "a":60, "b":60, "c":60}),
  19.         ({"A":100, "C":70.71067811865, "b":45}, {"A":100, "B":70.71067811865, "C":70.71067811865, "a":90, "b":45, "c":45}),
  20.         ({'A': 100, 'b': 60, 'C': 200}, {'a': 30, 'A': 100, 'c': 90.0, 'b': 60, 'B': 173.20508075688775, 'C': 200}),
  21.     ]
  22.  
  23.     one_side_two_angles_overlapping = [
  24.         ({"A":100, "a":60, "c":60}, {"A":100, "B":100, "C":100, "a":60, "b":60, "c":60}),
  25.         ({"A":100, "a":90, "b":45}, {"A":100, "B":70.71067811865, "C":70.71067811865, "a":90, "b":45, "c":45}),
  26.         ({'A': 100, 'c': 90.0, 'C': 200}, {'a': 30, 'A': 100, 'c': 90.0, 'b': 60, 'B': 173.20508075688775, 'C': 200}),
  27.     ]
  28.  
  29.     one_side_two_angles_non_overlapping = [
  30.         ({"A":100, "b":60, "c":60}, {"A":100, "B":100, "C":100, "a":60, "b":60, "c":60}),
  31.         ({"A":100, "c":45, "b":45}, {"A":100, "B":70.71067811865, "C":70.71067811865, "a":90, "b":45, "c":45}),
  32.     ]
  33.  
  34.     def test_3_sidesgiven(self):
  35.         for input, expected in self.three_sides:
  36.             for element, value in triangulo.get_triangle_values(**input).iteritems():
  37.                 self.assertAlmostEqual(value, expected[element])
  38.  
  39.     def test_2_sides_1_angle_non_overlapping(self):
  40.         for input, expected in self.two_sides_one_angle_non_overlapping:
  41.             for element, value in triangulo.get_triangle_values(**input).iteritems():
  42.                 self.assertAlmostEqual(value, expected[element])
  43.  
  44.     def test_2_sides_1_angle_overlapping(self):
  45.         for input, expected in self.two_sides_one_angle_overlapping:
  46.             for element, value in triangulo.get_triangle_values(**input).iteritems():
  47.                 self.assertAlmostEqual(value, expected[element])
  48.  
  49.     def test_1_side_2_angles_non_overlapping(self):
  50.         for input, expected in self.one_side_two_angles_non_overlapping:
  51.             for element, value in triangulo.get_triangle_values(**input).iteritems():
  52.                 self.assertAlmostEqual(value, expected[element])
  53.  
  54.     def test_1_side_2_angles_overlapping(self):
  55.         for input, expected in self.one_side_two_angles_overlapping:
  56.             for element, value in triangulo.get_triangle_values(**input).iteritems():
  57.                 self.assertAlmostEqual(value, expected[element])
  58.  
  59.     def test_angles(self):
  60.         """
  61.        No matter the input sides, the sum of the angles must be 180.
  62.        """
  63.         for i in range(1):
  64.             self.assertAlmostEqual(
  65.                 sum(
  66.                     triangulo.get_known_angles(
  67.                         **triangulo.get_triangle_values(
  68.                             A=random.Random().uniform(1,5),
  69.                             B=random.Random().uniform(1,5),
  70.                             c=random.Random().uniform(0,180))
  71.                     ).itervalues()),
  72.                     180)
  73.  
  74. class TrianguloBadInput(unittest.TestCase):
  75.     bad_sides = [
  76.         {"A":181, "B":90, "C":90},
  77.         {"A":90, "B":181, "C":90},
  78.         {"A":90, "B":90, "C":181},
  79.         {"A":20, "B":120, "C":90},
  80.         {"A":90, "B":20, "C":10},
  81.         {"A":0, "B":0, "C":1},
  82.     ]
  83.  
  84.     bad_angles = [
  85.         {"a":90, "b":90, "c":90, "B":90, "C":90},
  86.         {"A":90, "B":181, "C":90, "a":90, "b":90, "a":90},
  87.     ]
  88.  
  89.     few_inputs = [
  90.         {"A":100, "B":100},
  91.         {"A":100, "C":100},
  92.         {"B":100, "C":100},
  93.         {"A":100, "b":100},
  94.         {"A":100, "c":100},
  95.         {"a":100, "C":100},
  96.         {"a":100, "B":100},
  97.     ]
  98.  
  99.     def test_bad_sides(self):
  100.         """
  101.        len([i for i in sides if i <= sum(sides)/2]) == 0
  102.        """
  103.         for input in self.bad_sides:
  104.             self.failUnlessRaises(triangulo.InconsistentDataError, triangulo.get_triangle_values, **input)
  105.  
  106.     def test_bad_angles(self):
  107.         """
  108.        len([i for i in sides if i <= sum(sides)/2]) == 0
  109.        """
  110.         for input in self.bad_sides:
  111.             self.failUnlessRaises(triangulo.InconsistentDataError, triangulo.get_triangle_values, **input)
  112.  
  113.     def test_too_few_inputs(self):
  114.         """
  115.        
  116.        """
  117.         for input in self.few_inputs:
  118.             self.failUnlessRaises(triangulo.InsufficientDataError, triangulo.get_triangle_values, **input)
  119.  
  120.  
  121. class KnownSides(unittest.TestCase):
  122.     good_input = [ #100% coverage might be overkill :)
  123.         ({"A":100, "B":100, "C":100, "a":100, "b":100, "c":100}, {"A":100, "B":100, "C":100}),
  124.         ({"A":100, "B":100, "C":100, "b":100, "c":100}, {"A":100, "B":100, "C":100}),
  125.         ({"A":100, "B":100, "C":100, "a":100, "c":100}, {"A":100, "B":100, "C":100}),
  126.         ({"A":100, "B":100, "C":100, "a":100, "b":100}, {"A":100, "B":100, "C":100}),
  127.         ({"A":100, "B":100, "C":100, "a":100}, {"A":100, "B":100, "C":100}),
  128.         ({"A":100, "B":100, "C":100, "b":100}, {"A":100, "B":100, "C":100}),
  129.         ({"A":100, "B":100, "C":100, "c":100}, {"A":100, "B":100, "C":100}),
  130.  
  131.         ({"A":100, "B":100, "a":100, "b":100, "c":100}, {"A":100, "B":100}),
  132.         ({"A":100, "B":100, "b":100, "c":100}, {"A":100, "B":100}),
  133.         ({"A":100, "B":100, "a":100, "c":100}, {"A":100, "B":100}),
  134.         ({"A":100, "B":100, "a":100, "b":100}, {"A":100, "B":100}),
  135.         ({"A":100, "B":100, "a":100}, {"A":100, "B":100}),
  136.         ({"A":100, "B":100, "b":100}, {"A":100, "B":100}),
  137.         ({"A":100, "B":100, "c":100}, {"A":100, "B":100}),
  138.  
  139.         ({"A":100, "C":100, "a":100, "b":100, "c":100}, {"A":100, "C":100}),
  140.         ({"A":100, "C":100, "b":100, "c":100}, {"A":100, "C":100}),
  141.         ({"A":100, "C":100, "a":100, "c":100}, {"A":100, "C":100}),
  142.         ({"A":100, "C":100, "a":100, "b":100}, {"A":100, "C":100}),
  143.         ({"A":100, "C":100, "a":100}, {"A":100, "C":100}),
  144.         ({"A":100, "C":100, "b":100}, {"A":100, "C":100}),
  145.         ({"A":100, "C":100, "c":100}, {"A":100, "C":100}),
  146.  
  147.         ({"B":100, "C":100, "a":100, "b":100, "c":100}, {"B":100, "C":100}),
  148.         ({"B":100, "C":100, "b":100, "c":100}, {"B":100, "C":100}),
  149.         ({"B":100, "C":100, "a":100, "c":100}, {"B":100, "C":100}),
  150.         ({"B":100, "C":100, "a":100, "b":100}, {"B":100, "C":100}),
  151.         ({"B":100, "C":100, "a":100}, {"B":100, "C":100}),
  152.         ({"B":100, "C":100, "b":100}, {"B":100, "C":100}),
  153.         ({"B":100, "C":100, "c":100}, {"B":100, "C":100}),
  154.  
  155.         ({"A":100, "a":100, "b":100, "c":100}, {"A":100}),
  156.         ({"A":100, "b":100, "c":100}, {"A":100}),
  157.         ({"A":100, "a":100, "c":100}, {"A":100}),
  158.         ({"A":100, "a":100, "b":100}, {"A":100}),
  159.         ({"A":100, "a":100}, {"A":100}),
  160.         ({"A":100, "b":100}, {"A":100}),
  161.         ({"A":100, "c":100}, {"A":100}),
  162.  
  163.         ({"B":100, "a":100, "b":100, "c":100}, {"B":100}),
  164.         ({"B":100, "b":100, "c":100}, {"B":100}),
  165.         ({"B":100, "a":100, "c":100}, {"B":100}),
  166.         ({"B":100, "a":100, "b":100}, {"B":100}),
  167.         ({"B":100, "a":100}, {"B":100}),
  168.         ({"B":100, "b":100}, {"B":100}),
  169.         ({"B":100, "c":100}, {"B":100}),
  170.  
  171.         ({"C":100, "a":100, "b":100, "c":100}, {"C":100}),
  172.         ({"C":100, "b":100, "c":100}, {"C":100}),
  173.         ({"C":100, "a":100, "c":100}, {"C":100}),
  174.         ({"C":100, "a":100, "b":100}, {"C":100}),
  175.         ({"C":100, "a":100}, {"C":100}),
  176.         ({"C":100, "b":100}, {"C":100}),
  177.         ({"C":100, "c":100}, {"C":100}),
  178.  
  179.         ({"A":100, "B":100, "C":100}, {"A":100, "B":100, "C":100}),
  180.         ({"B":100, "C":100}, {"B":100, "C":100}),
  181.         ({"A":100, "C":100}, {"A":100, "C":100}),
  182.         ({"A":100, "B":100}, {"A":100, "B":100}),
  183.         ({"A":100}, {"A":100}),
  184.         ({"B":100}, {"B":100}),
  185.         ({"C":100}, {"C":100}),
  186.     ]
  187.  
  188.     def test_good_input(self):
  189.         for input, expected in self.good_input:
  190.             self.assertEqual(triangulo.get_known_sides(**input), expected)
  191.  
  192.  
  193. class KnownAngles(unittest.TestCase):
  194.     good_input = [ #100% coverage might be overkill :)
  195.         ({"A":100, "B":100, "C":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  196.         ({"A":100, "B":100, "C":100, "b":100, "c":100}, {"b":100, "c":100}),
  197.         ({"A":100, "B":100, "C":100, "a":100, "c":100}, {"a":100, "c":100}),
  198.         ({"A":100, "B":100, "C":100, "a":100, "b":100}, {"a":100, "b":100}),
  199.         ({"A":100, "B":100, "C":100, "a":100}, {"a":100}),
  200.         ({"A":100, "B":100, "C":100, "b":100}, {"b":100}),
  201.         ({"A":100, "B":100, "C":100, "c":100}, {"c":100}),
  202.  
  203.         ({"A":100, "B":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  204.         ({"A":100, "B":100, "b":100, "c":100}, {"b":100, "c":100}),
  205.         ({"A":100, "B":100, "a":100, "c":100}, {"a":100, "c":100}),
  206.         ({"A":100, "B":100, "a":100, "b":100}, {"a":100, "b":100}),
  207.         ({"A":100, "B":100, "a":100}, {"a":100}),
  208.         ({"A":100, "B":100, "b":100}, {"b":100}),
  209.         ({"A":100, "B":100, "c":100}, {"c":100}),
  210.  
  211.         ({"A":100, "C":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  212.         ({"A":100, "C":100, "b":100, "c":100}, {"b":100, "c":100}),
  213.         ({"A":100, "C":100, "a":100, "c":100}, {"a":100, "c":100}),
  214.         ({"A":100, "C":100, "a":100, "b":100}, {"a":100, "b":100}),
  215.         ({"A":100, "C":100, "a":100}, {"a":100}),
  216.         ({"A":100, "C":100, "b":100}, {"b":100}),
  217.         ({"A":100, "C":100, "c":100}, {"c":100}),
  218.  
  219.         ({"B":100, "C":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  220.         ({"B":100, "C":100, "b":100, "c":100}, {"b":100, "c":100}),
  221.         ({"B":100, "C":100, "a":100, "c":100}, {"a":100, "c":100}),
  222.         ({"B":100, "C":100, "a":100, "b":100}, {"a":100, "b":100}),
  223.         ({"B":100, "C":100, "a":100}, {"a":100}),
  224.         ({"B":100, "C":100, "b":100}, {"b":100}),
  225.         ({"B":100, "C":100, "c":100}, {"c":100}),
  226.  
  227.         ({"A":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  228.         ({"A":100, "b":100, "c":100}, {"b":100, "c":100}),
  229.         ({"A":100, "a":100, "c":100}, {"a":100, "c":100}),
  230.         ({"A":100, "a":100, "b":100}, {"a":100, "b":100}),
  231.         ({"A":100, "a":100}, {"a":100}),
  232.         ({"A":100, "b":100}, {"b":100}),
  233.         ({"A":100, "c":100}, {"c":100}),
  234.  
  235.         ({"B":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  236.         ({"B":100, "b":100, "c":100}, {"b":100, "c":100}),
  237.         ({"B":100, "a":100, "c":100}, {"a":100, "c":100}),
  238.         ({"B":100, "a":100, "b":100}, {"a":100, "b":100}),
  239.         ({"B":100, "a":100}, {"a":100}),
  240.         ({"B":100, "b":100}, {"b":100}),
  241.         ({"B":100, "c":100}, {"c":100}),
  242.  
  243.         ({"C":100, "a":100, "b":100, "c":100}, {"a":100, "b":100, "c":100}),
  244.         ({"C":100, "b":100, "c":100}, {"b":100, "c":100}),
  245.         ({"C":100, "a":100, "c":100}, {"a":100, "c":100}),
  246.         ({"C":100, "a":100, "b":100}, {"a":100, "b":100}),
  247.         ({"C":100, "a":100}, {"a":100}),
  248.         ({"C":100, "b":100}, {"b":100}),
  249.         ({"C":100, "c":100}, {"c":100}),
  250.  
  251.         ({"A":100, "B":100, "C":100}, {}),
  252.         ({"B":100, "C":100}, {}),
  253.         ({"A":100, "C":100}, {}),
  254.         ({"A":100, "B":100}, {}),
  255.         ({"A":100}, {}),
  256.         ({"B":100}, {}),
  257.         ({"C":100}, {}),
  258.     ]
  259.  
  260.     def test_good_input(self):
  261.         for input, expected in self.good_input:
  262.             self.assertEqual(triangulo.get_known_angles(**input), expected)
  263.  
  264. if __name__ == "__main__":
  265.     unittest.main()