module Main (main) where import Data.List qualified as List import Data.List.NonEmpty qualified as NonEmpty import Data.Loc import Data.Loc.Area qualified as Area import Data.Loc.Internal.Prelude import Data.Loc.List.OneToTwo qualified as OneToTwo import Data.Loc.List.ZeroToTwo qualified as ZeroToTwo import Data.Loc.Loc qualified as Loc import Data.Loc.Span qualified as Span import Gen qualified import Hedgehog import Hedgehog.Gen qualified as Gen import Hedgehog.Range qualified as Range import Test.Hspec import Test.Hspec.Hedgehog main :: IO () main = hspec do locSpec spanSpec areaSpec locSpec :: SpecWith () locSpec = describe "Loc" do specify "read and show" $ hedgehog do x <- forAll Gen.loc' read (show x) === x specify "read and show examples" $ hedgehog do show Loc.origin === "1:1" Loc.locShowsPrec minPrec (loc 3 14) "" === "3:14" readPrec_to_S Loc.locReadPrec minPrec "3:14" === [(read "3:14", "")] spanSpec :: SpecWith () spanSpec = describe "Span" do specify "joinAsc" $ hedgehog do spans <- forAll (Gen.list (Range.linear 1 10) Gen.span') areaSpansAsc (foldMap spanArea spans) === Span.joinAsc (List.sort spans) specify "read and show" $ hedgehog do x <- forAll Gen.span' read (show x) === x describe "read and show examples" do specify "show 3:14-6:5" $ Span.spanShowsPrec minPrec (Span.fromTo (read "3:14") (read "6:5")) "" == "3:14-6:5" specify "read 3:14-6:5" $ show (readPrec_to_S Span.spanReadPrec minPrec "3:14-6:5") == "[(3:14-6:5,\"\")]" specify "read 6:5-3:14" $ show (readPrec_to_S Span.spanReadPrec minPrec "6:5-3:14") == "[(3:14-6:5,\"\")]" specify "read 6:5-6:5" $ readPrec_to_S Span.spanReadPrec minPrec "6:5-6:5" == [] describe "lines" do specify "one" $ NonEmpty.toList (Span.lines (read "2:6-2:10")) == [2] specify "many" $ NonEmpty.toList (Span.lines (read "2:6-8:4")) == [2, 3, 4, 5, 6, 7, 8] describe "overlapping" do specify "if only touching, no" $ not $ Span.overlapping (read "1:5-1:8") (read "1:8-1:12") specify "on a single line" $ Span.overlapping (read "1:5-1:9") (read "1:8-1:12") specify "one contained within another" $ Span.overlapping (read "1:5-1:15") (read "1:6-1:10") specify "same span" $ hedgehog do x <- forAll Gen.span' assert (Span.overlapping x x) describe "linesOverlapping" do specify "same span" $ hedgehog do x <- forAll Gen.span' assert (Span.linesOverlapping x x) specify "multi line" $ Span.linesOverlapping (read "1:1-1:2") (read "1:1-2:1") specify "no" $ not $ Span.linesOverlapping (read "1:1-1:2") (read "2:1-2:2") describe "touching" do specify "same span" $ hedgehog do x <- forAll Gen.span' assert (Span.touching x x) specify "barely" $ Span.touching (read "1:1-1:2") (read "1:2-1:3") specify "overlapping" $ Span.touching (read "1:1-1:2") (read "1:1-1:3") specify "no" $ not $ Span.touching (read "1:1-1:2") (read "1:3-1:4") describe "join" do specify "touching" $ Span.join (read "1:1-1:2") (read "1:2-1:3") == read "1:1-1:3" specify "overlapping" $ Span.join (read "1:1-1:2") (read "1:1-1:3") == read "1:1-1:3" describe "addition" do specify "example 1" $ read "1:1-1:2" Span.+ read "1:2-1:3" == OneToTwo.One (read "1:1-1:3") specify "example 2" $ read "1:1-1:2" Span.+ read "1:1-3:1" == OneToTwo.One (read "1:1-3:1") specify "example 3" $ read "1:1-1:2" Span.+ read "1:1-11:1" == OneToTwo.One (read "1:1-11:1") specify "example 4" $ read "1:1-1:2" Span.+ read "2:1-2:5" == OneToTwo.Two (read "1:1-1:2") (read "2:1-2:5") specify "example 5" $ read "2:1-2:5" Span.+ read "1:1-1:2" == OneToTwo.Two (read "2:1-2:5") (read "1:1-1:2") describe "subtraction" do specify "x - x" $ hedgehog do x <- forAll Gen.span' x Span.- x === ZeroToTwo.Zero specify "example 1" $ read "2:5-4:1" Span.- read "2:9-3:5" == ZeroToTwo.Two (read "2:5-2:9") (read "3:5-4:1") specify "example 2" $ read "2:5-4:1" Span.- read "2:5-3:5" == ZeroToTwo.One (read "3:5-4:1") specify "example 3" $ read "2:5-4:1" Span.- read "2:2-3:5" == ZeroToTwo.One (read "3:5-4:1") specify "example 4" $ read "2:5-4:1" Span.- read "2:2-4:4" == ZeroToTwo.Zero specify "example 5" $ read "1:1-8:1" Span.- read "1:2-8:1" == ZeroToTwo.One (read "1:1-1:2") areaSpec :: SpecWith () areaSpec = describe "Area" do specify "add mempty = id for a single span" $ hedgehog do a <- forAll Gen.span' spanArea a Area.+ mempty === spanArea a specify "subtract mempty = id for a single span" $ hedgehog do a <- forAll Gen.span' spanArea a Area.- mempty === spanArea a specify "addition is commutative" $ hedgehog do a <- forAll Gen.area' b <- forAll Gen.area' a Area.+ b === b Area.+ a specify "add mempty = id" $ hedgehog do a <- forAll Gen.area' a Area.+ mempty === a specify "subtract mempty = id" $ hedgehog do a <- forAll Gen.area' a Area.- mempty === a specify "addition and subtraction" $ hedgehog do a <- forAll Gen.area' b <- forAll Gen.area' c <- forAll Gen.area' a Area.- b Area.- c === a Area.- (b Area.+ c) specify "addSpan" $ hedgehog do a <- forAll Gen.area' s <- forAll Gen.span' Area.addSpan s a === areaUnion (spanArea s) a specify "fromTo mempty 1" $ hedgehog do x <- forAll Gen.loc' y <- forAll Gen.loc' (Area.fromTo x y == mempty) === (x == y) specify "fromTo mempty 2" $ hedgehog do x <- forAll Gen.loc' Area.fromTo x x === mempty specify "read and show" $ hedgehog do x <- forAll Gen.area' read (show x) === x specify "read and show example 1" $ hedgehog do let x = show (readPrec_to_S Area.areaReadPrec minPrec "[]") x === "[([],\"\")]" specify "read and show example 2" $ hedgehog do x <- forAll (Gen.element ["[3:2-5:5,8:3-11:4]", "[3:2-5:5,11:4-8:3]"]) let y = show (readPrec_to_S Area.areaReadPrec minPrec x) y === "[([3:2-5:5,8:3-11:4],\"\")]" specify "read and show example 3" $ hedgehog do let x = show (readPrec_to_S Area.areaReadPrec minPrec "[3:2-5:5,8:3-8:3]") x === "[]" specify "constructed from a single span" $ hedgehog do let x = read "4:5-6:3" spanArea x === read "[4:5-6:3]" specify "converted to a span, maybe" $ hedgehog do Area.areaSpan mempty === Nothing Area.areaSpan (read "[3:4-7:2]") === Just (read "3:4-7:2") Area.areaSpan (read "[3:4-7:2,15:6-17:9]") === Just (read "3:4-17:9") specify "converted to a list of spans" $ hedgehog do Area.spansAsc mempty === [] Area.spansAsc (read "[3:4-7:2,15:6-17:9]") === [read "3:4-7:2", read "15:6-17:9"] specify "spanCount" $ hedgehog do Area.spanCount mempty === 0 Area.spanCount (read "[3:4-7:2]") === 1 Area.spanCount (read "[3:4-7:2,15:6-17:9]") === 2 specify "firstSpan" $ hedgehog do Area.firstSpan mempty === Nothing Area.firstSpan (read "[3:4-7:2]") === Just (read "3:4-7:2") Area.firstSpan (read "[3:4-7:2,15:6-17:9]") === Just (read "3:4-7:2") specify "lastSpan" $ hedgehog do Area.lastSpan mempty === Nothing Area.lastSpan (read "[3:4-7:2]") === Just (read "3:4-7:2") Area.lastSpan (read "[3:4-7:2,15:6-17:9]") === Just (read "15:6-17:9") specify "start" $ hedgehog do Area.start mempty === Nothing Area.start (read "[3:4-7:2]") === Just (read "3:4") Area.start (read "[3:4-7:2,15:6-17:9]") === Just (read "3:4") specify "end" $ hedgehog do Area.end mempty === Nothing Area.end (read "[3:4-7:2]") === Just (read "7:2") Area.end (read "[3:4-7:2,15:6-17:9]") === Just (read "17:9") specify "addition examples" $ hedgehog do read "[1:1-1:2]" Area.+ mempty === read "[1:1-1:2]" read "[1:1-1:2]" Area.+ read "[1:2-1:3]" === read "[1:1-1:3]" read "[1:1-1:2]" Area.+ read "[1:1-3:1]" === read "[1:1-3:1]" read "[1:1-1:2]" Area.+ read "[1:1-11:1]" === read "[1:1-11:1]" read "[1:1-3:1,6:1-6:2]" Area.+ read "[1:1-6:1]" === read "[1:1-6:2]" read "[1:1-3:1]" Area.+ read "[5:1-6:2]" === read "[1:1-3:1,5:1-6:2]" specify "addSpan examples" $ hedgehog do Area.addSpan (read "1:1-6:1") (read "[1:1-3:1,6:1-6:2]") === read "[1:1-6:2]"