ここでは、特定のモナドアクションの動作を調べるために使ってきたイベントネットワークのサンプルを紹介します。私はコードをテストするこの特別な方法ではなく、原則的なアプローチを望んでいます。私は自分の関数をテストする方法を知っていますが、私は新しいデザインの選択肢を考えて、ビヘイビアとイベントをテストするためのベストプラクティスを探していますreactive-banana 1.0.0
Reactive Banana 1.0.0 - MomentIO()モナドのユニットテスト
私はたくさん残しています。私の問題を説明するために必要です。問題を明確にするために含めるべきでないものがある場合は、教えてください。バッファが行うことになっている何
makeNetworkDescription :: Parameters -> MomentIO()
makeNetworkDescription params = mdo
eInput <- fromAddHandler (input params)
eTick <- fromAddHandler (tick params)
let
eValidated :: Event VAC
eValidated = toVAC <$> eInput
eClearBuffer = Clear <$ eBuffer
eBuffer ::Event BufferMap
eBuffer = bBuffer <@ eTick
bBuffer <- accumB (BufferMap (M.empty :: M.Map AID VAC)) $
manageBuffer <$> unionWith (clearBuffer) eValidated eClearBuffer
reactimate $ writeOut_Debug <$> eBuffer
、(その後、別の場所で処理されます)プレーヤーのコマンドを蓄積しており、プレイヤーのコマンドの特定のバッチが処理された後、その後、空にすること。次のティックで、それは再び何度も起こります。
私は、バッファが必要なときにクリアされていることを確認し、想定されているようなコマンドを蓄積します。今すぐコードが動作し、私はこのゲームを構築するときにそれが動作し続けることを保証するテストを書きたいと思う。
Behavior
を上記の例のEvent
ネットワークから分離することはできますが、それではどうしますか?テストから正確な結果を得るための最良の方法は何ですか?
編集:更新 - 私はthis linkが十分なヒントを提供すると信じています。私はそれを刺し、明日の詳細を報告します。
編集:更新 - ユニットテストが作成されています。私はgithubにパリティがあるときにアップロードし、投稿します。上記のリンクは、何をすべきかを整理するのに非常に役立ちました。
編集:更新 - スタックテストを実行しているときにタイプエラーが発生し、再度実行すると、テストが合格したという出力が表示されます。結局のところ、私は昨日だったとは限りません。私はコードと明確な問題があります。私はthat.ctの別の投稿を開始することがあります。
編集:更新 - 私は役に立つ方法で壊れてテストがありますが、私はそれについて正確に何をしないのですか。私は文脈のためにproject全体を投稿しました。以下に、テストコード、エラー、およびいくつかの議論だけを示します。
main :: IO()
main = defaultMain
[ testGroup "EventNetwork Input"
[testBuffer "bBuffer" Populated]
]
testBuffer :: String -> BufferState -> Test
testBuffer name Populated =
testCase name $ assert $ bufferPopulated (UAC (PlayerCommand (Move (ToPlanetName Mongo)) (AID (Data.Text.pack "100"))))
testBuffer name Empty =
testCase name $ assert $ bufferEmptied (UAC (PlayerCommand (Move (ToPlanetName Mongo)) (AID (Data.Text.pack "100"))))
bufferPopulated :: UAC -> MomentIO Bool
bufferPopulated ev = do
let eInput = ev <$ never
eValidated = toVAC <$> eInput
bBufferMap <- (buffer eValidated eClear) :: MomentIO (Behavior BufferMap)
let r2 = [(Just $ BufferMap $ M.insert (AID (Data.Text.pack "100")) (toVAC ev) (M.empty :: M.Map AID VAC))]
r1 <- liftIO $ ((interpret (eBuffer bBufferMap) []) :: IO [Maybe BufferMap])
return $ r1 == r2
bufferEmptied :: UAC -> MomentIO Bool
bufferEmptied ev = undefined
eBuffer :: Behavior BufferMap -> Event a -> Event BufferMap
eBuffer bBufferMap nvr =
bBufferMap <@ (() <$ nvr)
eClear = Clear <$ (() <$ never)
tests/Spec.hs:26:19:
No instance for (Test.HUnit.Base.Assertable (MomentIO Bool))
arising from a use of ‘assert’
In the expression: assert
In the second argument of ‘($)’, namely
‘assert
$ bufferPopulated
(UAC
(PlayerCommand (Move (ToPlanetName Mongo)) (AID (pack "100"))))’
In the expression:
testCase name
$ assert
$ bufferPopulated
(UAC
(PlayerCommand (Move (ToPlanetName Mongo)) (AID (pack "100"))))
問題がMomemtIO
でBehavior
を作成accumB
にダウンしています。もし私がbufferPopulated
を返すとIO Bool
私はそれをどのように調整できますか?
編集:明白なことは、必要なインスタンスを作成することです。私はこれがおそらく赤ちゃんだと思う。どう思いますか。これは単にMomentIO Bool
インスタンスを作成するだけの簡単なことですか?
編集:更新 私は正しい道にいると思う。私はのはReactive.Banana.Combinators
MonadMoment
を見てみましょう、すべてのテストハーネスのコードをコメントアウトしていると
bufferPopulated
bufferPopulated :: UAC -> IO Bool
bufferPopulated ev = do
let eInput = ev <$ never
eValidated = toVAC <$> eInput
bBufferMap <- liftMoment ((buffer eValidated eClear) :: Moment (Behavior BufferMap))
let r2 = [(Just $ BufferMap $ M.insert (AID (Data.Text.pack "100")) (toVAC ev) (M.empty :: M.Map AID VAC))]
r1 <- (interpret (eBuffer bBufferMap) []) :: IO [Maybe BufferMap])
return $ r1 == r2
のための署名を変更している私は、これは動作するはずと信じていますが、ここでエラーが
だtests/Spec.hs:35:17:
No instance for (MonadMoment IO) arising from a use of ‘liftMoment’
In a stmt of a 'do' block:
bBufferMap <- liftMoment
((buffer eValidated eClear) :: Moment (Behavior BufferMap))
m
は、いずれでもよいが、Monad
,IO
はMonad
。そうliftMoment
がMoment Behavior (BufferMap)
からIO Behavior (BufferMap)
を持ち上げる必要があり、なぜそれはしていません。私の推論で何が間違っていますか?答えの