{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}

module Math.Programming.Tests.Api where

import Control.Monad.IO.Class
import Math.Programming
import Test.Hspec

makeApiTests ::
  (MonadIO m, MonadLP v c o m) =>
  -- | The runner for the API being tested.
  (m () -> IO ()) ->
  -- | The resulting test suite.
  Spec
makeApiTests :: forall (m :: * -> *) v c o.
(MonadIO m, MonadLP v c o m) =>
(m () -> IO ()) -> Spec
makeApiTests m () -> IO ()
runner =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"API tests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"sets and gets variable names" (m () -> IO ()
runner m ()
forall (m :: * -> *) v c o. (MonadIO m, MonadLP v c o m) => m ()
setGetVariableName)
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"sets and gets constraint names" (m () -> IO ()
runner m ()
forall (m :: * -> *) v c o. (MonadIO m, MonadLP v c o m) => m ()
setGetConstraintName)

setGetVariableName :: (MonadIO m, MonadLP v c o m) => m ()
setGetVariableName :: forall (m :: * -> *) v c o. (MonadIO m, MonadLP v c o m) => m ()
setGetVariableName = do
  let name :: Text
name = Text
"foo"
  v
x <- m v
forall v c o (m :: * -> *). MonadLP v c o m => m v
free
  v -> Text -> m ()
forall v c o (m :: * -> *). MonadLP v c o m => v -> Text -> m ()
setVariableName v
x Text
name
  Text
vName <- v -> m Text
forall v c o (m :: * -> *). MonadLP v c o m => v -> m Text
getVariableName v
x
  IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Text
vName Text -> Text -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Text
name

setGetConstraintName :: (MonadIO m, MonadLP v c o m) => m ()
setGetConstraintName :: forall (m :: * -> *) v c o. (MonadIO m, MonadLP v c o m) => m ()
setGetConstraintName = do
  let name :: Text
name = Text
"foo"
  v
x <- m v
forall v c o (m :: * -> *). MonadLP v c o m => m v
free
  c
c <- v -> LinExpr Double v
forall a b. Num a => b -> LinExpr a b
var v
x LinExpr Double v -> Double -> m c
forall v c o (m :: * -> *).
MonadLP v c o m =>
Expr v -> Double -> m c
.>= Double
0
  c -> Text -> m ()
forall v c o (m :: * -> *). MonadLP v c o m => c -> Text -> m ()
setConstraintName c
c Text
name
  Text
cName <- c -> m Text
forall v c o (m :: * -> *). MonadLP v c o m => c -> m Text
getConstraintName c
c
  IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Text
cName Text -> Text -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Text
name