Additional testing

This commit is contained in:
Gregor Kleen 2019-05-20 00:06:15 +02:00
parent 848dc7470a
commit 7deba81320
3 changed files with 42 additions and 8 deletions

View File

@ -243,6 +243,7 @@ tests:
- uniworx - uniworx
- hspec >=2.0.0 - hspec >=2.0.0
- QuickCheck - QuickCheck
- HUnit
- yesod-test - yesod-test
- conduit-extra - conduit-extra
- quickcheck-classes - quickcheck-classes

View File

@ -188,7 +188,7 @@ assignSubmissions sid restriction = do
-- Deficit produced by restriction to tutors can thus be fixed by later submissions -- Deficit produced by restriction to tutors can thus be fixed by later submissions
targetSubmissions' <- liftIO . unstableSortBy (comparing $ \subId -> Map.null . view _2 $ submissionData ! subId) $ Set.toList targetSubmissions targetSubmissions' <- liftIO . unstableSortBy (comparing $ \subId -> Map.null . view _2 $ submissionData ! subId) $ Set.toList targetSubmissions
(newSubmissionData, ()) <- (\act -> execRWST act oldSubmissionData targetSubmissionData) . forM_ targetSubmissions' $ \subId -> do (newSubmissionData, ()) <- (\act -> execRWST act oldSubmissionData targetSubmissionData) . forM_ (zip [1..] targetSubmissions') $ \(i, subId) -> do
tutors <- gets $ view _2 . (! subId) -- :: Map UserId (Sum Natural) tutors <- gets $ view _2 . (! subId) -- :: Map UserId (Sum Natural)
let acceptableCorrectors let acceptableCorrectors
| correctorsByTut <- Map.filter (is _Just . view _byTutorial) $ sheetCorrectors `Map.restrictKeys` Map.keysSet tutors | correctorsByTut <- Map.filter (is _Just . view _byTutorial) $ sheetCorrectors `Map.restrictKeys` Map.keysSet tutors
@ -205,9 +205,9 @@ assignSubmissions sid restriction = do
& maximumsBy (deficits !) & maximumsBy (deficits !)
& maximumsBy (tutors !?) & maximumsBy (tutors !?)
$logDebugS "assignSubmissions" [st|Tutors for #{tshow subId}: #{tshow tutors}|] $logDebugS "assignSubmissions" [st|#{tshow i} Tutors for #{tshow subId}: #{tshow tutors}|]
$logDebugS "assignSubmissions" [st|Current (#{tshow subId}) relevant deficits: #{tshow deficits}|] $logDebugS "assignSubmissions" [st|#{tshow i} Current (#{tshow subId}) relevant deficits: #{tshow deficits}|]
$logDebugS "assignSubmissions" [st|Assigning #{tshow subId} to one of #{tshow bestCorrectors}|] $logDebugS "assignSubmissions" [st|#{tshow i} Assigning #{tshow subId} to one of #{tshow bestCorrectors}|]
ix subId . _1 <~ Just <$> liftIO (Rand.uniform bestCorrectors) ix subId . _1 <~ Just <$> liftIO (Rand.uniform bestCorrectors)

View File

@ -3,11 +3,13 @@ module Handler.Utils.SubmissionSpec where
import qualified Yesod import qualified Yesod
import TestImport import TestImport
-- import qualified Test.HUnit.Base as HUnit
import Handler.Utils.Submission import Handler.Utils.Submission
import ModelSpec () import ModelSpec ()
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map ((!?))
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.List (genericLength) import Data.List (genericLength)
@ -19,10 +21,12 @@ import System.IO.Unsafe
import System.Random.Shuffle import System.Random.Shuffle
import Control.Monad.Random.Class import Control.Monad.Random.Class
import Database.Persist.Sql (fromSqlKey) import Database.Persist.Sql (toSqlKey, fromSqlKey)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
-- import Data.Maybe (fromJust)
userNumber :: TVar Natural userNumber :: TVar Natural
userNumber = unsafePerformIO $ newTVarIO 1 userNumber = unsafePerformIO $ newTVarIO 1
@ -135,10 +139,27 @@ spec = withApp . describe "Submission distribution" $ do
countResult `shouldNotSatisfy` Map.member Nothing countResult `shouldNotSatisfy` Map.member Nothing
countResult' `shouldSatisfy` all (\(Just (_, prop), subsSet) -> (== 50 * prop) $ fromIntegral subsSet) . Map.toList countResult' `shouldSatisfy` all (\(Just (_, prop), subsSet) -> (== 50 * prop) $ fromIntegral subsSet) . Map.toList
) )
it "follows non-constant cumulative distribution over multiple sheets" $ do
let ns = replicate 4 100
loads = do
(onesBefore, onesAfter) <- zip [0,2..6] [6,4..0]
return $ replicate onesBefore (Just $ Load Nothing 1)
++ replicate 2 (Just $ Load Nothing 2)
++ replicate onesAfter (Just $ Load Nothing 1)
distributionExample
(return $ zip ns loads)
(\_ _ -> return ())
(\result -> do
let countResult = Map.map Set.size result
countResult' = Map.mapKeysWith (+) (fmap $ \SheetCorrector{..} -> fromSqlKey sheetCorrectorUser) countResult
countResult `shouldNotSatisfy` Map.member Nothing
countResult' `shouldSatisfy` all (\(Just _, subsSet) -> subsSet == 50) . Map.toList
)
it "handles tutorials with proportion" $ do it "handles tutorials with proportion" $ do
ns <- liftIO . replicateM 5 . fmap fromInteger $ getRandomR (0, 100) ns <- liftIO . replicateM 5 . fmap fromInteger $ getRandomR (0, 100)
let ns' = ns ++ [500 - sum ns] let ns' = ns ++ [500 - sum ns]
loads = replicate 6 (Just $ Load Nothing 1) ++ replicate 2 (Just $ Load Nothing 2) loads = replicate 6 (Just $ Load (Just True) 1) ++ replicate 2 (Just $ Load (Just True) 2)
tutSubIds <- liftIO $ newTVarIO Map.empty
distributionExample distributionExample
(return [ (n, loads) | n <- ns' ]) (return [ (n, loads) | n <- ns' ])
(\subs corrs -> do (\subs corrs -> do
@ -146,6 +167,7 @@ spec = withApp . describe "Submission distribution" $ do
subs' <- liftIO $ shuffleM subs subs' <- liftIO $ shuffleM subs
forM_ (take tutSubmissions subs') $ \(Entity subId Submission{..}) -> do forM_ (take tutSubmissions subs') $ \(Entity subId Submission{..}) -> do
Entity _ SheetCorrector{..} <- liftIO $ uniform corrs Entity _ SheetCorrector{..} <- liftIO $ uniform corrs
atomically . modifyTVar tutSubIds . Map.insertWith mappend sheetCorrectorUser $ Set.singleton subId
Sheet{..} <- getJust submissionSheet Sheet{..} <- getJust submissionSheet
tut <- liftIO $ generate arbitrary <&> \c -> c { tutorialName = CI.mk $ "Tut for " <> tshow (fromSqlKey subId), tutorialCourse = sheetCourse } tut <- liftIO $ generate arbitrary <&> \c -> c { tutorialName = CI.mk $ "Tut for " <> tshow (fromSqlKey subId), tutorialCourse = sheetCourse }
tutId <- insert tut tutId <- insert tut
@ -157,6 +179,17 @@ spec = withApp . describe "Submission distribution" $ do
(\result -> do (\result -> do
let countResult = Map.map Set.size result let countResult = Map.map Set.size result
countResult' = Map.mapKeysWith (+) (fmap $ \SheetCorrector{..} -> (fromSqlKey sheetCorrectorUser, byProportion sheetCorrectorLoad)) countResult countResult' = Map.mapKeysWith (+) (fmap $ \SheetCorrector{..} -> (fromSqlKey sheetCorrectorUser, byProportion sheetCorrectorLoad)) countResult
countResult `shouldNotSatisfy` Map.member Nothing tutSubIds' <- liftIO $ readTVarIO tutSubIds
countResult' `shouldSatisfy` all (\(Just (_, prop), subsSet) -> (== 50 * prop) $ fromIntegral subsSet) . Map.toList
countResult' `shouldNotSatisfy` Map.member Nothing
countResult' `shouldSatisfy` all (\(Just (corr, prop), subsSet) -> fromIntegral subsSet <= max (50 * prop) (maybe 0 (fromIntegral . Set.size) $ tutSubIds' !? toSqlKey corr)) . Map.toList
-- -- Does not currently work, because `User`s are reused within `distributionExample`, so submissions end up having more associated course-tutors, because the same user might be a member of a tutorial created for another submission
--
-- let subs = fold tutSubIds'
-- forM_ subs $ \subId -> do
-- let tutors = Map.keysSet $ Map.filter (Set.member subId) tutSubIds'
-- assignedTo = Set.map (sheetCorrectorUser . fromJust) . Map.keysSet $ Map.filter (Set.member subId) result
-- HUnit.assertEqual ("Submission " <> show (fromSqlKey subId) <> " assigned to multiple correctors") 1 $ Set.size assignedTo
-- HUnit.assertEqual ("Submission " <> show (fromSqlKey subId) <> " assigned to non-tutors (" <> show (Set.map fromSqlKey tutors) <> ")") Set.empty (Set.map fromSqlKey $ assignedTo `Set.difference` tutors)
) )