content: module UnitConversions.Tests where
  
  import Data.Tuple (swap)
  import Instances ()
  import Test.HUnit ((@?=))
  import Test.QuickCheck ((===), (==>))
  import Test.Tasty (TestTree, testGroup)
  import Test.Tasty.HUnit (testCase)
  import Test.Tasty.QuickCheck (testProperty)
  import Types
  import UnitConversions
  
  isMetric :: Unit -> Bool
  isMetric unit =
    case unit of
      Ml -> True
      L -> True
      G -> True
      _ -> False
  
  test :: TestTree
  test =
    testGroup
      "ConversionTests"
      [ ingredientTests,
        temperatureUnitTests,
        findingTemperaturesUnitTests
      ]
  
  ingredientTests :: TestTree
  ingredientTests =
    testGroup
      "IngredientConversions"
      [ testProperty "testToMetric" $
          \x ->
            isMetric (unit x)
              ==> convertIngredientToMetric x === x,
        testProperty "testToImperial" $
          \x ->
            not (isMetric (unit x))
              ==> convertIngredientToImperial x === x
      ]
  
  temperatureUnitTests :: TestTree
  temperatureUnitTests =
    testGroup
      "TemperatureConversions"
      [ testCase "Converting °F to °C in a text" $
          convertTemperatureToMetric "preheat to 110°F" @?= "preheat to 43°C",
        testCase "Converting °C to °F in a text" $
          -- because of rounding we get 109°F when converting 110° F -> °C -> °F
          convertTemperatureToImperial "preheat to 43°C" @?= "preheat to 109°F"
      ]
  
  findingTemperaturesUnitTests :: TestTree
  findingTemperaturesUnitTests =
    testGroup "recognizing/ignoring temperatures in a test" $
      let getTemperatures = map snd . findReplacements
          cases =
            [ ("250°C", [Temperature 250 C]),
              ("10 °C", [Temperature 10 C]),
              ("-10 °C", [Temperature (-10) C]),
              ("abc 15 C def", [Temperature 15 C]),
              ("5 C", [Temperature 5 C]),
              ("250C", [Temperature 250 C]),
              ("999°F", [Temperature 999 F]),
              ("34F", [Temperature 34 F]),
              ("250°C.", [Temperature 250 C]),
              ("250°C!", [Temperature 250 C]),
              ("250°C?", [Temperature 250 C]),
              ("10C 15F", [Temperature 10 C, Temperature 15 F]),
              ("0 Frites", []),
              ("250Crabs", []),
              ("250 Crabs", [])
            ] ::
              [(String, [Temperature])]
       in map ((\(exp, test) -> testCase test (getTemperatures test @?= exp)) . swap) cases
  