simplify types, make changed char have new format

This commit is contained in:
Evgeny Poberezkin 2023-10-02 21:54:56 +01:00
parent 7c73a44a51
commit ef02b27bca
4 changed files with 340 additions and 484 deletions

View File

@ -17,7 +17,7 @@ import qualified Data.Attoparsec.Text as A
import Data.Char (isDigit) import Data.Char (isDigit)
import Data.Either (fromRight) import Data.Either (fromRight)
import Data.Functor (($>)) import Data.Functor (($>))
import Data.List (intercalate, foldl') import Data.List (foldl', intercalate)
import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as L import qualified Data.List.NonEmpty as L
import Data.Maybe (fromMaybe, isNothing) import Data.Maybe (fromMaybe, isNothing)
@ -51,8 +51,16 @@ data Format
| SimplexLink {linkType :: SimplexLinkType, simplexUri :: Text, trustedUri :: Bool, smpHosts :: NonEmpty Text} | SimplexLink {linkType :: SimplexLinkType, simplexUri :: Text, trustedUri :: Bool, smpHosts :: NonEmpty Text}
| Email | Email
| Phone | Phone
| Edited EditAction Format
deriving (Eq, Show, Generic) deriving (Eq, Show, Generic)
data EditAction = EAInsert | EADelete | EAChangeFormat
deriving (Eq, Show, Generic)
instance ToJSON EditAction where
toJSON = J.genericToJSON . enumJSON $ dropPrefix "EA"
toEncoding = J.genericToEncoding . enumJSON $ dropPrefix "EA"
data SimplexLinkType = XLContact | XLInvitation | XLGroup data SimplexLinkType = XLContact | XLInvitation | XLGroup
deriving (Eq, Show, Generic) deriving (Eq, Show, Generic)
@ -129,7 +137,7 @@ parseMaybeMarkdownList s
| otherwise = Just . reverse $ foldl' acc [] ml | otherwise = Just . reverse $ foldl' acc [] ml
where where
ml = intercalate ["\n"] . map (markdownToList . parseMarkdown) $ T.lines s ml = intercalate ["\n"] . map (markdownToList . parseMarkdown) $ T.lines s
acc [] m = [m] acc [] m = [m]
acc ms@(FormattedText f t : ms') ft@(FormattedText f' t') acc ms@(FormattedText f t : ms') ft@(FormattedText f' t')
| f == f' = FormattedText f (t <> t') : ms' | f == f' = FormattedText f (t <> t') : ms'
| otherwise = ft : ms | otherwise = ft : ms
@ -170,14 +178,14 @@ markdownP = mconcat <$> A.many' fragmentP
md :: Char -> Format -> Text -> Markdown md :: Char -> Format -> Text -> Markdown
md c f s md c f s
| T.null s || T.head s == ' ' || T.last s == ' ' = | T.null s || T.head s == ' ' || T.last s == ' ' =
unmarked $ c `T.cons` s `T.snoc` c unmarked $ c `T.cons` s `T.snoc` c
| otherwise = markdown f s | otherwise = markdown f s
secretP :: Parser Markdown secretP :: Parser Markdown
secretP = secret <$> A.takeWhile (== '#') <*> A.takeTill (== '#') <*> A.takeWhile (== '#') secretP = secret <$> A.takeWhile (== '#') <*> A.takeTill (== '#') <*> A.takeWhile (== '#')
secret :: Text -> Text -> Text -> Markdown secret :: Text -> Text -> Text -> Markdown
secret b s a secret b s a
| T.null a || T.null s || T.head s == ' ' || T.last s == ' ' = | T.null a || T.null s || T.head s == ' ' || T.last s == ' ' =
unmarked $ '#' `T.cons` ss unmarked $ '#' `T.cons` ss
| otherwise = markdown Secret $ T.init ss | otherwise = markdown Secret $ T.init ss
where where
ss = b <> s <> a ss = b <> s <> a
@ -218,8 +226,8 @@ markdownP = mconcat <$> A.many' fragmentP
wordMD s wordMD s
| T.null s = unmarked s | T.null s = unmarked s
| isUri s = case strDecode $ encodeUtf8 s of | isUri s = case strDecode $ encodeUtf8 s of
Right cReq -> markdown (simplexUriFormat cReq) s Right cReq -> markdown (simplexUriFormat cReq) s
_ -> markdown Uri s _ -> markdown Uri s
| isEmail s = markdown Email s | isEmail s = markdown Email s
| otherwise = unmarked s | otherwise = unmarked s
isUri s = T.length s >= 10 && any (`T.isPrefixOf` s) ["http://", "https://", "simplex:/"] isUri s = T.length s >= 10 && any (`T.isPrefixOf` s) ["http://", "https://", "simplex:/"]

View File

@ -7,12 +7,8 @@
module Simplex.Chat.MarkdownDiff module Simplex.Chat.MarkdownDiff
( DiffChar (..), ( DiffChar (..),
DiffPlainChar (..), DiffPlainChar (..),
DiffStatus (..),
DiffPlainStatus (..),
DiffFormatStatus (..), DiffFormatStatus (..),
FormatChar (..), FormatChar (..),
LeftSide (..),
RightSide (..),
diff, diff,
plainDiff, plainDiff,
) )
@ -20,34 +16,22 @@ where
import qualified Data.Diff.Myers as D import qualified Data.Diff.Myers as D
import qualified Data.Foldable as F import qualified Data.Foldable as F
import Data.Function ((&)) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
import Data.Sequence (Seq (..), (><)) import Data.Sequence (Seq (..), (><))
import qualified Data.Sequence as S import qualified Data.Sequence as S
import qualified Data.Text as T import qualified Data.Text as T
import Simplex.Chat.Markdown (Format) import Simplex.Chat.Markdown (EditAction (..), Format)
data DiffStatus
= UnchangedChar DiffFormatStatus
| Inserted
| Deleted
deriving (Show, Eq)
data DiffPlainStatus
= UnchangedP
| InsertedP
| DeletedP
deriving (Show, Eq)
data DiffFormatStatus data DiffFormatStatus
= UnchangedFormat = UnchangedFormat
| ChangedToFormat (Maybe Format) | ChangedToFormat (Maybe Format)
deriving (Show, Eq) deriving (Show, Eq)
data DiffChar = DiffChar FormatChar DiffStatus data DiffChar = DiffChar FormatChar (Maybe EditAction)
deriving (Show, Eq) deriving (Show, Eq)
data DiffPlainChar = DiffPlainChar Char DiffPlainStatus data DiffPlainChar = DiffPlainChar Char (Maybe EditAction)
deriving (Show, Eq) deriving (Show, Eq)
data FormatChar = FormatChar data FormatChar = FormatChar
@ -56,48 +40,44 @@ data FormatChar = FormatChar
} }
deriving (Show, Eq) deriving (Show, Eq)
newtype LeftSide a = LeftSide a deriving (Show, Eq) newtype DeleteIndices = DeleteIndices (Seq Int) deriving (Show, Eq)
newtype RightSide a = RightSide a deriving (Show, Eq) newtype InsertIndices = InsertIndices (Seq Int) deriving (Show, Eq)
newtype DeleteIndicies = DeleteIndicies (Seq Int) deriving (Show, Eq) plainDiff :: T.Text -> T.Text -> Seq DiffPlainChar
plainDiff left right = toPlain <$> formattedDiff
newtype InsertIndicies = InsertIndicies (Seq Int) deriving (Show, Eq)
plainDiff :: LeftSide T.Text -> RightSide T.Text -> Seq DiffPlainChar
plainDiff (LeftSide left) (RightSide right) = toPlain <$> formattedDiff
where where
formattedDiff = diff (LeftSide $ toFormatted left) (RightSide $ toFormatted right) formattedDiff = diff (toFormatted left) (toFormatted right)
toPlain :: DiffChar -> DiffPlainChar toPlain :: DiffChar -> DiffPlainChar
toPlain (DiffChar (FormatChar c _) diffStatus) = DiffPlainChar c diffStatusPlain toPlain (DiffChar (FormatChar c _) editAction) = DiffPlainChar c editActionPlain
where where
diffStatusPlain = case diffStatus of editActionPlain = case editAction of
UnchangedChar _ -> UnchangedP Just EAInsert -> Just EAInsert
Inserted -> InsertedP Just EADelete -> Just EADelete
Deleted -> DeletedP Just EAChangeFormat -> Nothing
Nothing -> Nothing
toFormatted :: T.Text -> Seq FormatChar toFormatted :: T.Text -> Seq FormatChar
toFormatted = fmap (`FormatChar` Nothing) . S.fromList . T.unpack toFormatted = fmap (`FormatChar` Nothing) . S.fromList . T.unpack
diff :: LeftSide (Seq FormatChar) -> RightSide (Seq FormatChar) -> Seq DiffChar diff :: Seq FormatChar -> Seq FormatChar -> Seq DiffChar
diff (LeftSide left) (RightSide right) = addInserts markDeletesAndUnchangedChars diff left right = addInserts markDeletesAndUnchangedChars
where where
edits = D.diffTexts (toText left) (toText right) edits = D.diffTexts (toText left) (toText right)
(DeleteIndicies deleteIndicies, InsertIndicies insertIndicies) = indices (DeleteIndices deleteIndicies, InsertIndices insertIndicies) = indices
toText :: Seq FormatChar -> T.Text toText :: Seq FormatChar -> T.Text
toText = T.pack . F.toList . fmap char toText = T.pack . F.toList . fmap char
indices :: (DeleteIndicies, InsertIndicies) indices :: (DeleteIndices, InsertIndices)
indices = F.foldl' f (DeleteIndicies S.empty, InsertIndicies S.empty) edits indices = F.foldl' f (DeleteIndices S.empty, InsertIndices S.empty) edits
where where
f :: (DeleteIndicies, InsertIndicies) -> D.Edit -> (DeleteIndicies, InsertIndicies) f :: (DeleteIndices, InsertIndices) -> D.Edit -> (DeleteIndices, InsertIndices)
f (x@(DeleteIndicies ds), y@(InsertIndicies is)) e = case e of f (x@(DeleteIndices ds), y@(InsertIndices is)) e = case e of
D.EditDelete m n -> (x', y) where x' = DeleteIndicies $ ds >< S.fromList [m .. n] D.EditDelete m n -> (x', y) where x' = DeleteIndices $ ds >< S.fromList [m .. n]
D.EditInsert _ m n -> (x, y') where y' = InsertIndicies $ is >< S.fromList [m .. n] D.EditInsert _ m n -> (x, y') where y' = InsertIndices $ is >< S.fromList [m .. n]
unchangedChars :: M.Map Int DiffFormatStatus -- indexed in left unchangedChars :: Map Int DiffFormatStatus -- indexed in left
unchangedChars = F.foldl' f mempty unchangedCharPairs unchangedChars = F.foldl' f mempty unchangedCharPairs
where where
unchangedCharPairs :: Seq (Int, FormatChar, FormatChar) unchangedCharPairs :: Seq (Int, FormatChar, FormatChar)
@ -105,17 +85,15 @@ diff (LeftSide left) (RightSide right) = addInserts markDeletesAndUnchangedChars
leftWithoutDeletes :: Seq (Int, FormatChar) leftWithoutDeletes :: Seq (Int, FormatChar)
leftWithoutDeletes = leftWithoutDeletes =
left S.filter (\(i, _) -> i `notElem` deleteIndicies) $
& S.zip (S.fromList [0 .. S.length left - 1]) S.zip (S.fromList [0 .. S.length left - 1]) left
& S.filter (\(i, _) -> i `notElem` deleteIndicies)
rightWithoutInserts :: Seq (Int, FormatChar) rightWithoutInserts :: Seq (Int, FormatChar)
rightWithoutInserts = rightWithoutInserts =
right S.filter (\(i, _) -> i `notElem` insertIndicies) $
& S.zip (S.fromList [0 .. S.length right - 1]) S.zip (S.fromList [0 .. S.length right - 1]) right
& S.filter (\(i, _) -> i `notElem` insertIndicies)
f :: M.Map Int DiffFormatStatus -> (Int, FormatChar, FormatChar) -> M.Map Int DiffFormatStatus f :: Map Int DiffFormatStatus -> (Int, FormatChar, FormatChar) -> Map Int DiffFormatStatus
f acc (i, FormatChar _ fL, FormatChar _ fR) = M.insert i x acc f acc (i, FormatChar _ fL, FormatChar _ fR) = M.insert i x acc
where where
x = if fL == fR then UnchangedFormat else ChangedToFormat fR x = if fL == fR then UnchangedFormat else ChangedToFormat fR
@ -127,11 +105,11 @@ diff (LeftSide left) (RightSide right) = addInserts markDeletesAndUnchangedChars
markDeletesAndUnchangedChars = S.mapWithIndex f left markDeletesAndUnchangedChars = S.mapWithIndex f left
where where
f :: Int -> FormatChar -> DiffChar f :: Int -> FormatChar -> DiffChar
f i x = f i x@(FormatChar c _)
DiffChar x $ | i `elem` deleteIndicies = DiffChar x (Just EADelete)
if i `elem` deleteIndicies | otherwise = case unchangedChars M.! i of -- should never error
then Deleted UnchangedFormat -> DiffChar x Nothing
else UnchangedChar $ unchangedChars M.! i -- should never error ChangedToFormat f' -> DiffChar (FormatChar c f') (Just EAChangeFormat)
addInserts :: Seq DiffChar -> Seq DiffChar addInserts :: Seq DiffChar -> Seq DiffChar
addInserts base = F.foldr f base edits -- start from end and work backwards, hence foldr addInserts base = F.foldr f base edits -- start from end and work backwards, hence foldr
where where
@ -150,9 +128,9 @@ diff (LeftSide left) (RightSide right) = addInserts markDeletesAndUnchangedChars
slidePastDeleteBlock x = case S.lookup x acc of slidePastDeleteBlock x = case S.lookup x acc of
Nothing -> x Nothing -> x
Just (DiffChar _ diffStatus) -> Just (DiffChar _ diffStatus) ->
if diffStatus == Deleted if diffStatus == Just EADelete
then slidePastDeleteBlock (x + 1) then slidePastDeleteBlock (x + 1)
else x else x
rightFormatChars = S.take (n - m + 1) $ S.drop m right rightFormatChars = S.take (n - m + 1) $ S.drop m right
inserts = fmap (`DiffChar` Inserted) rightFormatChars inserts = fmap (`DiffChar` Just EAInsert) rightFormatChars

View File

@ -5,7 +5,6 @@
module MarkdownDiffTests where module MarkdownDiffTests where
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
import qualified Data.Sequence as S
import Simplex.Chat.Markdown import Simplex.Chat.Markdown
import Simplex.Chat.MarkdownDiff import Simplex.Chat.MarkdownDiff
import System.Console.ANSI.Types import System.Console.ANSI.Types
@ -17,449 +16,319 @@ markdownDiffTests = do
formattedEditedTextTests :: Spec formattedEditedTextTests :: Spec
formattedEditedTextTests = describe "show edits" do formattedEditedTextTests = describe "show edits" do
it "empty no change" do it "empty no change" $
diff diff [] [] `shouldBe` []
( LeftSide $ it "no change" $
S.fromList diff [FormatChar 'H' Nothing] [FormatChar 'H' Nothing]
[] `shouldBe` [DiffChar (FormatChar 'H' Nothing) Nothing]
) it "add 1 char to empty" $
( RightSide $ diff [] [FormatChar 'H' Nothing]
S.fromList `shouldBe` [DiffChar (FormatChar 'H' Nothing) $ Just EAInsert]
[] it "del the one and only" $
) diff [FormatChar 'H' Nothing] []
`shouldBe` S.fromList `shouldBe` [DiffChar (FormatChar 'H' Nothing) $ Just EADelete]
[]
it "no change" do
diff
( LeftSide $
S.fromList
[ FormatChar 'H' Nothing
]
)
( RightSide $
S.fromList
[ FormatChar 'H' Nothing
]
)
`shouldBe` S.fromList
[ DiffChar (FormatChar 'H' Nothing) $ UnchangedChar UnchangedFormat
]
it "add 1 char to empty" do
diff
( LeftSide $
S.fromList
[]
)
( RightSide $
S.fromList
[ FormatChar 'H' Nothing
]
)
`shouldBe` S.fromList
[ DiffChar (FormatChar 'H' Nothing) Inserted
]
it "del the one and only" do
diff
( LeftSide $
S.fromList
[ FormatChar 'H' Nothing
]
)
( RightSide $
S.fromList
[]
)
`shouldBe` S.fromList
[ DiffChar (FormatChar 'H' Nothing) Deleted
]
it "one character change" do it "one character change" do
diff diff
( LeftSide $ [ FormatChar 'H' Nothing,
S.fromList FormatChar 'r' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'l' Nothing,
FormatChar 'r' Nothing, FormatChar 'l' Nothing,
FormatChar 'l' Nothing, FormatChar 'o' Nothing
FormatChar 'l' Nothing, ]
FormatChar 'o' Nothing [ FormatChar 'H' Nothing,
] FormatChar 'e' Nothing,
) FormatChar 'l' Nothing,
( RightSide $ FormatChar 'l' Nothing,
S.fromList FormatChar 'o' Nothing
[ FormatChar 'H' Nothing, ]
FormatChar 'e' Nothing, `shouldBe` [ DiffChar (FormatChar 'H' Nothing) Nothing,
FormatChar 'l' Nothing, DiffChar (FormatChar 'r' Nothing) $ Just EADelete,
FormatChar 'l' Nothing, DiffChar (FormatChar 'e' Nothing) $ Just EAInsert,
FormatChar 'o' Nothing DiffChar (FormatChar 'l' Nothing) Nothing,
] DiffChar (FormatChar 'l' Nothing) Nothing,
) DiffChar (FormatChar 'o' Nothing) Nothing
`shouldBe` S.fromList ]
[ DiffChar (FormatChar 'H' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'r' Nothing) Deleted,
DiffChar (FormatChar 'e' Nothing) Inserted,
DiffChar (FormatChar 'l' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'l' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'o' Nothing) $ UnchangedChar UnchangedFormat
]
it "more1" do it "more1" do
diff diff
( LeftSide $ [ FormatChar 'H' Nothing,
S.fromList FormatChar 'r' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'l' Nothing,
FormatChar 'r' Nothing, FormatChar 'l' Nothing,
FormatChar 'l' Nothing, FormatChar 'o' Nothing
FormatChar 'l' Nothing, ]
FormatChar 'o' Nothing [ FormatChar 'H' Nothing,
] FormatChar 'e' Nothing,
) FormatChar 'l' Nothing,
( RightSide $ FormatChar 'l' Nothing,
S.fromList FormatChar 'o' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'x' Nothing,
FormatChar 'e' Nothing, FormatChar 'y' Nothing,
FormatChar 'l' Nothing, FormatChar 'z' Nothing
FormatChar 'l' Nothing, ]
FormatChar 'o' Nothing, `shouldBe` [ DiffChar (FormatChar 'H' Nothing) Nothing,
FormatChar 'x' Nothing, DiffChar (FormatChar 'r' Nothing) $ Just EADelete,
FormatChar 'y' Nothing, DiffChar (FormatChar 'e' Nothing) $ Just EAInsert,
FormatChar 'z' Nothing DiffChar (FormatChar 'l' Nothing) Nothing,
] DiffChar (FormatChar 'l' Nothing) Nothing,
) DiffChar (FormatChar 'o' Nothing) Nothing,
`shouldBe` S.fromList DiffChar (FormatChar 'x' Nothing) $ Just EAInsert,
[ DiffChar (FormatChar 'H' Nothing) $ UnchangedChar UnchangedFormat, DiffChar (FormatChar 'y' Nothing) $ Just EAInsert,
DiffChar (FormatChar 'r' Nothing) Deleted, DiffChar (FormatChar 'z' Nothing) $ Just EAInsert
DiffChar (FormatChar 'e' Nothing) Inserted, ]
DiffChar (FormatChar 'l' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'l' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'o' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'x' Nothing) Inserted,
DiffChar (FormatChar 'y' Nothing) Inserted,
DiffChar (FormatChar 'z' Nothing) Inserted
]
it "more2" do it "more2" do
diff diff
( LeftSide $ [ FormatChar 'H' Nothing,
S.fromList FormatChar 'r' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'l' Nothing,
FormatChar 'r' Nothing, FormatChar 'l' Nothing,
FormatChar 'l' Nothing, FormatChar 'o' Nothing
FormatChar 'l' Nothing, ]
FormatChar 'o' Nothing [ FormatChar 'H' Nothing,
] FormatChar 'e' Nothing,
) FormatChar 'x' Nothing,
( RightSide $ FormatChar 'y' Nothing,
S.fromList FormatChar 'z' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'o' Nothing
FormatChar 'e' Nothing, ]
FormatChar 'x' Nothing, `shouldBe` [ DiffChar (FormatChar 'H' Nothing) Nothing,
FormatChar 'y' Nothing, DiffChar (FormatChar 'r' Nothing) $ Just EADelete,
FormatChar 'z' Nothing, DiffChar (FormatChar 'l' Nothing) $ Just EADelete,
FormatChar 'o' Nothing DiffChar (FormatChar 'l' Nothing) $ Just EADelete,
] DiffChar (FormatChar 'e' Nothing) $ Just EAInsert,
) DiffChar (FormatChar 'x' Nothing) $ Just EAInsert,
`shouldBe` S.fromList DiffChar (FormatChar 'y' Nothing) $ Just EAInsert,
[ DiffChar (FormatChar 'H' Nothing) $ UnchangedChar UnchangedFormat, DiffChar (FormatChar 'z' Nothing) $ Just EAInsert,
DiffChar (FormatChar 'r' Nothing) Deleted, DiffChar (FormatChar 'o' Nothing) Nothing
DiffChar (FormatChar 'l' Nothing) Deleted, ]
DiffChar (FormatChar 'l' Nothing) Deleted,
DiffChar (FormatChar 'e' Nothing) Inserted,
DiffChar (FormatChar 'x' Nothing) Inserted,
DiffChar (FormatChar 'y' Nothing) Inserted,
DiffChar (FormatChar 'z' Nothing) Inserted,
DiffChar (FormatChar 'o' Nothing) $ UnchangedChar UnchangedFormat
]
it "more3" do it "more3" do
diff diff
( LeftSide $ [ FormatChar 'H' $ Just Bold,
S.fromList FormatChar 'H' $ Just Bold,
[ FormatChar 'H' $ Just Bold, FormatChar 'r' Nothing,
FormatChar 'H' $ Just Bold, FormatChar 'l' $ Just Secret,
FormatChar 'r' Nothing, FormatChar 'l' Nothing,
FormatChar 'l' $ Just Secret, FormatChar 'o' $ Just $ colored Green
FormatChar 'l' Nothing, ]
FormatChar 'o' $ Just $ colored Green [ FormatChar 'H' $ Just Italic,
] FormatChar 'H' $ Just Bold,
) FormatChar 'e' $ Just $ colored Cyan,
( RightSide $ FormatChar 'x' Nothing,
S.fromList FormatChar 'y' Nothing,
[ FormatChar 'H' $ Just Italic, FormatChar 'z' $ Just Secret,
FormatChar 'H' $ Just Bold, FormatChar 'o' $ Just $ colored Blue
FormatChar 'e' $ Just $ colored Cyan, ]
FormatChar 'x' Nothing, `shouldBe` [ DiffChar (FormatChar 'H' (Just Italic)) (Just EAChangeFormat),
FormatChar 'y' Nothing, DiffChar (FormatChar 'H' (Just Bold)) Nothing,
FormatChar 'z' $ Just Secret, DiffChar (FormatChar 'r' Nothing) $ Just EADelete,
FormatChar 'o' $ Just $ colored Blue DiffChar (FormatChar 'l' (Just Secret)) $ Just EADelete,
] DiffChar (FormatChar 'l' Nothing) $ Just EADelete,
) DiffChar (FormatChar 'e' (Just $ colored Cyan)) $ Just EAInsert,
`shouldBe` S.fromList DiffChar (FormatChar 'x' Nothing) $ Just EAInsert,
[ DiffChar (FormatChar 'H' (Just Bold)) $ UnchangedChar $ ChangedToFormat $ Just Italic, DiffChar (FormatChar 'y' Nothing) $ Just EAInsert,
DiffChar (FormatChar 'H' (Just Bold)) $ UnchangedChar UnchangedFormat, DiffChar (FormatChar 'z' (Just Secret)) $ Just EAInsert,
DiffChar (FormatChar 'r' Nothing) Deleted, DiffChar (FormatChar 'o' (Just $ colored Blue)) (Just EAChangeFormat)
DiffChar (FormatChar 'l' (Just Secret)) Deleted, ]
DiffChar (FormatChar 'l' Nothing) Deleted,
DiffChar (FormatChar 'e' (Just $ colored Cyan)) Inserted,
DiffChar (FormatChar 'x' Nothing) Inserted,
DiffChar (FormatChar 'y' Nothing) Inserted,
DiffChar (FormatChar 'z' (Just Secret)) Inserted,
DiffChar (FormatChar 'o' (Just $ colored Green)) $ UnchangedChar $ ChangedToFormat $ Just $ colored Blue
]
it "more4" do it "more4" do
diff diff
( LeftSide $ [ FormatChar 'H' Nothing,
S.fromList FormatChar 'r' Nothing,
[ FormatChar 'H' Nothing, FormatChar 'l' Nothing,
FormatChar 'r' Nothing, FormatChar '~' Nothing,
FormatChar 'l' Nothing, FormatChar '!' Nothing,
FormatChar '~' Nothing, FormatChar '@' Nothing,
FormatChar '!' Nothing, FormatChar 'l' Nothing,
FormatChar '@' Nothing, FormatChar 'o' Nothing
FormatChar 'l' Nothing, ]
FormatChar 'o' Nothing [ FormatChar 'H' Nothing,
] FormatChar 'e' Nothing,
) FormatChar 'r' Nothing,
( RightSide $ FormatChar 'x' Nothing,
S.fromList FormatChar 'y' Nothing,
[ FormatChar 'H' Nothing, FormatChar '!' Nothing,
FormatChar 'e' Nothing, FormatChar '@' Nothing,
FormatChar 'r' Nothing, FormatChar 'z' Nothing,
FormatChar 'x' Nothing, FormatChar 'o' Nothing,
FormatChar 'y' Nothing, FormatChar '1' Nothing,
FormatChar '!' Nothing, FormatChar '2' Nothing
FormatChar '@' Nothing, ]
FormatChar 'z' Nothing, `shouldBe` [ DiffChar (FormatChar 'H' Nothing) Nothing,
FormatChar 'o' Nothing, DiffChar (FormatChar 'e' Nothing) $ Just EAInsert,
FormatChar '1' Nothing, DiffChar (FormatChar 'r' Nothing) Nothing,
FormatChar '2' Nothing DiffChar (FormatChar 'l' Nothing) $ Just EADelete,
] DiffChar (FormatChar '~' Nothing) $ Just EADelete,
) DiffChar (FormatChar 'x' Nothing) $ Just EAInsert,
`shouldBe` S.fromList DiffChar (FormatChar 'y' Nothing) $ Just EAInsert,
[ DiffChar (FormatChar 'H' Nothing) $ UnchangedChar UnchangedFormat, DiffChar (FormatChar '!' Nothing) Nothing,
DiffChar (FormatChar 'e' Nothing) Inserted, DiffChar (FormatChar '@' Nothing) Nothing,
DiffChar (FormatChar 'r' Nothing) $ UnchangedChar UnchangedFormat, DiffChar (FormatChar 'l' Nothing) $ Just EADelete,
DiffChar (FormatChar 'l' Nothing) Deleted, DiffChar (FormatChar 'z' Nothing) $ Just EAInsert,
DiffChar (FormatChar '~' Nothing) Deleted, DiffChar (FormatChar 'o' Nothing) Nothing,
DiffChar (FormatChar 'x' Nothing) Inserted, DiffChar (FormatChar '1' Nothing) $ Just EAInsert,
DiffChar (FormatChar 'y' Nothing) Inserted, DiffChar (FormatChar '2' Nothing) $ Just EAInsert
DiffChar (FormatChar '!' Nothing) $ UnchangedChar UnchangedFormat, ]
DiffChar (FormatChar '@' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar 'l' Nothing) Deleted,
DiffChar (FormatChar 'z' Nothing) Inserted,
DiffChar (FormatChar 'o' Nothing) $ UnchangedChar UnchangedFormat,
DiffChar (FormatChar '1' Nothing) Inserted,
DiffChar (FormatChar '2' Nothing) Inserted
]
it "SimplexLink 1" do it "SimplexLink 1" do
diff diff
( LeftSide $ [ FormatChar '>' $
S.fromList Just $
[ FormatChar '>' $ SimplexLink
Just $ { linkType = XLContact,
SimplexLink simplexUri = "https://api.twitter.com/2/tweets/:id",
{ linkType = XLContact, trustedUri = True,
simplexUri = "https://api.twitter.com/2/tweets/:id", smpHosts = NE.fromList ["host1", "host2", "host3"]
trustedUri = True, }
smpHosts = NE.fromList ["host1", "host2", "host3"] ]
} [ FormatChar '>' $
] Just
) SimplexLink
( RightSide $ { linkType = XLContact,
S.fromList simplexUri = "https://api.twitter.com/3/tweets/:id",
[ FormatChar '>' $ trustedUri = True,
Just smpHosts = NE.fromList ["host0", "host2", "host3"]
SimplexLink }
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/3/tweets/:id", `shouldBe` [ DiffChar
trustedUri = True, ( FormatChar '>' $
smpHosts = NE.fromList ["host0", "host2", "host3"] Just
} SimplexLink
] { linkType = XLContact,
) simplexUri = "https://api.twitter.com/3/tweets/:id",
`shouldBe` S.fromList trustedUri = True,
[ DiffChar smpHosts = NE.fromList ["host0", "host2", "host3"]
( FormatChar '>' $ }
Just )
SimplexLink (Just EAChangeFormat)
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/2/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host1", "host2", "host3"]
}
)
$ UnchangedChar
$ ChangedToFormat
$ Just
SimplexLink
{ linkType = XLContact,
simplexUri = "https://api.twitter.com/3/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host0", "host2", "host3"]
}
]
it "SimplexLink 2" do it "SimplexLink 2" do
diff diff
( LeftSide $ [ FormatChar '>' $
S.fromList Just $
[ FormatChar '>' $ SimplexLink
Just $ { linkType = XLContact,
SimplexLink simplexUri = "https://api.twitter.com/2/tweets/:id",
{ linkType = XLContact, trustedUri = True,
simplexUri = "https://api.twitter.com/2/tweets/:id", smpHosts = NE.fromList ["host1", "host2", "host3"]
trustedUri = True, }
smpHosts = NE.fromList ["host1", "host2", "host3"] ]
} [ FormatChar '>' $
] Just
) SimplexLink
( RightSide $ { linkType = XLContact,
S.fromList simplexUri = "https://api.twitter.com/3/tweets/:id",
[ FormatChar '>' $ trustedUri = True,
Just smpHosts = NE.fromList ["host1", "host2", "host3"]
SimplexLink }
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/3/tweets/:id", `shouldBe` [ DiffChar
trustedUri = True, ( FormatChar '>' $
smpHosts = NE.fromList ["host1", "host2", "host3"] Just
} SimplexLink
] { linkType = XLContact,
) simplexUri = "https://api.twitter.com/3/tweets/:id",
`shouldBe` S.fromList trustedUri = True,
[ DiffChar smpHosts = NE.fromList ["host1", "host2", "host3"]
( FormatChar '>' $ }
Just )
SimplexLink (Just EAChangeFormat)
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/2/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host1", "host2", "host3"]
}
)
$ UnchangedChar
$ ChangedToFormat
$ Just
SimplexLink
{ linkType = XLContact,
simplexUri = "https://api.twitter.com/3/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host1", "host2", "host3"]
}
]
it "SimplexLink 3" do it "SimplexLink 3" do
diff diff
( LeftSide $ [ FormatChar '>' $
S.fromList Just $
[ FormatChar '>' $ SimplexLink
Just $ { linkType = XLContact,
SimplexLink simplexUri = "https://api.twitter.com/2/tweets/:id",
{ linkType = XLContact, trustedUri = True,
simplexUri = "https://api.twitter.com/2/tweets/:id", smpHosts = NE.fromList ["host1", "host2", "host3"]
trustedUri = True, }
smpHosts = NE.fromList ["host1", "host2", "host3"] ]
} [ FormatChar '>' $
] Just
) SimplexLink
( RightSide $ { linkType = XLContact,
S.fromList simplexUri = "https://api.twitter.com/2/tweets/:id",
[ FormatChar '>' $ trustedUri = True,
Just smpHosts = NE.fromList ["host0", "host2", "host3"]
SimplexLink }
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/2/tweets/:id", `shouldBe` [ DiffChar
trustedUri = True, ( FormatChar '>' $
smpHosts = NE.fromList ["host0", "host2", "host3"] Just
} SimplexLink
] { linkType = XLContact,
) simplexUri = "https://api.twitter.com/2/tweets/:id",
`shouldBe` S.fromList trustedUri = True,
[ DiffChar smpHosts = NE.fromList ["host0", "host2", "host3"]
( FormatChar '>' $ }
Just )
SimplexLink (Just EAChangeFormat)
{ linkType = XLContact, ]
simplexUri = "https://api.twitter.com/2/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host1", "host2", "host3"]
}
)
$ UnchangedChar
$ ChangedToFormat
$ Just
SimplexLink
{ linkType = XLContact,
simplexUri = "https://api.twitter.com/2/tweets/:id",
trustedUri = True,
smpHosts = NE.fromList ["host0", "host2", "host3"]
}
]
it "plainDiff 1" do it "plainDiff 1" do
plainDiff plainDiff
(LeftSide "https://api.twitter.com/2/tweets/:id") "https://api.twitter.com/2/tweets/:id"
(RightSide "https://api.twitter.com/3/tweets/:id") "https://api.twitter.com/3/tweets/:id"
`shouldBe` S.fromList `shouldBe` [ DiffPlainChar 'h' Nothing,
[ DiffPlainChar 'h' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 'p' Nothing,
DiffPlainChar 'p' UnchangedP, DiffPlainChar 's' Nothing,
DiffPlainChar 's' UnchangedP, DiffPlainChar ':' Nothing,
DiffPlainChar ':' UnchangedP, DiffPlainChar '/' Nothing,
DiffPlainChar '/' UnchangedP, DiffPlainChar '/' Nothing,
DiffPlainChar '/' UnchangedP, DiffPlainChar 'a' Nothing,
DiffPlainChar 'a' UnchangedP, DiffPlainChar 'p' Nothing,
DiffPlainChar 'p' UnchangedP, DiffPlainChar 'i' Nothing,
DiffPlainChar 'i' UnchangedP, DiffPlainChar '.' Nothing,
DiffPlainChar '.' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 'w' Nothing,
DiffPlainChar 'w' UnchangedP, DiffPlainChar 'i' Nothing,
DiffPlainChar 'i' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 'e' Nothing,
DiffPlainChar 'e' UnchangedP, DiffPlainChar 'r' Nothing,
DiffPlainChar 'r' UnchangedP, DiffPlainChar '.' Nothing,
DiffPlainChar '.' UnchangedP, DiffPlainChar 'c' Nothing,
DiffPlainChar 'c' UnchangedP, DiffPlainChar 'o' Nothing,
DiffPlainChar 'o' UnchangedP, DiffPlainChar 'm' Nothing,
DiffPlainChar 'm' UnchangedP, DiffPlainChar '/' Nothing,
DiffPlainChar '/' UnchangedP, DiffPlainChar '2' $ Just EADelete,
DiffPlainChar '2' DeletedP, DiffPlainChar '3' $ Just EAInsert,
DiffPlainChar '3' InsertedP, DiffPlainChar '/' Nothing,
DiffPlainChar '/' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 'w' Nothing,
DiffPlainChar 'w' UnchangedP, DiffPlainChar 'e' Nothing,
DiffPlainChar 'e' UnchangedP, DiffPlainChar 'e' Nothing,
DiffPlainChar 'e' UnchangedP, DiffPlainChar 't' Nothing,
DiffPlainChar 't' UnchangedP, DiffPlainChar 's' Nothing,
DiffPlainChar 's' UnchangedP, DiffPlainChar '/' Nothing,
DiffPlainChar '/' UnchangedP, DiffPlainChar ':' Nothing,
DiffPlainChar ':' UnchangedP, DiffPlainChar 'i' Nothing,
DiffPlainChar 'i' UnchangedP, DiffPlainChar 'd' Nothing
DiffPlainChar 'd' UnchangedP ]
]
it "plainDiff 2" do it "plainDiff 2" do
plainDiff plainDiff
(LeftSide "Hrl~!@lo") "Hrl~!@lo"
(RightSide "Herxy!@zo12") "Herxy!@zo12"
`shouldBe` S.fromList `shouldBe` [ DiffPlainChar 'H' Nothing,
[ DiffPlainChar 'H' UnchangedP, DiffPlainChar 'e' $ Just EAInsert,
DiffPlainChar 'e' InsertedP, DiffPlainChar 'r' Nothing,
DiffPlainChar 'r' UnchangedP, DiffPlainChar 'l' $ Just EADelete,
DiffPlainChar 'l' DeletedP, DiffPlainChar '~' $ Just EADelete,
DiffPlainChar '~' DeletedP, DiffPlainChar 'x' $ Just EAInsert,
DiffPlainChar 'x' InsertedP, DiffPlainChar 'y' $ Just EAInsert,
DiffPlainChar 'y' InsertedP, DiffPlainChar '!' Nothing,
DiffPlainChar '!' UnchangedP, DiffPlainChar '@' Nothing,
DiffPlainChar '@' UnchangedP, DiffPlainChar 'l' $ Just EADelete,
DiffPlainChar 'l' DeletedP, DiffPlainChar 'z' $ Just EAInsert,
DiffPlainChar 'z' InsertedP, DiffPlainChar 'o' Nothing,
DiffPlainChar 'o' UnchangedP, DiffPlainChar '1' $ Just EAInsert,
DiffPlainChar '1' InsertedP, DiffPlainChar '2' $ Just EAInsert
DiffPlainChar '2' InsertedP ]
]

View File

@ -5,8 +5,8 @@ import ChatTests
import ChatTests.Utils (xdescribe'') import ChatTests.Utils (xdescribe'')
import Control.Logger.Simple import Control.Logger.Simple
import Data.Time.Clock.System import Data.Time.Clock.System
import MarkdownTests
import MarkdownDiffTests import MarkdownDiffTests
import MarkdownTests
import MobileTests import MobileTests
import ProtocolTests import ProtocolTests
import SchemaDump import SchemaDump
@ -21,6 +21,7 @@ main = do
withGlobalLogging logCfg . hspec $ do withGlobalLogging logCfg . hspec $ do
describe "Schema dump" schemaDumpTest describe "Schema dump" schemaDumpTest
describe "SimpleX chat markdown" markdownTests describe "SimpleX chat markdown" markdownTests
fdescribe "SimpleX chat markdown diff" markdownDiffTests
describe "SimpleX chat view" viewTests describe "SimpleX chat view" viewTests
describe "SimpleX chat protocol" protocolTests describe "SimpleX chat protocol" protocolTests
describe "WebRTC encryption" webRTCTests describe "WebRTC encryption" webRTCTests