Skip to content
This repository was archived by the owner on Sep 30, 2025. It is now read-only.

Commit 4537442

Browse files
committed
Add property based tests and refactor
1 parent 7954604 commit 4537442

5 files changed

Lines changed: 78 additions & 33 deletions

File tree

package.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ tests:
6363
dependencies:
6464
- QuickCheck
6565
- hspec
66-
- hspec-expectations-lifted
6766
- quickcheck-classes
6867
- yesod-core
6968
- yesod-paginator

src/Yesod/Paginator/Widgets.hs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module Yesod.Paginator.Widgets
99
, ellipsedWith
1010

1111
-- * Exported for testing
12-
, buildParams
12+
, setPageParameters
1313
) where
1414

1515
import Yesod.Paginator.Prelude
@@ -180,15 +180,15 @@ getUpdateGetParams
180180
:: PageParamName -> WidgetFor site (PageNumber -> [(Text, Text)])
181181
getUpdateGetParams pageParamName = do
182182
params <- handlerToWidget $ reqGetParams <$> getRequest
183-
pure
184-
$ \number -> buildParams pageParamName number params
183+
pure $ \number -> setPageParameters pageParamName number params
185184

186185
renderGetParams :: [(Text, Text)] -> Text
187186
renderGetParams [] = ""
188187
renderGetParams ps = "?" <> T.intercalate "&" (map renderGetParam ps)
189188
where renderGetParam (k, v) = encodeText k <> "=" <> encodeText v
190189

191-
buildParams :: Show a => PageParamName -> a -> [(Text, Text)] -> [(Text, Text)]
192-
buildParams pageParamName number params =
193-
let name = unPageParamName pageParamName
194-
in [(name, tshow number)] <> filter ((/=) name . fst) params
190+
setPageParameters
191+
:: Show a => PageParamName -> a -> [(Text, Text)] -> [(Text, Text)]
192+
setPageParameters pageParamName number params =
193+
let name = unPageParamName pageParamName
194+
in [(name, tshow number)] <> filter ((/=) name . fst) params

test/SpecHelper.hs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ module SpecHelper
1010
, module X
1111
) where
1212

13-
import Test.Hspec as X hiding (shouldBe)
14-
import Test.Hspec.Expectations.Lifted as HspecLifted
13+
import qualified Data.List as List
14+
import Test.Hspec as X
1515
import Yesod.Core
1616
import Yesod.Paginator as X
1717
import Yesod.Paginator.Prelude as X
@@ -64,5 +64,20 @@ getEllipsedParamNameR total per elements pageParamName = do
6464
withApp :: SpecWith (TestApp App) -> Spec
6565
withApp = before $ pure (App, id)
6666

67-
shouldBe :: (HasCallStack, Eq a, Show a) => a -> a -> YesodExample site ()
68-
shouldBe a b = a `HspecLifted.shouldBe` b
67+
shouldIncludeAll
68+
:: (Foldable t, Eq a, Show a, Show (t a)) => t a -> [a] -> Expectation
69+
shouldIncludeAll actual subset = expectTrue msg (all isIncluded subset)
70+
where
71+
isIncluded = (`elem` actual)
72+
msg =
73+
show actual
74+
<> " did not include all of "
75+
<> show subset
76+
<> " - missing: "
77+
<> List.intercalate
78+
", "
79+
(fmap show (filter (not . isIncluded) subset))
80+
81+
-- Cloned from 'Test.Hspec.Expectations'
82+
expectTrue :: HasCallStack => String -> Bool -> Expectation
83+
expectTrue msg b = unless b (expectationFailure msg)

test/Yesod/Paginator/WidgetsSpec.hs

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
{-# LANGUAGE OverloadedStrings #-}
2+
23
module Yesod.Paginator.WidgetsSpec
34
( spec
45
) where
56

7+
import Data.Functor ((<&>))
68
import SpecHelper
9+
import Test.Hspec.QuickCheck
10+
import Test.QuickCheck
711

812
spec :: Spec
9-
spec = withApp $ do
13+
spec = integrationSpecs >> setPageParametersSpecs
14+
15+
integrationSpecs :: Spec
16+
integrationSpecs = withApp $ do
1017
describe "simple" $ it "works" $ do
1118
get $ SimpleR 10 3 3
1219

@@ -189,22 +196,47 @@ spec = withApp $ do
189196
, "</ul>"
190197
]
191198

192-
describe "buildParams" $ it "works" $ do
193-
let pageParamName = PageParamName "p"
194-
pageNumber :: Int
195-
pageNumber = 3
196-
params :: [(Text, Text)]
197-
params =
198-
[ ("p", "2")
199-
, ("p", "3")
200-
, ("foo", "bar")
201-
, ("ids[]", "1")
202-
, ("ids[]", "2")
203-
]
204-
205-
buildParams pageParamName pageNumber params
206-
`shouldBe` [ ("p", "3")
207-
, ("foo", "bar")
208-
, ("ids[]", "1")
209-
, ("ids[]", "2")
210-
]
199+
data Params = Params
200+
{ paramsPageParamName :: PageParamName
201+
, paramsPageNumber :: Int
202+
, paramsParams :: [(Text, Text)]
203+
}
204+
deriving Show
205+
206+
instance Arbitrary Params where
207+
arbitrary = do
208+
params <- listOf $ liftArbitrary2 genText genText
209+
pageNumber <- getPositive <$> arbitrary
210+
pageParamName <- PageParamName <$> genText
211+
pure $ Params pageParamName pageNumber params
212+
where
213+
genText :: Gen Text
214+
genText = listOf (choose ('a', 'z')) <&> pack
215+
216+
217+
setPageParametersSpecs :: Spec
218+
setPageParametersSpecs = describe "setPageParameters" $ do
219+
it "inserts" $ do
220+
let paramName = PageParamName "p"
221+
pageNumber = 1 :: Int
222+
setPageParameters paramName pageNumber [] `shouldBe` [("p", "1")]
223+
224+
it "updates" $ do
225+
let paramName = PageParamName "p"
226+
pageNumber = 1 :: Int
227+
setPageParameters paramName pageNumber [("p", "foo")]
228+
`shouldBe` [("p", "1")]
229+
230+
prop "doesn't remove not-ours elements" $ do
231+
Params paramName pageNumber params <- arbitrary
232+
let outputKeys = fst <$> setPageParameters paramName pageNumber params
233+
inputKeys = fst <$> params
234+
pure $ outputKeys `shouldIncludeAll` inputKeys
235+
236+
prop "doesn't add not-ours elements" $ do
237+
Params paramName pageNumber params <- arbitrary
238+
let outputKeys = fst <$> setPageParameters paramName pageNumber params
239+
inputKeys = fst <$> params
240+
pure
241+
$ (unPageParamName paramName : inputKeys)
242+
`shouldIncludeAll` outputKeys

yesod-paginator.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ test-suite test
116116
QuickCheck
117117
, base <5
118118
, hspec
119-
, hspec-expectations-lifted
120119
, quickcheck-classes
121120
, yesod-core
122121
, yesod-paginator

0 commit comments

Comments
 (0)