1
1
mirror of https://github.com/github/semantic.git synced 2024-12-26 08:25:19 +03:00
This commit is contained in:
Rob Rix 2017-11-21 15:56:34 -05:00
parent 4aa083332c
commit 4b07ad44ac

View File

@ -19,9 +19,11 @@ import Data.Record
import Data.Semigroup ((<>))
import qualified Data.Source as Source
import Data.SplitDiff
import qualified Data.Syntax as Syntax
import Data.Term
import qualified Data.Text as Text
import Data.These
import Data.Union
import Test.Hspec (Spec, describe, it, parallel)
import Test.Hspec.Expectations.Pretty
import Test.Hspec.LeanCheck
@ -63,13 +65,13 @@ spec = parallel $ do
describe "alignDiff" $ do
it "aligns identical branches on a single line" $
let sources = both (Source.fromText "[ foo ]") (Source.fromText "[ foo ]") in
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])
(wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])) ]
it "aligns identical branches spanning multiple lines" $
let sources = both (Source.fromText "[\nfoo\n]") (Source.fromText "[\nfoo\n]") in
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 2 `In` [])
(wrap $ info 0 2 `In` []))
, Join (These (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ])
@ -80,7 +82,7 @@ spec = parallel $ do
it "aligns reformatted branches" $
let sources = both (Source.fromText "[ foo ]") (Source.fromText "[\nfoo\n]") in
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources
[ Join (That (wrap $ info 0 2 `In` []))
, Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])
(wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ]))
@ -89,7 +91,7 @@ spec = parallel $ do
it "aligns nodes following reformatted branches" $
let sources = both (Source.fromText "[ foo ]\nbar\n") (Source.fromText "[\nfoo\n]\nbar\n") in
align sources ((info 0 12, info 0 12) `merge` [ (info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ], (info 8 11, info 8 11) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources
align sources ((info 0 12, info 0 12) `merge` [ (info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ], (info 8 11, info 8 11) `merge` inj (Syntax.Identifier "bar") ]) `shouldBe` prettyDiff sources
[ Join (That (wrap $ info 0 2 `In` [ wrap $ info 0 2 `In` [] ]))
, Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ] ])
(wrap $ info 2 6 `In` [ wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ] ]))
@ -102,12 +104,12 @@ spec = parallel $ do
it "aligns identical branches with multiple children on the same line" $
let sources = pure (Source.fromText "[ foo, bar ]") in
align sources ((info 0 12, info 0 12) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo", (info 7 10, info 7 10) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources
align sources ((info 0 12, info 0 12) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo"), (info 7 10, info 7 10) `merge` inj (Syntax.Identifier "bar") ]) `shouldBe` prettyDiff sources
[ Join (runBothWith These (pure (wrap $ info 0 12 `In` [ wrap $ info 2 5 `In` [], wrap $ info 7 10 `In` [] ])) ) ]
it "aligns insertions" $
let sources = both (Source.fromText "a") (Source.fromText "a\nb") in
align sources ((info 0 1, info 0 3) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources
align sources ((info 0 1, info 0 3) `merge` [ (info 0 1, info 0 1) `merge` inj (Syntax.Identifier "a"), inserting (termIn (info 2 3) inj (Syntax.Identifier "b")) ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 1 `In` [ wrap $ info 0 1 `In` [] ])
(wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]))
, Join (That (wrap $ info 2 3 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
@ -115,19 +117,19 @@ spec = parallel $ do
it "aligns total insertions" $
let sources = both (Source.fromText "") (Source.fromText "a") in
align sources (inserting (Term (info 0 1 `In` Leaf "a"))) `shouldBe` prettyDiff sources
align sources (inserting (Term (info 0 1 `In` Syntax.Identifier "a"))) `shouldBe` prettyDiff sources
[ Join (That (pure (SplitInsert (Term (info 0 1 `In` []))))) ]
it "aligns insertions into empty branches" $
let sources = both (Source.fromText "[ ]") (Source.fromText "[a]") in
align sources ((info 0 3, info 0 3) `merge` [ inserting (Term (info 1 2 `In` Leaf "a")) ]) `shouldBe` prettyDiff sources
align sources ((info 0 3, info 0 3) `merge` [ inserting (termIn (info 1 2) (inj (Syntax.Identifier "a"))) ]) `shouldBe` prettyDiff sources
[ Join (That (wrap $ info 0 3 `In` [ pure (SplitInsert (Term (info 1 2 `In` []))) ]))
, Join (This (wrap $ info 0 3 `In` []))
]
it "aligns symmetrically following insertions" $
let sources = both (Source.fromText "a\nc") (Source.fromText "a\nb\nc") in
align sources ((info 0 3, info 0 5) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")), (info 2 3, info 4 5) `merge` Leaf "c" ])
align sources ((info 0 3, info 0 5) `merge` [ (info 0 1, info 0 1) `merge` Syntax.Identifier "a", inserting (Term (info 2 3 `In` Syntax.Identifier "b")), (info 2 3, info 4 5) `merge` Syntax.Identifier "c" ])
`shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])
(wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]))
@ -138,13 +140,13 @@ spec = parallel $ do
it "symmetrical nodes force the alignment of asymmetrical nodes on both sides" $
let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ b, c ]") in
align sources ((info 0 8, info 0 8) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), (info 5 6, info 2 3) `merge` Leaf "b", inserting (Term (info 5 6 `In` Leaf "c")) ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ])
align sources ((info 0 8, info 0 8) `merge` [ deleting (termIn (info 2 3) (inj (Syntax.Identifier "a"))), (info 5 6, info 2 3) `merge` inj (Syntax.Identifier "b"), inserting (Term (info 5 6 `In` Syntax.Identifier "c")) ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (termIn (info 2 3) (inj []))), wrap $ info 5 6 `In` [] ])
(wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], pure (SplitInsert (Term (info 5 6 `In` []))) ])) ]
it "when one of two symmetrical nodes must be split, splits the latter" $
let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ a\n, b\n]") in
align sources ((info 0 8, info 0 9) `merge` [ (info 2 3, info 2 3) `merge` Leaf "a", (info 5 6, info 6 7) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources
align sources ((info 0 8, info 0 9) `merge` [ (info 2 3, info 2 3) `merge` inj (Syntax.Identifier "a"), (info 5 6, info 6 7) `merge` inj (Syntax.Identifier "b") ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], wrap $ info 5 6 `In` [] ])
(wrap $ info 0 4 `In` [ wrap $ info 2 3 `In` [] ]))
, Join (That (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ]))
@ -153,14 +155,14 @@ spec = parallel $ do
it "aligns deletions before insertions" $
let sources = both (Source.fromText "[ a ]") (Source.fromText "[ b ]") in
align sources ((info 0 5, info 0 5) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources
align sources ((info 0 5, info 0 5) `merge` [ deleting (termIn (info 2 3) (inj (Syntax.Identifier "a"))), inserting (termIn (info 2 3) (inj (Syntax.Identifier "b"))) ]) `shouldBe` prettyDiff sources
[ Join (This (wrap $ info 0 5 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))) ]))
, Join (That (wrap $ info 0 5 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
]
it "aligns context-only lines symmetrically" $
let sources = both (Source.fromText "[\n a\n,\n b\n]") (Source.fromText "[\n a, b\n\n\n]") in
align sources ((info 0 13, info 0 12) `merge` [ (info 4 5, info 4 5) `merge` Leaf "a", (info 10 11, info 7 8) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources
align sources ((info 0 13, info 0 12) `merge` [ (info 4 5, info 4 5) `merge` inj (Syntax.Identifier "a"), (info 10 11, info 7 8) `merge` inj (Syntax.Identifier "b") ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 2 `In` [])
(wrap $ info 0 2 `In` []))
, Join (These (wrap $ info 2 6 `In` [ wrap $ info 4 5 `In` [] ])
@ -175,7 +177,7 @@ spec = parallel $ do
it "aligns asymmetrical nodes preceding their symmetrical siblings conservatively" $
let sources = both (Source.fromText "[ b, c ]") (Source.fromText "[ a\n, c\n]") in
align sources ((info 0 8, info 0 9) `merge` [ inserting (Term (info 2 3 `In` Leaf "a")), deleting (Term (info 2 3 `In` Leaf "b")), (info 5 6, info 6 7) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources
align sources ((info 0 8, info 0 9) `merge` [ inserting (Term (info 2 3 `In` Syntax.Identifier "a")), deleting (Term (info 2 3 `In` Syntax.Identifier "b")), (info 5 6, info 6 7) `merge` Syntax.Identifier "c" ]) `shouldBe` prettyDiff sources
[ Join (That (wrap $ info 0 4 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
, Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ])
(wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ]))
@ -184,7 +186,7 @@ spec = parallel $ do
it "aligns symmetrical reformatted nodes" $
let sources = both (Source.fromText "a [ b ]\nc") (Source.fromText "a [\nb\n]\nc") in
align sources ((info 0 9, info 0 9) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", (info 2 7, info 2 7) `merge` [ (info 4 5, info 4 5) `merge` Leaf "b" ], (info 8 9, info 8 9) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources
align sources ((info 0 9, info 0 9) `merge` [ (info 0 1, info 0 1) `merge` Syntax.Identifier "a", (info 2 7, info 2 7) `merge` [ (info 4 5, info 4 5) `merge` Syntax.Identifier "b" ], (info 8 9, info 8 9) `merge` Syntax.Identifier "c" ]) `shouldBe` prettyDiff sources
[ Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 7 `In` [ wrap $ info 4 5 `In` [] ] ])
(wrap $ info 0 4 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 4 `In` [] ]))
, Join (That (wrap $ info 4 6 `In` [ wrap $ info 4 6 `In` [ wrap $ info 4 5 `In` [] ] ]))
@ -257,7 +259,7 @@ instance Listable BranchElement where
counts :: [Join These (Int, a)] -> Both Int
counts numbered = fromMaybe 0 . getLast . mconcat . fmap Last <$> Join (unalign (runJoin . fmap fst <$> numbered))
align :: Both Source.Source -> Diff Syntax (Record '[Range]) (Record '[Range]) -> PrettyDiff (SplitDiff [] (Record '[Range]))
align :: Both Source.Source -> Diff ListableSyntax (Record '[Range]) (Record '[Range]) -> PrettyDiff (SplitDiff [] (Record '[Range]))
align sources = PrettyDiff sources . fmap (fmap (getRange &&& id)) . alignDiff sources
info :: Int -> Int -> Record '[Range]