2016-07-13 21:32:53 +03:00
{- # LANGUAGE DataKinds # -}
2016-05-17 20:09:14 +03:00
module DiffSummarySpec where
2016-05-16 21:43:53 +03:00
2016-05-26 20:40:54 +03:00
import Prologue
2016-06-17 20:33:50 +03:00
import Data.Record
2016-05-16 21:43:53 +03:00
import Test.Hspec
2016-05-17 22:59:07 +03:00
import Diff
import Info
import Syntax
2016-07-14 20:01:16 +03:00
import Term
2016-05-17 20:09:14 +03:00
import Patch
2016-05-17 22:59:07 +03:00
import Range
import Category
2016-05-16 21:43:53 +03:00
import DiffSummary
2016-07-13 21:32:53 +03:00
import Text.PrettyPrint.Leijen.Text ( pretty )
import Test.Hspec.QuickCheck
import Interpreter
2016-07-14 18:52:40 +03:00
import Diff.Arbitrary
2016-07-13 21:32:53 +03:00
import Text.Megaparsec.Text
import Text.Megaparsec
2016-07-14 20:01:16 +03:00
import Data.List ( partition )
2016-05-17 20:09:14 +03:00
2016-05-17 22:59:07 +03:00
arrayInfo :: Info
2016-06-17 20:33:50 +03:00
arrayInfo = rangeAt 0 .: ArrayLiteral .: 2 .: 0 .: RNil
2016-05-17 22:59:07 +03:00
literalInfo :: Info
2016-06-17 20:33:50 +03:00
literalInfo = rangeAt 1 .: StringLiteral .: 1 .: 0 .: RNil
2016-05-17 22:59:07 +03:00
2016-06-10 23:42:11 +03:00
testDiff :: Diff Text Info
2016-05-17 22:59:07 +03:00
testDiff = free $ Free ( pure arrayInfo :< Indexed [ free $ Pure ( Insert ( cofree $ literalInfo :< Leaf " a " ) ) ] )
2016-05-31 23:15:40 +03:00
testSummary :: DiffSummary DiffInfo
2016-07-15 02:35:23 +03:00
testSummary = DiffSummary { patch = Insert ( DiffInfo " string " " a " ) , parentAnnotations = [] , patchAnnotations = [] }
2016-05-17 20:09:14 +03:00
2016-05-31 23:15:40 +03:00
replacementSummary :: DiffSummary DiffInfo
2016-07-15 02:35:23 +03:00
replacementSummary = DiffSummary { patch = Replace ( DiffInfo " string " " a " ) ( DiffInfo " symbol " " b " ) , parentAnnotations = [ ArrayLiteral ] , patchAnnotations = [] }
2016-05-18 17:24:08 +03:00
2016-05-17 20:09:14 +03:00
spec :: Spec
spec = parallel $ do
2016-05-17 22:59:07 +03:00
describe " diffSummary " $ do
it " outputs a diff summary " $ do
2016-07-15 02:35:23 +03:00
diffSummary testDiff ` shouldBe ` [ DiffSummary { patch = Insert ( DiffInfo " string " " a " ) , parentAnnotations = [ ArrayLiteral ] , patchAnnotations = [] } ]
2016-05-17 20:09:14 +03:00
describe " show " $ do
it " should print adds " $
2016-07-13 18:58:43 +03:00
show ( pretty testSummary ) ` shouldBe ` ( " Added the 'a' string " :: Text )
2016-05-18 17:24:08 +03:00
it " prints a replacement " $ do
2016-07-13 18:58:43 +03:00
show ( pretty replacementSummary ) ` shouldBe ` ( " Replaced the 'a' string with the 'b' symbol in the array context " :: Text )
2016-07-15 02:35:23 +03:00
prop " patches in summaries match the patches in diffs " $
2016-07-14 18:52:40 +03:00
\ a -> let
2016-07-15 02:35:23 +03:00
diff = ( toDiff ( a :: ArbitraryDiff Text ( Record '[Category, Cost] ) ) )
2016-07-14 20:01:16 +03:00
summaries = diffSummary diff
patches = toList diff
isIndexedOrFixed :: Patch ( Term a annotation ) -> Bool
isIndexedOrFixed patch = case unwrap <$> patch of
( Insert syntax ) -> isIndexedOrFixed' syntax
( Delete syntax ) -> isIndexedOrFixed' syntax
( Replace s1 s2 ) -> isIndexedOrFixed' s1 || isIndexedOrFixed' s2
2016-07-14 21:38:46 +03:00
isIndexedOrFixed' syntax = case syntax of
2016-07-14 20:01:16 +03:00
( Indexed _ ) -> True
( Fixed _ ) -> True
_ -> False
2016-07-15 02:35:23 +03:00
isBranchNode :: DiffSummary DiffInfo -> Bool
isBranchNode summary = ( not . null $ patchAnnotations summary ) || ( case patch summary of
( Insert diffInfo ) -> termName diffInfo == " branch "
( Delete diffInfo ) -> termName diffInfo == " branch "
( Replace i1 i2 ) -> termName i1 == " branch " || termName i2 == " branch " )
2016-07-14 20:01:16 +03:00
in
2016-07-15 02:35:23 +03:00
case ( partition isBranchNode summaries , partition isIndexedOrFixed patches ) of
2016-07-14 21:38:46 +03:00
( ( branchSummaries , otherSummaries ) , ( branchPatches , otherPatches ) ) ->
2016-07-15 02:35:23 +03:00
( ( () <$ ) . patch <$> branchSummaries , ( () <$ ) . patch <$> otherSummaries ) ` shouldBe ` ( ( () <$ ) <$> branchPatches , ( () <$ ) <$> otherPatches )
2016-07-14 20:01:16 +03:00
2016-07-15 02:35:23 +03:00
-- ((() <$) <$> (patch <$> summaries)) `shouldBe` ((() <$) <$> patches)
-- [Insert (), Insert ()] == [ Insert () ]
-- explodePatch :: Patch (Syntax a) -> [Patch (Syntax a)]
-- explodePatch Indexed = explodePatch <$> children
2016-07-13 21:32:53 +03:00
2016-07-15 02:35:23 +03:00
-- Patches of branch nodes with children should have a summary for each child that is not a branch node
-- Patches of branch nodes with children that are branch nodes shoudl have a summary for each of those children or one summary per branch if the branches are empty
-- let xs = ArbitraryPure (Insert (ArbitraryTerm {annotation = Category.Operator .: RNil, syntax = Indexed [ArbitraryTerm {annotation = Program .: RNil, syntax = Leaf ""}]}))
-- let xs = ArbitraryPure (Delete (ArbitraryTerm {annotation = Category.Case .: RNil, syntax = Fixed [ArbitraryTerm {annotation = Category.FunctionCall .: RNil, syntax = Leaf ""}]})) :: ArbitraryDiff Text (Record '[Category])
-- ((() <$) . patch <$> summaries) `shouldBe` ((() <$) <$> otherPatches)