سؤال

أود أن تمرير عدد صحيح كوسيطة كلي لبرنامج هاسكل الذي يجعل من استخدام كويكشيك / monadicIO.سيتم استخدام هذا العدد الصحيح داخل assert لجعل الاختبارات قابلة للتخصيص.المشكلة هي أنه بمجرد تحليل قيمة عدد صحيح في main, ، أنا لا أعرف كيفية تمريرها داخل monadicIO اتصل دون استخدام شيء قبيح مثل IORef.أعتقد أن الحل الأنيق قد يكون Reader موناد ، ولكن لم أتمكن من العثور على حل لجعلها تعمل ، ينظر إليها على أنها quickCheck جامدة في حججها.أي أفكار?

في وقت لاحق تحرير 1: كما هو مطلوب ، أقوم بإرفاق الرمز الفعلي الذي أحاول تشغيله ، وفشل.تمثل الخطوط المعلقة محاولتي الفاشلة.معلومات أساسية:ويهدف جناح الاختبار إلى ممارسة نقطة نهاية بعيدة بسيطة جدا أن يحسب شا 512 من المدخلات العشوائية التي تم إنشاؤها بواسطة كويكشيك.نقطة النهاية عن بعد هي بيثون / قارورة مقرها.

في وقت لاحق تحرير 2 ردا على @ المستخدم2407038: أنا يمكن أن تجعل propHasExpectedLengthCeiling خذ حجة إضافية من نوع كثافة العمليات ، ولكن quickCheck من شأنه أن يولد قيما عشوائية لذلك ، وهذا ليس ما أريد حدوثه.هدفي هو استخدام maxSegmentLengthCeiling أن أنا أخذ في من وسيطات سطر الأوامر واستخدامها في let testPassed = actualMaxSegmentLength <= maxSegmentLengthCeiling داخل monadicIO منع.الآن maxSegmentLengthCeiling يتم تحديده كقيمة المستوى الأعلى ، مما يعني أنني يجب أن إعادة ترجمة التعليمات البرمجية في كل مرة أقوم بتغيير القيمة.ليس لدي حتى الآن أي رمز يتضمن IORef لأن هذا هو الملاذ الأخير وجوهر سؤالي هو كيفية تجنب الذهاب IORef الطريق.

import qualified Data.ByteString.Lazy.Char8 as LC

import Control.Applicative     ( (<$>) )
import Data.Function           ( on )
import Data.List               ( groupBy )
import Data.Char               ( isDigit )
--import Safe                    ( headMay
--                               , readMay
--                               )
--import System.Environment      ( getArgs )
import Network.HTTP.Conduit    ( simpleHttp )
import Test.QuickCheck         ( Arbitrary
                               , Property
                               , arbitrary
                               , choose
                               , frequency
                               , quickCheckWith
                               , stdArgs
                               , vectorOf
                               )
import Test.QuickCheck.Test    ( Args
                               , maxSuccess
                               )
import Test.QuickCheck.Monadic ( assert
                               , monadicIO
                               , run
                               )

newtype CustomInput = MkCustomInput String deriving Show

instance Arbitrary CustomInput where
  arbitrary =
    let
      genCustomInput = vectorOf 20
                       $ frequency [ (26, choose ('0','9'))
                                   , (10, choose ('a','z'))
                                   ]
    in
      MkCustomInput <$> genCustomInput

maxSegmentLengthCeiling :: Int
maxSegmentLengthCeiling = 22

urlPrefix :: String
urlPrefix = "http://192.168.2.3:5000/sha512sum/"

propHasExpectedLengthCeiling :: CustomInput -> Property
propHasExpectedLengthCeiling (MkCustomInput input) = monadicIO $ do
  testPassed <- run $ do
    response <- simpleHttp $ urlPrefix ++ input
    let stringResponse = LC.unpack response
    let brokenDownStringResponse = groupBy ( (==) `on` isDigit ) stringResponse
    let actualMaxSegmentLength = maximum $ map length brokenDownStringResponse
    let testPassed = actualMaxSegmentLength <= maxSegmentLengthCeiling
    putStrLn ""
    putStrLn ""
    putStrLn $ "Input:       " ++ input
    putStrLn $ "Control sum: " ++ stringResponse
    putStrLn $ "Breakdown:   " ++ show brokenDownStringResponse
    putStrLn $ "Max. length: " ++ show actualMaxSegmentLength
    putStrLn $ "Ceiling:     " ++ show maxSegmentLengthCeiling
    putStrLn $ "Test result: " ++ if testPassed then "Pass" else "Fail"
    putStrLn ""
    putStrLn ""
    return testPassed
  assert $ testPassed

customArgs :: Args
customArgs = stdArgs { maxSuccess = 1000000 }

--readMayAsInt :: String -> Maybe Int
--readMayAsInt = readMay

main :: IO ()
main =
--main = do
--  cliArgs <- getArgs
--  let ceilingInputMay = headMay cliArgs >>= readMayAsInt
--  maxSegmentLengthCeiling <- case ceilingInputMay of
--                               (Just lengthCeiling) -> return lengthCeiling
--                               Nothing              -> error "No valid number given"
  quickCheckWith
    customArgs
    propHasExpectedLengthCeiling
هل كانت مفيدة؟

المحلول

جعل maxSegmentLengthCeiling معلمة إلى propHasExpectedLengthCeiling :

propHasExpectedLengthCeiling :: Int -> CustomInput -> Property

واستدعاء ذلك على النحو التالي

main = do 
  [n] <- getArgs
  quickCheckWith customArgs (propHasExpectedLengthCeiling (read n))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top