{-# LANGUAGE TemplateHaskell #-}
module ShellCheck.Formatter.Diff (format, ShellCheck.Formatter.Diff.runTests) where
import ShellCheck.Interface
import ShellCheck.Fixer
import ShellCheck.Formatter.Format
import Control.Monad
import Data.Algorithm.Diff
import Data.Array
import Data.IORef
import Data.List
import qualified Data.Monoid as Monoid
import Data.Maybe
import qualified Data.Map as M
import GHC.Exts (sortWith)
import System.IO
import System.FilePath
import Test.QuickCheck
format :: FormatterOptions -> IO Formatter
format :: FormatterOptions -> IO Formatter
format FormatterOptions
options = do
IORef Bool
foundIssues <- forall a. a -> IO (IORef a)
newIORef Bool
False
IORef Bool
reportedIssues <- forall a. a -> IO (IORef a)
newIORef Bool
False
Bool
shouldColor <- ColorOption -> IO Bool
shouldOutputColor (FormatterOptions -> ColorOption
foColorOption FormatterOptions
options)
let color :: Int -> String -> String
color = if Bool
shouldColor then forall {a}. Show a => a -> String -> String
colorize else forall {p} {a}. p -> a -> a
nocolor
forall (m :: * -> *) a. Monad m => a -> m a
return Formatter {
header :: IO ()
header = forall (m :: * -> *) a. Monad m => a -> m a
return (),
footer :: IO ()
footer = IORef Bool -> IORef Bool -> (Int -> String -> String) -> IO ()
checkFooter IORef Bool
foundIssues IORef Bool
reportedIssues Int -> String -> String
color,
onFailure :: String -> String -> IO ()
onFailure = (Int -> String -> String) -> String -> String -> IO ()
reportFailure Int -> String -> String
color,
onResult :: CheckResult -> SystemInterface IO -> IO ()
onResult = IORef Bool
-> IORef Bool
-> (Int -> String -> String)
-> CheckResult
-> SystemInterface IO
-> IO ()
reportResult IORef Bool
foundIssues IORef Bool
reportedIssues Int -> String -> String
color
}
contextSize :: Int
contextSize = Int
3
red :: Int
red = Int
31
green :: Int
green = Int
32
yellow :: Integer
yellow = Integer
33
cyan :: Int
cyan = Int
36
bold :: Int
bold = Int
1
nocolor :: p -> a -> a
nocolor p
n = forall a. a -> a
id
colorize :: a -> String -> String
colorize a
n String
s = (forall {a}. Show a => a -> String
ansi a
n) forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ (forall {a}. Show a => a -> String
ansi Integer
0)
ansi :: a -> String
ansi a
n = String
"\x1B[" forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
"m"
printErr :: ColorFunc -> String -> IO ()
printErr :: (Int -> String -> String) -> String -> IO ()
printErr Int -> String -> String
color = Handle -> String -> IO ()
hPutStrLn Handle
stderr forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
color Int
bold forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
color Int
red
reportFailure :: (Int -> String -> String) -> String -> String -> IO ()
reportFailure Int -> String -> String
color String
file String
msg = (Int -> String -> String) -> String -> IO ()
printErr Int -> String -> String
color forall a b. (a -> b) -> a -> b
$ String
file forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ String
msg
IORef Bool
foundIssues IORef Bool
reportedIssues Int -> String -> String
color = do
Bool
found <- forall a. IORef a -> IO a
readIORef IORef Bool
foundIssues
Bool
output <- forall a. IORef a -> IO a
readIORef IORef Bool
reportedIssues
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
found Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
output) forall a b. (a -> b) -> a -> b
$
(Int -> String -> String) -> String -> IO ()
printErr Int -> String -> String
color String
"Issues were detected, but none were auto-fixable. Use another format to see them."
type ColorFunc = (Int -> String -> String)
data LFStatus = LinefeedMissing | LinefeedOk
data DiffDoc a = DiffDoc String LFStatus [DiffRegion a]
data DiffRegion a = DiffRegion (Int, Int) (Int, Int) [Diff a]
reportResult :: (IORef Bool) -> (IORef Bool) -> ColorFunc -> CheckResult -> SystemInterface IO -> IO ()
reportResult :: IORef Bool
-> IORef Bool
-> (Int -> String -> String)
-> CheckResult
-> SystemInterface IO
-> IO ()
reportResult IORef Bool
foundIssues IORef Bool
reportedIssues Int -> String -> String
color CheckResult
result SystemInterface IO
sys = do
let comments :: [PositionedComment]
comments = CheckResult -> [PositionedComment]
crComments CheckResult
result
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PositionedComment]
comments) forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
foundIssues Bool
True
let suggestedFixes :: [Fix]
suggestedFixes = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe PositionedComment -> Maybe Fix
pcFix [PositionedComment]
comments
let fixmap :: Map String Fix
fixmap = [Fix] -> Map String Fix
buildFixMap [Fix]
suggestedFixes
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String, Fix) -> IO ()
output forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.toList Map String Fix
fixmap
where
output :: (String, Fix) -> IO ()
output (String
name, Fix
fix) = do
Either String String
file <- forall (m :: * -> *).
SystemInterface m
-> Maybe Bool -> String -> m (Either String String)
siReadFile SystemInterface IO
sys (forall a. a -> Maybe a
Just Bool
True) String
name
case Either String String
file of
Right String
contents -> do
String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ (Int -> String -> String) -> DiffDoc String -> String
formatDoc Int -> String -> String
color forall a b. (a -> b) -> a -> b
$ String -> String -> Fix -> DiffDoc String
makeDiff String
name String
contents Fix
fix
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
reportedIssues Bool
True
Left String
msg -> (Int -> String -> String) -> String -> String -> IO ()
reportFailure Int -> String -> String
color String
name String
msg
hasTrailingLinefeed :: String -> Bool
hasTrailingLinefeed String
str =
case String
str of
[] -> Bool
True
String
_ -> forall a. [a] -> a
last String
str forall a. Eq a => a -> a -> Bool
== Char
'\n'
coversLastLine :: [(Bool, b)] -> Bool
coversLastLine [(Bool, b)]
regions =
case [(Bool, b)]
regions of
[] -> Bool
False
[(Bool, b)]
_ -> (forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last [(Bool, b)]
regions)
makeDiff :: String -> String -> Fix -> DiffDoc String
makeDiff :: String -> String -> Fix -> DiffDoc String
makeDiff String
name String
contents Fix
fix = do
let hunks :: [(Bool, [Diff String])]
hunks = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff forall a b. (a -> b) -> a -> b
$ String -> Fix -> [Diff String]
computeDiff String
contents Fix
fix
let lf :: LFStatus
lf = if forall {b}. [(Bool, b)] -> Bool
coversLastLine [(Bool, [Diff String])]
hunks Bool -> Bool -> Bool
&& Bool -> Bool
not (String -> Bool
hasTrailingLinefeed String
contents)
then LFStatus
LinefeedMissing
else LFStatus
LinefeedOk
forall a. String -> LFStatus -> [DiffRegion a] -> DiffDoc a
DiffDoc String
name LFStatus
lf forall a b. (a -> b) -> a -> b
$ [(Bool, [Diff String])] -> [DiffRegion String]
findRegions [(Bool, [Diff String])]
hunks
computeDiff :: String -> Fix -> [Diff String]
computeDiff :: String -> Fix -> [Diff String]
computeDiff String
contents Fix
fix =
let old :: [String]
old = String -> [String]
lines String
contents
array :: Array Int String
array = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
1, forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
old)) [String]
old
new :: [String]
new = Fix -> Array Int String -> [String]
applyFix Fix
fix Array Int String
array
in forall a. Eq a => [a] -> [a] -> [Diff a]
getDiff [String]
old [String]
new
groupDiff :: [Diff a] -> [(Bool, [Diff a])]
groupDiff :: forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff = forall a. (a -> Bool) -> [a] -> [a]
filter (\(Bool
_, [Diff a]
l) -> Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Diff a]
l)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a} {b}.
[PolyDiff a b] -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
hunt []
where
hunt :: [PolyDiff a b] -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
hunt [PolyDiff a b]
current [] = [(Bool
False, forall a. [a] -> [a]
reverse [PolyDiff a b]
current)]
hunt [PolyDiff a b]
current (x :: PolyDiff a b
x@Both {}:[PolyDiff a b]
rest) = [PolyDiff a b] -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
hunt (PolyDiff a b
xforall a. a -> [a] -> [a]
:[PolyDiff a b]
current) [PolyDiff a b]
rest
hunt [PolyDiff a b]
current [PolyDiff a b]
list =
let ([PolyDiff a b]
context, [PolyDiff a b]
previous) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
contextSize [PolyDiff a b]
current
in (Bool
False, forall a. [a] -> [a]
reverse [PolyDiff a b]
previous) forall a. a -> [a] -> [a]
: [PolyDiff a b] -> Int -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
gather [PolyDiff a b]
context Int
0 [PolyDiff a b]
list
gather :: [PolyDiff a b] -> Int -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
gather [PolyDiff a b]
current Int
n [] =
let ([PolyDiff a b]
extras, [PolyDiff a b]
patch) = forall a. Int -> [a] -> ([a], [a])
splitAt (forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
n forall a. Num a => a -> a -> a
- Int
contextSize) [PolyDiff a b]
current
in [(Bool
True, forall a. [a] -> [a]
reverse [PolyDiff a b]
patch), (Bool
False, forall a. [a] -> [a]
reverse [PolyDiff a b]
extras)]
gather [PolyDiff a b]
current Int
n list :: [PolyDiff a b]
list@(Both {}:[PolyDiff a b]
_) | Int
n forall a. Eq a => a -> a -> Bool
== Int
contextSizeforall a. Num a => a -> a -> a
*Int
2 =
let ([PolyDiff a b]
context, [PolyDiff a b]
previous) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
contextSize [PolyDiff a b]
current
in (Bool
True, forall a. [a] -> [a]
reverse [PolyDiff a b]
previous) forall a. a -> [a] -> [a]
: [PolyDiff a b] -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
hunt [PolyDiff a b]
context [PolyDiff a b]
list
gather [PolyDiff a b]
current Int
n (x :: PolyDiff a b
x@Both {}:[PolyDiff a b]
rest) = [PolyDiff a b] -> Int -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
gather (PolyDiff a b
xforall a. a -> [a] -> [a]
:[PolyDiff a b]
current) (Int
nforall a. Num a => a -> a -> a
+Int
1) [PolyDiff a b]
rest
gather [PolyDiff a b]
current Int
n (PolyDiff a b
x:[PolyDiff a b]
rest) = [PolyDiff a b] -> Int -> [PolyDiff a b] -> [(Bool, [PolyDiff a b])]
gather (PolyDiff a b
xforall a. a -> [a] -> [a]
:[PolyDiff a b]
current) Int
0 [PolyDiff a b]
rest
findRegions :: [(Bool, [Diff String])] -> [DiffRegion String]
findRegions :: [(Bool, [Diff String])] -> [DiffRegion String]
findRegions = forall {a}. Int -> Int -> [(Bool, [Diff a])] -> [DiffRegion a]
find' Int
1 Int
1
where
find' :: Int -> Int -> [(Bool, [Diff a])] -> [DiffRegion a]
find' Int
_ Int
_ [] = []
find' Int
left Int
right ((Bool
output, [Diff a]
run):[(Bool, [Diff a])]
rest) =
let (Int
dl, Int
dr) = forall a. [Diff a] -> (Int, Int)
countDelta [Diff a]
run
remainder :: [DiffRegion a]
remainder = Int -> Int -> [(Bool, [Diff a])] -> [DiffRegion a]
find' (Int
leftforall a. Num a => a -> a -> a
+Int
dl) (Int
rightforall a. Num a => a -> a -> a
+Int
dr) [(Bool, [Diff a])]
rest
in
if Bool
output
then forall a. (Int, Int) -> (Int, Int) -> [Diff a] -> DiffRegion a
DiffRegion (Int
left, Int
dl) (Int
right, Int
dr) [Diff a]
run forall a. a -> [a] -> [a]
: [DiffRegion a]
remainder
else [DiffRegion a]
remainder
countDelta :: [Diff a] -> (Int, Int)
countDelta :: forall a. [Diff a] -> (Int, Int)
countDelta = forall {t} {t} {a} {b}.
(Num t, Num t) =>
t -> t -> [PolyDiff a b] -> (t, t)
count' Int
0 Int
0
where
count' :: t -> t -> [PolyDiff a b] -> (t, t)
count' t
left t
right [] = (t
left, t
right)
count' t
left t
right (PolyDiff a b
x:[PolyDiff a b]
rest) =
case PolyDiff a b
x of
Both {} -> t -> t -> [PolyDiff a b] -> (t, t)
count' (t
leftforall a. Num a => a -> a -> a
+t
1) (t
rightforall a. Num a => a -> a -> a
+t
1) [PolyDiff a b]
rest
First {} -> t -> t -> [PolyDiff a b] -> (t, t)
count' (t
leftforall a. Num a => a -> a -> a
+t
1) t
right [PolyDiff a b]
rest
Second {} -> t -> t -> [PolyDiff a b] -> (t, t)
count' t
left (t
rightforall a. Num a => a -> a -> a
+t
1) [PolyDiff a b]
rest
formatRegion :: ColorFunc -> LFStatus -> DiffRegion String -> String
formatRegion :: (Int -> String -> String)
-> LFStatus -> DiffRegion String -> String
formatRegion Int -> String -> String
color LFStatus
lf (DiffRegion (Int, Int)
left (Int, Int)
right [Diff String]
diffs) =
let header :: String
header = Int -> String -> String
color Int
cyan (String
"@@ -" forall a. [a] -> [a] -> [a]
++ (forall {a} {a}. (Show a, Show a) => (a, a) -> String
tup (Int, Int)
left) forall a. [a] -> [a] -> [a]
++ String
" +" forall a. [a] -> [a] -> [a]
++ (forall {a} {a}. (Show a, Show a) => (a, a) -> String
tup (Int, Int)
right) forall a. [a] -> [a] -> [a]
++String
" @@")
in
[String] -> String
unlines forall a b. (a -> b) -> a -> b
$ String
header forall a. a -> [a] -> [a]
: forall a. [a] -> [a]
reverse (LFStatus -> [Diff String] -> [String]
getStrings LFStatus
lf (forall a. [a] -> [a]
reverse [Diff String]
diffs))
where
noLF :: String
noLF = String
"\\ No newline at end of file"
getStrings :: LFStatus -> [Diff String] -> [String]
getStrings LFStatus
LinefeedOk [Diff String]
list = forall a b. (a -> b) -> [a] -> [b]
map Diff String -> String
format [Diff String]
list
getStrings LFStatus
LinefeedMissing list :: [Diff String]
list@((Both String
_ String
_):[Diff String]
_) = String
noLF forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Diff String -> String
format [Diff String]
list
getStrings LFStatus
LinefeedMissing list :: [Diff String]
list@((First String
_):[Diff String]
_) = String
noLF forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Diff String -> String
format [Diff String]
list
getStrings LFStatus
LinefeedMissing (Diff String
last:[Diff String]
rest) = Diff String -> String
format Diff String
last forall a. a -> [a] -> [a]
: LFStatus -> [Diff String] -> [String]
getStrings LFStatus
LinefeedMissing [Diff String]
rest
tup :: (a, a) -> String
tup (a
a,a
b) = (forall {a}. Show a => a -> String
show a
a) forall a. [a] -> [a] -> [a]
++ String
"," forall a. [a] -> [a] -> [a]
++ (forall {a}. Show a => a -> String
show a
b)
format :: Diff String -> String
format (Both String
x String
_) = Char
' 'forall a. a -> [a] -> [a]
:String
x
format (First String
x) = Int -> String -> String
color Int
red forall a b. (a -> b) -> a -> b
$ Char
'-'forall a. a -> [a] -> [a]
:String
x
format (Second String
x) = Int -> String -> String
color Int
green forall a b. (a -> b) -> a -> b
$ Char
'+'forall a. a -> [a] -> [a]
:String
x
splitLast :: [a] -> ([a], [a])
splitLast [] = ([], [])
splitLast [a]
x =
let ([a]
last, [a]
rest) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
1 forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [a]
x
in (forall a. [a] -> [a]
reverse [a]
rest, [a]
last)
formatDoc :: (Int -> String -> String) -> DiffDoc String -> String
formatDoc Int -> String -> String
color (DiffDoc String
name LFStatus
lf [DiffRegion String]
regions) =
let ([DiffRegion String]
most, [DiffRegion String]
last) = forall {a}. [a] -> ([a], [a])
splitLast [DiffRegion String]
regions
in
(Int -> String -> String
color Int
bold forall a b. (a -> b) -> a -> b
$ String
"--- " forall a. [a] -> [a] -> [a]
++ (String
"a" String -> String -> String
</> String
name)) forall a. [a] -> [a] -> [a]
++ String
"\n" forall a. [a] -> [a] -> [a]
++
(Int -> String -> String
color Int
bold forall a b. (a -> b) -> a -> b
$ String
"+++ " forall a. [a] -> [a] -> [a]
++ (String
"b" String -> String -> String
</> String
name)) forall a. [a] -> [a] -> [a]
++ String
"\n" forall a. [a] -> [a] -> [a]
++
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Int -> String -> String)
-> LFStatus -> DiffRegion String -> String
formatRegion Int -> String -> String
color LFStatus
LinefeedOk) [DiffRegion String]
most forall a. [a] -> [a] -> [a]
++
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Int -> String -> String)
-> LFStatus -> DiffRegion String -> String
formatRegion Int -> String -> String
color LFStatus
lf) [DiffRegion String]
last
buildFixMap :: [Fix] -> M.Map String Fix
buildFixMap :: [Fix] -> Map String Fix
buildFixMap [Fix]
fixes = Map String Fix
perFile
where
splitFixes :: [Fix]
splitFixes = Fix -> [Fix]
splitFixByFile forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [Fix]
fixes
perFile :: Map String Fix
perFile = forall k v. (Ord k, Monoid v) => (v -> k) -> [v] -> Map k v
groupByMap (Position -> String
posFile forall b c a. (b -> c) -> (a -> b) -> a -> c
. Replacement -> Position
repStartPos forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> a
head forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fix -> [Replacement]
fixReplacements) [Fix]
splitFixes
splitFixByFile :: Fix -> [Fix]
splitFixByFile :: Fix -> [Fix]
splitFixByFile Fix
fix = forall a b. (a -> b) -> [a] -> [b]
map [Replacement] -> Fix
makeFix forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy Replacement -> Replacement -> Bool
sameFile (Fix -> [Replacement]
fixReplacements Fix
fix)
where
sameFile :: Replacement -> Replacement -> Bool
sameFile Replacement
rep1 Replacement
rep2 = (Position -> String
posFile forall a b. (a -> b) -> a -> b
$ Replacement -> Position
repStartPos Replacement
rep1) forall a. Eq a => a -> a -> Bool
== (Position -> String
posFile forall a b. (a -> b) -> a -> b
$ Replacement -> Position
repStartPos Replacement
rep2)
makeFix :: [Replacement] -> Fix
makeFix [Replacement]
reps = Fix
newFix { fixReplacements :: [Replacement]
fixReplacements = [Replacement]
reps }
groupByMap :: (Ord k, Monoid v) => (v -> k) -> [v] -> M.Map k v
groupByMap :: forall k v. (Ord k, Monoid v) => (v -> k) -> [v] -> Map k v
groupByMap v -> k
f = forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
M.fromListWith forall a. Monoid a => a -> a -> a
Monoid.mappend forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (\v
x -> (v -> k
f v
x, v
x))
b :: b -> PolyDiff b b
b b
n = forall a b. a -> b -> PolyDiff a b
Both b
n b
n
l :: a -> PolyDiff a b
l = forall a b. a -> PolyDiff a b
First
r :: b -> PolyDiff a b
r = forall a b. b -> PolyDiff a b
Second
prop_identifiesProperContext :: Bool
prop_identifiesProperContext = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff [forall {b}. b -> PolyDiff b b
b Integer
1, forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3, forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b}. b -> PolyDiff b b
b Integer
8, forall {b}. b -> PolyDiff b b
b Integer
9] forall a. Eq a => a -> a -> Bool
==
[(Bool
False, [forall {b}. b -> PolyDiff b b
b Integer
1]),
(Bool
True, [forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3, forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b}. b -> PolyDiff b b
b Integer
8]),
(Bool
False, [forall {b}. b -> PolyDiff b b
b Integer
9])]
prop_includesContextFromStartIfNecessary :: Bool
prop_includesContextFromStartIfNecessary = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff [forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b}. b -> PolyDiff b b
b Integer
8, forall {b}. b -> PolyDiff b b
b Integer
9] forall a. Eq a => a -> a -> Bool
==
[
(Bool
True, [forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b}. b -> PolyDiff b b
b Integer
8]),
(Bool
False, [forall {b}. b -> PolyDiff b b
b Integer
9])]
prop_includesContextUntilEndIfNecessary :: Bool
prop_includesContextUntilEndIfNecessary = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff [forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5] forall a. Eq a => a -> a -> Bool
==
[
(Bool
True, [forall {b}. b -> PolyDiff b b
b Integer
4, forall a b. a -> PolyDiff a b
l Integer
5])
]
prop_splitsIntoMultipleHunks :: Bool
prop_splitsIntoMultipleHunks = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff [forall a b. a -> PolyDiff a b
l Integer
1, forall {b}. b -> PolyDiff b b
b Integer
1, forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3, forall {b}. b -> PolyDiff b b
b Integer
4, forall {b}. b -> PolyDiff b b
b Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b} {a}. b -> PolyDiff a b
r Integer
8] forall a. Eq a => a -> a -> Bool
==
[
(Bool
True, [forall a b. a -> PolyDiff a b
l Integer
1, forall {b}. b -> PolyDiff b b
b Integer
1, forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3]),
(Bool
False, [forall {b}. b -> PolyDiff b b
b Integer
4]),
(Bool
True, [forall {b}. b -> PolyDiff b b
b Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b}. b -> PolyDiff b b
b Integer
7, forall {b} {a}. b -> PolyDiff a b
r Integer
8])
]
prop_splitsIntoMultipleHunksUnlessTouching :: Bool
prop_splitsIntoMultipleHunksUnlessTouching = forall a. [Diff a] -> [(Bool, [Diff a])]
groupDiff [forall a b. a -> PolyDiff a b
l Integer
1, forall {b}. b -> PolyDiff b b
b Integer
1, forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3, forall {b}. b -> PolyDiff b b
b Integer
4, forall {b}. b -> PolyDiff b b
b Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b} {a}. b -> PolyDiff a b
r Integer
7] forall a. Eq a => a -> a -> Bool
==
[
(Bool
True, [forall a b. a -> PolyDiff a b
l Integer
1, forall {b}. b -> PolyDiff b b
b Integer
1, forall {b}. b -> PolyDiff b b
b Integer
2, forall {b}. b -> PolyDiff b b
b Integer
3, forall {b}. b -> PolyDiff b b
b Integer
4, forall {b}. b -> PolyDiff b b
b Integer
5, forall {b}. b -> PolyDiff b b
b Integer
6, forall {b} {a}. b -> PolyDiff a b
r Integer
7])
]
prop_countDeltasWorks :: Bool
prop_countDeltasWorks = forall a. [Diff a] -> (Int, Int)
countDelta [forall {b}. b -> PolyDiff b b
b Integer
1, forall a b. a -> PolyDiff a b
l Integer
2, forall {b} {a}. b -> PolyDiff a b
r Integer
3, forall {b} {a}. b -> PolyDiff a b
r Integer
4, forall {b}. b -> PolyDiff b b
b Integer
5] forall a. Eq a => a -> a -> Bool
== (Int
3,Int
4)
prop_countDeltasWorks2 :: Bool
prop_countDeltasWorks2 = forall a. [Diff a] -> (Int, Int)
countDelta [] forall a. Eq a => a -> a -> Bool
== (Int
0,Int
0)
return []
runTests :: IO Bool
runTests = $Bool
String
[(String, Property)]
[(String, Property)] -> (Property -> IO Result) -> IO Bool
forall prop. Testable prop => prop -> IO Result
forall prop. Testable prop => prop -> Property
runQuickCheckAll :: [(String, Property)] -> (Property -> IO Result) -> IO Bool
property :: forall prop. Testable prop => prop -> Property
quickCheckResult :: forall prop. Testable prop => prop -> IO Result
prop_countDeltasWorks2 :: Bool
prop_countDeltasWorks :: Bool
prop_splitsIntoMultipleHunksUnlessTouching :: Bool
prop_splitsIntoMultipleHunks :: Bool
prop_includesContextUntilEndIfNecessary :: Bool
prop_includesContextFromStartIfNecessary :: Bool
prop_identifiesProperContext :: Bool
quickCheckAll