staversion-0.2.1.0: test/Staversion/Internal/FormatSpec.hs
module Staversion.Internal.FormatSpec (main,spec) where
import Data.Monoid ((<>))
import Data.Text (pack)
import qualified Data.Text.Lazy as TL
import Test.Hspec
import Staversion.Internal.Aggregate (aggOr, Aggregator, aggregateResults)
import Staversion.Internal.Format
( formatAggregatedResults,
FormatConfig(..),
formatVersionCabal,
formatVersionCabalCaret,
)
import Staversion.Internal.Log (LogEntry)
import Staversion.Internal.Query
( PackageSource(..), Query(..),
Resolver, PackageName
)
import Staversion.Internal.Result
( Result(..), ResultBody, ResultBody'(..), ResultSource(..),
singletonResult
)
import Staversion.Internal.Cabal (Target(..))
import Staversion.Internal.TestUtil
( ver, simpleResultBody, verPairs,
vthis, vors', vint
)
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
spec_simple
spec_aggregate
spec_formatVersionCabalCaret
-- | for backward-compatibility.
formatResultsCabal :: [Result] -> TL.Text
formatResultsCabal = formatAggregatedResults fconf . map singletonResult where
fconf = FormatConfig { fconfFormatVersion = formatVersionCabal
}
-- | for backward-compatibility.
formatResultsCabalAggregated :: Aggregator -> [Result] -> (TL.Text, [LogEntry])
formatResultsCabalAggregated agg = mapFirst (formatAggregatedResults fconf) . aggregateResults agg where
fconf = FormatConfig { fconfFormatVersion = formatVersionCabal
}
mapFirst f (a, b) = (f a, b)
spec_simple :: Spec
spec_simple = describe "formatAggregatedResults" $ do
it "should return empty text for empty list" $ do
formatResultsCabal [] `shouldBe` ""
it "should format a Result in a Cabal way" $ do
let input = [ Result { resultIn = ResultSource (SourceStackage "lts-6.10") (Just $ SourceStackage "lts-6.10"),
resultFor = QueryName "hoge",
resultBody = Right $ simpleResultBody "hoge" [3,4,5]
}
]
expected = ( "------ lts-6.10\n"
<> "hoge ==3.4.5\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should group Results by PackageSource with preserved order" $ do
let input = [ simpleResult "source_c" "hoge" [0,5,7],
simpleResult "source_a" "hoge" [1,0,0],
simpleResult "source_b" "foobar" [0,2,5,3],
simpleResult "source_b" "hoge" [1,2,0],
simpleResult "source_a" "quux" [300,5],
simpleResult "source_a" "foobar" [0,3,2],
simpleResult "source_b" "quux" [299,10]
]
expected = ( "------ source_c\n"
<> "hoge ==0.5.7\n"
<> "\n"
<> "------ source_a\n"
<> "hoge ==1.0.0,\n"
<> "quux ==300.5,\n"
<> "foobar ==0.3.2\n"
<> "\n"
<> "------ source_b\n"
<> "foobar ==0.2.5.3,\n"
<> "hoge ==1.2.0,\n"
<> "quux ==299.10\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should group Results by PackageSource with preserved order (2)" $ do
let input = [ simpleResult "lts-5.0" "pack-A" [1,0],
simpleResult "lts-5.0" "pack-A" [2,0],
simpleResult "lts-6.6" "pack-A" [3,0],
simpleResult "lts-6.6" "pack-A" [4,0],
simpleResult "lts-8.0" "pack-A" [5,0],
simpleResult "lts-6.6" "pack-A" [6,0],
simpleResult "lts-6.6" "pack-A" [7,0]
]
expected = ( "------ lts-5.0\n"
<> "pack-A ==1.0,\n"
<> "pack-A ==2.0\n"
<> "\n"
<> "------ lts-6.6\n"
<> "pack-A ==3.0,\n"
<> "pack-A ==4.0,\n"
<> "pack-A ==6.0,\n"
<> "pack-A ==7.0\n"
<> "\n"
<> "------ lts-8.0\n"
<> "pack-A ==5.0\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should not put comma at the last non-N/A entry even if it is followed by N/A entries" $ do
let input = [ simpleResult "s" "hoge" [1,0,0],
simpleResult "s" "not-found-1" [],
simpleResult "s" "foobar" [2,0,0],
simpleResult "s" "not-found-2" [],
simpleResult "s" "not-found-3" []
]
expected = ( "------ s\n"
<> "hoge ==1.0.0,\n"
<> "-- not-found-1 N/A,\n"
<> "foobar ==2.0.0\n"
<> "-- not-found-2 N/A,\n"
<> "-- not-found-3 N/A\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should output resultReallyIn field" $ do
let input = [ Result { resultIn = ResultSource (SourceStackage "lts") (Just $ SourceStackage "lts-7.4"),
resultFor = QueryName "foobar",
resultBody = Right $ simpleResultBody "foobar" [3,4,5]
} ]
expected = ( "------ lts (lts-7.4)\n"
<> "foobar ==3.4.5\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should show ERROR if resultBody is Left, resultFor is QueryName" $ do
let input = [ Result { resultIn = ResultSource (SourceStackage "lts-4.2") Nothing,
resultFor = QueryName "hogehoge",
resultBody = Left "some error"
} ]
expected = ( "------ lts-4.2\n"
<> "-- hogehoge ERROR\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should show ERROR if resultBody is Left, resultFor is QueryCabalFile" $ do
let input = [ Result { resultIn = ResultSource (SourceStackage "lts-5.3") (Just $ SourceStackage "lts-5.3"),
resultFor = QueryCabalFile "foobar.cabal",
resultBody = Left "some error"
},
Result { resultIn = ResultSource (SourceStackage "lts-5.3") (Just $ SourceStackage "lts-5.3"),
resultFor = QueryName "hoge",
resultBody = Right $ simpleResultBody "hoge" [5,5]
}
]
expected = ( "------ lts-5.3\n"
<> "-- foobar.cabal ERROR\n"
<> "\n"
<> "hoge ==5.5\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should show build-depends blocks for CabalResultBody" $ do
let mkRet = cabalResult "lts-7.0" "hoge.cabal"
input = [ mkRet TargetLibrary [ ("base", [4,6,0,0]),
("foobar", [5,7])
],
mkRet (TargetExecutable "hoge-exe") [ ("bytestring", [1,9]) ],
mkRet (TargetTestSuite "hoge-test") [ ("hspec", [10,8,9]),
("QuickCheck", [5,4,2]),
("unknown", [])
],
mkRet (TargetBenchmark "hoge-bench") [ ("base", [4,8,0,4]),
("quux", []),
("parsec", [3,0,2])
]
]
expected = ( "------ lts-7.0\n"
<> "-- hoge.cabal - library\n"
<> "base ==4.6.0.0,\n"
<> "foobar ==5.7\n"
<> "\n"
<> "-- hoge.cabal - executable hoge-exe\n"
<> "bytestring ==1.9\n"
<> "\n"
<> "-- hoge.cabal - test-suite hoge-test\n"
<> "hspec ==10.8.9,\n"
<> "QuickCheck ==5.4.2\n"
<> "-- unknown N/A\n"
<> "\n"
<> "-- hoge.cabal - benchmark hoge-bench\n"
<> "base ==4.8.0.4,\n"
<> "-- quux N/A,\n"
<> "parsec ==3.0.2\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
it "should show mixed blocks and lines" $ do
let input = [ simpleResult "lts-5.0" "pack-A" [4,5],
simpleResult "lts-5.0" "pack-B" [7,7],
cabalResult "lts-5.0" "X.cabal" TargetLibrary [("pack-A", [4,5,1]), ("pack-B", [6,0])],
cabalResult "lts-5.0" "X.cabal" (TargetExecutable "X-exe") [("pack-A", []), ("pack-B", [6,6]), ("pack-C", [0,10])],
cabalResult "lts-6.6" "Y.cabal" TargetLibrary [("pack-C", [9,99,0])],
simpleResult "lts-6.6" "pack-A" [],
simpleResult "lts-7.2" "pack-B" [8,4],
cabalResult "lts-6.6" "Y.cabal" (TargetTestSuite "X-test") [("pack-D", [1,0]), ("pack-A", [5,0]), ("pack-C", []), ("pack-B", [6,5])]
]
expected = ( "------ lts-5.0\n"
<> "pack-A ==4.5,\n"
<> "pack-B ==7.7\n"
<> "\n"
<> "-- X.cabal - library\n"
<> "pack-A ==4.5.1,\n"
<> "pack-B ==6.0\n"
<> "\n"
<> "-- X.cabal - executable X-exe\n"
<> "-- pack-A N/A,\n"
<> "pack-B ==6.6,\n"
<> "pack-C ==0.10\n"
<> "\n"
<> "------ lts-6.6\n"
<> "-- Y.cabal - library\n"
<> "pack-C ==9.99.0\n"
<> "\n"
<> "-- pack-A N/A\n"
<> "\n"
<> "-- Y.cabal - test-suite X-test\n"
<> "pack-D ==1.0,\n"
<> "pack-A ==5.0,\n"
<> "-- pack-C N/A,\n"
<> "pack-B ==6.5\n"
<> "\n"
<> "------ lts-7.2\n"
<> "pack-B ==8.4\n"
<> "\n"
)
formatResultsCabal input `shouldBe` expected
spec_aggregate :: Spec
spec_aggregate = describe "formatAggregatedResults" $ do
it "should aggregate Results over multiple package sources" $ do
let input = [ simpleResult "lts-4.2" "hoge" [1,2,3],
simpleResult "lts-5.0" "hoge" [1,5]
]
expected = ( "------ lts-4.2, lts-5.0\n"
<> "hoge ==1.2.3 || ==1.5\n"
<> "\n"
)
formatResultsCabalAggregated aggOr input `shouldBe` (expected, [])
it "should show resultReallyIn in the header" $ do
let input = [ setRealSource "lts-4.22" $ simpleResult "lts-4" "foobar" [2,3],
hackageResult "foobar" [2,3,10],
simpleResult "lts-5.3" "foobar" [2,3,4]
]
expected = ( "------ lts-4 (lts-4.22), latest in hackage, lts-5.3\n"
<> "foobar ==2.3 || ==2.3.4 || ==2.3.10\n"
<> "\n"
)
formatResultsCabalAggregated aggOr input `shouldBe` (expected, [])
simpleResult :: Resolver -> PackageName -> [Int] -> Result
simpleResult res name vs = Result { resultIn = ResultSource (SourceStackage res) (Just $ SourceStackage res),
resultFor = QueryName name,
resultBody = Right $ simpleResultBody name vs
}
hackageResult :: PackageName -> [Int] -> Result
hackageResult name vs = Result { resultIn = ResultSource SourceHackage (Just SourceHackage),
resultFor = QueryName name,
resultBody = Right $ simpleResultBody name vs
}
cabalResult :: Resolver -> FilePath -> Target -> [(PackageName, [Int])] -> Result
cabalResult res file target vps =
Result { resultIn = ResultSource (SourceStackage res) (Just $ SourceStackage res),
resultFor = QueryCabalFile file,
resultBody = Right $ CabalResultBody file target $ verPairs vps
}
setRealSource :: Resolver -> Result -> Result
setRealSource resolver ret = ret { resultIn = rin { resultSourceReal = Just $ SourceStackage resolver } } where
rin = resultIn ret
spec_formatVersionCabalCaret :: Spec
spec_formatVersionCabalCaret = describe "formatVersionCabalCaret" $ do
specify "single" $ do
formatVersionCabalCaret (vthis [1,0,0]) `shouldBe` "==1.0.0"
specify "or equals" $ do
formatVersionCabalCaret (vors' [vthis [1,0,0], vthis [1,0,5,6]]) `shouldBe` "==1.0.0 || ==1.0.5.6"
specify "caret" $ do
formatVersionCabalCaret (vint [1,2,3,4] [1,3]) `shouldBe` "^>=1.2.3.4"
specify "caret or" $ do
formatVersionCabalCaret (vors' [vint [1] [1,1], vint [2,0,3] [2,1]]) `shouldBe` "^>=1 || ^>=2.0.3"
specify "mixed" $ do
formatVersionCabalCaret (vors' [vint [1,2,0,4] [1,2,3], vint [2,0] [2,1], vint [3,0,4,5] [3,1]])
`shouldBe` ">=1.2.0.4 && <1.2.3 || ^>=2.0 || ^>=3.0.4.5"