mirror of
https://github.com/github/semantic.git
synced 2024-12-01 00:33:59 +03:00
61 lines
2.6 KiB
Haskell
61 lines
2.6 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
||
module Source.Test
|
||
( testTree
|
||
) where
|
||
|
||
import qualified Data.Text as Text
|
||
import Hedgehog hiding (Range)
|
||
import qualified Hedgehog.Gen as Gen
|
||
import qualified Hedgehog.Range as Range
|
||
import qualified Source.Source as Source
|
||
import Source.Span
|
||
import qualified Test.Tasty as Tasty
|
||
import Test.Tasty.HUnit
|
||
import Test.Tasty.Hedgehog (testProperty)
|
||
|
||
|
||
source :: MonadGen m => Range.Range Int -> m Source.Source
|
||
source r = Gen.frequency [ (1, empty), (20, nonEmpty) ] where
|
||
empty = pure mempty
|
||
nonEmpty = Source.fromUTF8 <$> Gen.utf8 r (Gen.frequency [ (1, pure '\r'), (1, pure '\n'), (20, Gen.unicode) ])
|
||
|
||
testTree :: Tasty.TestTree
|
||
testTree = Tasty.testGroup "Data.Source"
|
||
[ Tasty.testGroup "lineRanges"
|
||
[ testProperty "produces 1 more range than there are newlines" . property $ do
|
||
source <- forAll (source (Range.linear 0 100))
|
||
summarize source
|
||
length (Source.lineRanges source) === length (Text.splitOn "\r\n" (Source.toText source) >>= Text.splitOn "\r" >>= Text.splitOn "\n")
|
||
|
||
, testProperty "produces exhaustive ranges" . property $ do
|
||
source <- forAll (source (Range.linear 0 100))
|
||
summarize source
|
||
foldMap (Source.slice source) (Source.lineRanges source) === source
|
||
]
|
||
|
||
, Tasty.testGroup "totalSpan"
|
||
[ testProperty "covers single lines" . property $ do
|
||
n <- forAll $ Gen.int (Range.linear 0 100)
|
||
Source.totalSpan (Source.fromText (Text.replicate n "*")) === Span (Pos 1 1) (Pos 1 (max 1 (succ n)))
|
||
|
||
, testProperty "covers multiple lines" . property $ do
|
||
n <- forAll $ Gen.int (Range.linear 0 100)
|
||
Source.totalSpan (Source.fromText (Text.intersperse '\n' (Text.replicate n "*"))) === Span (Pos 1 1) (Pos (max 1 n) (if n > 0 then 2 else 1))
|
||
]
|
||
|
||
, Tasty.testGroup "newlineIndices"
|
||
[ testCase "finds \\n" $ Source.newlineIndices "a\nb" @?= [1]
|
||
, testCase "finds \\r" $ Source.newlineIndices "a\rb" @?= [1]
|
||
, testCase "finds \\r\\n" $ Source.newlineIndices "a\r\nb" @?= [2]
|
||
, testCase "finds intermixed line endings" $ Source.newlineIndices "hi\r}\r}\n xxx \r a" @?= [2, 4, 6, 12]
|
||
]
|
||
]
|
||
|
||
summarize :: Source.Source -> PropertyT IO ()
|
||
summarize src = do
|
||
let lines = Source.lines src
|
||
-- FIXME: this should be using cover (reverted in 1b427b995), but that leads to flaky tests: hedgehog’s 'cover' implementation fails tests instead of warning, and currently has no equivalent to 'checkCoverage'.
|
||
classify "empty" $ Source.null src
|
||
classify "single-line" $ length lines == 1
|
||
classify "multiple lines" $ length lines > 1
|