content: module Text.Megaparsec.PosSpec (spec) where
  
  import Control.Exception (evaluate)
  import Data.Function (on)
  import Data.List (isInfixOf)
  import Test.Hspec
  import Test.Hspec.Megaparsec.AdHoc ()
  import Test.QuickCheck
  import Text.Megaparsec.Pos
  
  spec :: Spec
  spec = do
    describe "mkPos" $ do
      context "when the argument is a non-positive number" $
        it "throws InvalidPosException" $
          property $ \n ->
            n <= 0 ==>
              evaluate (mkPos n) `shouldThrow` (== InvalidPosException n)
      context "when the argument is not 0" $
        it "returns Pos with the given value" $
          property $ \n ->
            (n > 0) ==> (unPos (mkPos n) `shouldBe` n)
  
    describe "Read and Show instances of Pos" $
      it "printed representation of Pos is isomorphic to its value" $
        property $ \x ->
          read (show x) === (x :: Pos)
  
    describe "Ord instance of Pos" $
      it "works just like Ord instance of underlying Word" $
        property $ \x y ->
          compare x y === (compare `on` unPos) x y
  
    describe "Semigroup instance of Pos" $
      it "works like addition" $
        property $ \x y ->
          x <> y === mkPos (unPos x + unPos y)
            .&&. unPos (x <> y) === unPos x + unPos y
  
    describe "initialPos" $
      it "constructs initial position correctly" $
        property $ \path ->
          let x = initialPos path
           in sourceName x === path
                .&&. sourceLine x === mkPos 1
                .&&. sourceColumn x === mkPos 1
  
    describe "Read and Show instances of SourcePos" $
      it "printed representation of SourcePos in isomorphic to its value" $
        property $ \x ->
          read (show x) === (x :: SourcePos)
  
    describe "sourcePosPretty" $ do
      it "displays file name" $
        property $ \x ->
          sourceName x `isInfixOf` sourcePosPretty x
      it "displays line number" $
        property $ \x ->
          (show . unPos . sourceLine) x `isInfixOf` sourcePosPretty x
      it "displays column number" $
        property $ \x ->
          (show . unPos . sourceColumn) x `isInfixOf` sourcePosPretty x
  