fortran-src-0.7.0: test/Language/Fortran/Rewriter/InternalSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Language.Fortran.Rewriter.InternalSpec
( spec
)
where
import qualified Data.ByteString.Lazy.Char8 as BC
import Test.Hspec
import Control.Exception.Base ( evaluate )
import Language.Fortran.Rewriter.Internal
spec :: Spec
spec = do
describe "SourceLocation" $ it "Initialize SourceLocation" $ do
let sl = SourceLocation 0 0
sl `shouldBe` SourceLocation 0 0
describe "SourceRange" $ it "Initialize SourceRange" $ do
let sr = SourceRange (SourceLocation 0 0) (SourceLocation 0 5)
sr `shouldBe` SourceRange (SourceLocation 0 0) (SourceLocation 0 5)
describe "RChar" $ do
it "Initialize RChar" $ do
let rch = RChar (Just 'a') False (SourceLocation 0 0) ""
rch `shouldBe` RChar (Just 'a') False (SourceLocation 0 0) ""
it "Convert line to [RChar]" $ do
let line = "Line"
rcharl = toRCharList line
rcharl
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
it "Convert multiline string to [RChar]" $ do
let multiLine = "fi\nl\nes"
rcharl = toRCharList multiLine
rcharl
`shouldBe` [ RChar (Just 'f') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just '\n') False (SourceLocation 0 2) ""
, RChar (Just 'l') False (SourceLocation 1 0) ""
, RChar (Just '\n') False (SourceLocation 1 1) ""
, RChar (Just 'e') False (SourceLocation 2 0) ""
, RChar (Just 's') False (SourceLocation 2 1) ""
, RChar Nothing False (SourceLocation 2 2) ""
]
it "Mark range in line (in the middle)" $ do
let line = toRCharList "Long Line"
range = SourceRange (SourceLocation 0 1) (SourceLocation 0 5)
rcharl = markRChars line range
rcharl
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'o') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'g') True (SourceLocation 0 3) ""
, RChar (Just ' ') True (SourceLocation 0 4) ""
, RChar (Just 'L') False (SourceLocation 0 5) ""
, RChar (Just 'i') False (SourceLocation 0 6) ""
, RChar (Just 'n') False (SourceLocation 0 7) ""
, RChar (Just 'e') False (SourceLocation 0 8) ""
, RChar Nothing False (SourceLocation 0 9) ""
]
it "Mark range in line (the whole line)" $ do
let line = toRCharList "Long Line"
range = SourceRange (SourceLocation 0 0) (SourceLocation 0 9)
rcharl = markRChars line range
rcharl
`shouldBe` [ RChar (Just 'L') True (SourceLocation 0 0) ""
, RChar (Just 'o') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'g') True (SourceLocation 0 3) ""
, RChar (Just ' ') True (SourceLocation 0 4) ""
, RChar (Just 'L') True (SourceLocation 0 5) ""
, RChar (Just 'i') True (SourceLocation 0 6) ""
, RChar (Just 'n') True (SourceLocation 0 7) ""
, RChar (Just 'e') True (SourceLocation 0 8) ""
, RChar Nothing False (SourceLocation 0 9) ""
]
it "Mark range in multiline string (in the middle)" $ do
let line = toRCharList "Li\nn\nes12"
range = SourceRange (SourceLocation 0 1) (SourceLocation 2 2)
rcharl = markRChars line range
rcharl
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just '\n') True (SourceLocation 0 2) ""
, RChar (Just 'n') True (SourceLocation 1 0) ""
, RChar (Just '\n') True (SourceLocation 1 1) ""
, RChar (Just 'e') True (SourceLocation 2 0) ""
, RChar (Just 's') True (SourceLocation 2 1) ""
, RChar (Just '1') False (SourceLocation 2 2) ""
, RChar (Just '2') False (SourceLocation 2 3) ""
, RChar Nothing False (SourceLocation 2 4) ""
]
it "Mark range in multiline string (the whole multiline)" $ do
let multiline = toRCharList "Li\nn\nes12"
range = SourceRange (SourceLocation 0 0) (SourceLocation 2 4)
rcharl = markRChars multiline range
rcharl
`shouldBe` [ RChar (Just 'L') True (SourceLocation 0 0) ""
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just '\n') True (SourceLocation 0 2) ""
, RChar (Just 'n') True (SourceLocation 1 0) ""
, RChar (Just '\n') True (SourceLocation 1 1) ""
, RChar (Just 'e') True (SourceLocation 2 0) ""
, RChar (Just 's') True (SourceLocation 2 1) ""
, RChar (Just '1') True (SourceLocation 2 2) ""
, RChar (Just '2') True (SourceLocation 2 3) ""
, RChar Nothing False (SourceLocation 2 4) ""
]
it "Set replacement string (SourceLocation)" $ do
let line = toRCharList "Line"
sl = SourceLocation 0 1
repl = "repl"
rchars = setReplacementStringSL line sl repl False
rchars
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) "repl"
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
it "Set replacement string (SourceRange)" $ do
let line = toRCharList "Line"
range = SourceRange (SourceLocation 0 1) (SourceLocation 0 3)
repl = "repl"
rchars = setReplacementStringSR line range repl False
rchars
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) "repl"
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
it "Evaluate single line (empty replacement)" $ do
let rchars =
[ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "Line"
it "Evaluate single line (one-to-none replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "ine"
it "Evaluate single line (many-to-none replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) ""
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'q') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "q"
it "Evaluate single line (many-to-none replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) ""
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "e"
it "Evaluate single line (one-to-one replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) "T"
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "Tine"
it "Evaluate single line (many-to-one replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) "T"
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "Te"
it "Evaluate single line (one-to-many replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) "Argent"
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') False (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "Argentine"
it "Evaluate single line (many-to-many replacement)" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) "Pineappl"
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'e') False (SourceLocation 0 3) ""
, RChar Nothing False (SourceLocation 0 4) ""
]
result = evaluateRChars rchars
result `shouldBe` "Pineapple"
it "Evaluate multiline" $ do
let rchars =
[ RChar (Just 'L') True (SourceLocation 0 0) "Formula"
, RChar (Just 'i') True (SourceLocation 0 1) ""
, RChar (Just '\n') True (SourceLocation 0 2) ""
, RChar (Just '\n') False (SourceLocation 0 3) ""
, RChar (Just '1') False (SourceLocation 0 4) ""
, RChar Nothing False (SourceLocation 0 5) ""
]
result = evaluateRChars rchars
result `shouldBe` "Formula\n1"
describe "Chunk" $ do
it "Take next chunk (no replacements)" $ do
let line = toRCharList "a very long text"
chunk = nextChunk line
chunk `shouldBe` (line, [])
it "Take next chunk (replacement in the middle)" $ do
let line =
[ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just 'n') True (SourceLocation 0 2) "repl"
, RChar (Just 'e') True (SourceLocation 0 3) ""
, RChar (Just 'O') True (SourceLocation 0 4) ""
, RChar (Just 'f') False (SourceLocation 0 5) ""
, RChar Nothing False (SourceLocation 0 6) ""
]
chunk = nextChunk line
chunk `shouldBe` (take 2 line, drop 2 line)
it "Take next chunk (replacement in the begining)" $ do
let line =
[ RChar (Just 'D') True (SourceLocation 0 0) "repl"
, RChar (Just 'o') True (SourceLocation 0 1) ""
, RChar (Just 'g') False (SourceLocation 0 2) ""
, RChar Nothing False (SourceLocation 0 3) ""
]
chunk = nextChunk line
chunk `shouldBe` (take 1 line, drop 1 line)
it "Take next chunk (deletion in the begining)" $ do
let line =
[ RChar (Just 'D') True (SourceLocation 0 0) ""
, RChar (Just 'o') True (SourceLocation 0 1) ""
, RChar (Just 'g') False (SourceLocation 0 2) ""
, RChar Nothing False (SourceLocation 0 3) ""
]
chunk = nextChunk line
chunk `shouldBe` (take 1 line, drop 1 line)
it "Take next chunk (with a new line)" $ do
let multiline = toRCharList "some text with\na new line"
chunk = nextChunk multiline
chunk `shouldBe` (take 15 multiline, drop 15 multiline)
it "Take all chunks (single chunk)" $ do
let line = toRCharList "A single chunk"
chunks = allChunks line
chunks `shouldBe` [line]
it "Take all chunks (chunks separated by a new line)" $ do
let multiline = toRCharList "Two \n chunks"
chunks = allChunks multiline
chunks `shouldBe` [take 5 multiline, drop 5 multiline]
it "Take all chunks (chunks separated by a new line and deletion marks)"
$ do
let multiline =
[ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just '\n') False (SourceLocation 0 2) ""
, RChar (Just 'e') True (SourceLocation 1 0) "repl"
, RChar (Just 't') True (SourceLocation 1 1) ""
, RChar (Just 'f') False (SourceLocation 2 0) ""
, RChar Nothing False (SourceLocation 2 1) ""
]
chunks = allChunks multiline
chunks
`shouldBe` [ [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') False (SourceLocation 0 1) ""
, RChar (Just '\n') False (SourceLocation 0 2) ""
]
, [RChar (Just 'e') True (SourceLocation 1 0) "repl"]
, [RChar (Just 't') True (SourceLocation 1 1) ""]
, [ RChar (Just 'f') False (SourceLocation 2 0) ""
, RChar Nothing False (SourceLocation 2 1) ""
]
]
it "Evaluate chunks (no replacements; short single line)" $ do
let chunks = allChunks $ toRCharList "Line"
str = evaluateChunks chunks
str `shouldBe` "Line"
it "Evaluate chunks (no replacements; short multiline)" $ do
let chunks = allChunks $ toRCharList "Multi\nline"
str = evaluateChunks chunks
str `shouldBe` "Multi\nline"
it "Evaluate chunks (no replacements; long single line)" $ do
let rchars = toRCharList $ BC.replicate 90 'a'
chunks = allChunks rchars
str = evaluateChunks chunks
str `shouldBe` BC.replicate 90 'a'
it "Evaluate chunks (no replacements; long multiline)" $ do
let ostr =
BC.replicate 20 'a'
<> "\n"
<> BC.replicate 40 'b'
<> "\n"
<> BC.replicate 90 'c'
<> "\n"
<> BC.replicate 70 'd'
rchars = toRCharList ostr
chunks = allChunks rchars
str = evaluateChunks chunks
str `shouldBe` ostr
it "Evaluate chunks (empty replacement; short line)" $ do
let range = SourceRange (SourceLocation 0 5) (SourceLocation 0 5)
repl = Replacement range ""
rchars = setReplacement (toRCharList "A short one") repl
chunks = allChunks rchars
str = evaluateChunks chunks
str `shouldBe` "A short one"
it "Evaluate chunks (short replacement; short line)" $ do
let range = SourceRange (SourceLocation 0 5) (SourceLocation 0 7)
repl = Replacement range "repl"
rchars = setReplacement (toRCharList "A short line") repl
chunks = allChunks rchars
str = evaluateChunks chunks
str `shouldBe` "A shorepl line"
it "Evaluate chunks (long replacement; short line)" $ do
let
range = SourceRange (SourceLocation 0 34) (SourceLocation 0 35)
replS = replicate 60 'a'
repl = Replacement range replS
rchars = setReplacement
(toRCharList "A very long line with many words in it")
repl
chunks = allChunks rchars
str = evaluateChunks chunks
str
`shouldBe` "A very long line with many words i"
<> "\n +"
<> BC.replicate 60 'a'
<> " it"
it "Evaluate chunks (long replacement; long line)" $ do
let range = SourceRange (SourceLocation 0 3) (SourceLocation 0 4)
replS = replicate 70 'a'
repl = Replacement range replS
rchars = setReplacement (toRCharList $ BC.replicate 70 'b') repl
chunks = allChunks rchars
str = evaluateChunks chunks
str
`shouldBe` BC.replicate 3 'b'
<> "\n +"
<> BC.replicate 70 'a'
<> "\n +"
<> BC.replicate 66 'b'
it "Evaluate chunks (multiline replacement; short line)" $ do
let range = SourceRange (SourceLocation 0 9) (SourceLocation 0 10)
replS = replicate 30 'a' <> "\n" <> replicate 30 'b'
repl = Replacement range replS
rchars = setReplacement (toRCharList $ BC.replicate 20 'c') repl
chunks = allChunks rchars
str = evaluateChunks chunks
str
`shouldBe` BC.replicate 9 'c'
<> BC.replicate 30 'a'
<> "\n"
<> BC.replicate 30 'b'
<> BC.replicate 10 'c'
it "Evaluate chunks (multiline replacement; long line)" $ do
let range = SourceRange (SourceLocation 0 8) (SourceLocation 0 9)
replS = replicate 30 'a' <> "\n" <> replicate 30 'b'
repl = Replacement range replS
rchars = setReplacement (toRCharList $ BC.replicate 60 'c') repl
chunks = allChunks rchars
str = evaluateChunks chunks
str
`shouldBe` BC.replicate 8 'c'
<> BC.replicate 30 'a'
<> "\n"
<> BC.replicate 30 'b'
<> "\n +"
<> BC.replicate 51 'c'
it "Evaluate chunks (multiline replacement; multiline)" $ do
let range = SourceRange (SourceLocation 0 10) (SourceLocation 0 15)
replS = replicate 30 'a' <> "\n" <> replicate 30 'd'
repl = Replacement range replS
rchars = setReplacement
(toRCharList $ BC.replicate 30 'c' <> "\n" <> BC.replicate 30 'c')
repl
chunks = allChunks rchars
str = evaluateChunks chunks
str
`shouldBe` BC.replicate 10 'c'
<> BC.replicate 30 'a'
<> "\n"
<> BC.replicate 30 'd'
<> BC.replicate 15 'c'
<> "\n"
<> BC.replicate 30 'c'
describe "Replacement" $ do
it "Initialize Replacement" $ do
let
r =
Replacement (SourceRange (SourceLocation 0 0) (SourceLocation 0 5)) ""
r `shouldBe` Replacement
(SourceRange (SourceLocation 0 0) (SourceLocation 0 5))
""
it "Set replacement (regular)" $ do
let line = toRCharList "LineOf"
range = SourceRange (SourceLocation 0 1) (SourceLocation 0 5)
replS = "repl"
r = Replacement range replS
res = setReplacement line r
res
`shouldBe` [ RChar (Just 'L') False (SourceLocation 0 0) ""
, RChar (Just 'i') True (SourceLocation 0 1) "repl"
, RChar (Just 'n') True (SourceLocation 0 2) ""
, RChar (Just 'e') True (SourceLocation 0 3) ""
, RChar (Just 'O') True (SourceLocation 0 4) ""
, RChar (Just 'f') False (SourceLocation 0 5) ""
, RChar Nothing False (SourceLocation 0 6) ""
]
it "Set replacement (insertion in the middle)" $ do
let line = toRCharList "shorty"
range = SourceRange (SourceLocation 0 1) (SourceLocation 0 1)
replS = "Va"
r = Replacement range replS
res = setReplacement line r
res
`shouldBe` [ RChar (Just 's') False (SourceLocation 0 0) ""
, RChar (Just 'h') True (SourceLocation 0 1) "Vah"
, RChar (Just 'o') False (SourceLocation 0 2) ""
, RChar (Just 'r') False (SourceLocation 0 3) ""
, RChar (Just 't') False (SourceLocation 0 4) ""
, RChar (Just 'y') False (SourceLocation 0 5) ""
, RChar Nothing False (SourceLocation 0 6) ""
]
it "Set replacement (insertion at the end)" $ do
let line = toRCharList "shorty"
range = SourceRange (SourceLocation 0 6) (SourceLocation 0 6)
replS = "Vb"
r = Replacement range replS
res = setReplacement line r
res
`shouldBe` [ RChar (Just 's') False (SourceLocation 0 0) ""
, RChar (Just 'h') False (SourceLocation 0 1) ""
, RChar (Just 'o') False (SourceLocation 0 2) ""
, RChar (Just 'r') False (SourceLocation 0 3) ""
, RChar (Just 't') False (SourceLocation 0 4) ""
, RChar (Just 'y') False (SourceLocation 0 5) ""
, RChar Nothing True (SourceLocation 0 6) "Vb"
]
it "Set replacements" $ do
let code = toRCharList $ BC.replicate 6 'a'
range1 = SourceRange (SourceLocation 0 1) (SourceLocation 0 3)
range2 = SourceRange (SourceLocation 0 3) (SourceLocation 0 5)
replS1 = "repl1"
replS2 = "repl2"
r1 = Replacement range1 replS1
r2 = Replacement range2 replS2
res = setReplacements code [r1, r2]
res
`shouldBe` [ RChar (Just 'a') False (SourceLocation 0 0) ""
, RChar (Just 'a') True (SourceLocation 0 1) (BC.pack replS1)
, RChar (Just 'a') True (SourceLocation 0 2) ""
, RChar (Just 'a') True (SourceLocation 0 3) (BC.pack replS2)
, RChar (Just 'a') True (SourceLocation 0 4) ""
, RChar (Just 'a') False (SourceLocation 0 5) ""
, RChar Nothing False (SourceLocation 0 6) ""
]
it "Disjoint replacements (disjoint, different lines)" $ do
let range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 14)
range2 = SourceRange (SourceLocation 1 2) (SourceLocation 1 20)
r1 = Replacement range1 "zz"
r2 = Replacement range2 "xx"
areDisjoint r1 r2 `shouldBe` True
areDisjoint r2 r1 `shouldBe` True
it "Disjoint replacements (disjoint, same line)" $ do
let range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 4)
range2 = SourceRange (SourceLocation 0 4) (SourceLocation 0 6)
r1 = Replacement range1 "ee"
r2 = Replacement range2 "ff"
areDisjoint r1 r2 `shouldBe` True
areDisjoint r2 r1 `shouldBe` True
it "Disjoint replacements (overlapping, same line)" $ do
let range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 14)
range2 = SourceRange (SourceLocation 0 7) (SourceLocation 0 20)
r1 = Replacement range1 "aa"
r2 = Replacement range2 "bb"
areDisjoint r1 r2 `shouldBe` False
areDisjoint r2 r1 `shouldBe` False
it "Disjoint replacements (overlapping, across lines)" $ do
let range1 = SourceRange (SourceLocation 0 2) (SourceLocation 2 14)
range2 = SourceRange (SourceLocation 1 7) (SourceLocation 5 20)
r1 = Replacement range1 "cc"
r2 = Replacement range2 "dd"
areDisjoint r1 r2 `shouldBe` False
areDisjoint r2 r1 `shouldBe` False
it "Apply replacement (continuation line)" $ do
let source = BC.replicate 30 'a' <> "\n" <> BC.replicate 30 'a'
range = SourceRange (SourceLocation 0 2) (SourceLocation 1 2)
replS = replicate 71 'b' <> "\n" <> replicate 71 'c'
r = Replacement range replS
res = applyReplacements source [r]
res
`shouldBe` ( BC.replicate 2 'a'
<> "\n +"
<> BC.pack replS
<> "\n +"
<> BC.replicate 28 'a'
)
it "Apply replacement (insertion in the middle)" $ do
let source = "abc"
range = SourceRange (SourceLocation 0 0) (SourceLocation 0 0)
replS = "DDD"
r = Replacement range replS
res = applyReplacements source [r]
res `shouldBe` "DDDabc"
it "Apply replacement (insertion at the end)" $ do
let source = "abz"
range = SourceRange (SourceLocation 0 3) (SourceLocation 0 3)
replS = "DFG"
r = Replacement range replS
res = applyReplacements source [r]
res `shouldBe` "abzDFG"
it "Apply replacements (disjoint)" $ do
let source = BC.replicate 30 'a'
range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 4)
range2 = SourceRange (SourceLocation 0 4) (SourceLocation 0 6)
replS1 = "repl1"
replS2 = "2lper"
r1 = Replacement range1 replS1
r2 = Replacement range2 replS2
res = applyReplacements source [r1, r2]
res
`shouldBe` BC.replicate 2 'a'
<> BC.pack replS1
<> BC.pack replS2
<> BC.replicate 24 'a'
it "Apply replacement ('!' in a string literal)" $ do
let
source =
" write(8, *) 'hi! this string is really long, overflowing even'"
-- ^ Column 68
range = SourceRange (SourceLocation 0 68) (SourceLocation 0 68)
replS = ", variableHello"
r = Replacement range replS
res = applyReplacements source [r]
res
`shouldBe`
" write(8, *) 'hi! this string is really long, overflowing even'\n +, variableHello"
it "Apply replacements (overlapping)" $ do
let source = BC.replicate 30 'a'
range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 4)
range2 = SourceRange (SourceLocation 0 3) (SourceLocation 0 6)
replS = "repl"
r1 = Replacement range1 replS
r2 = Replacement range2 replS
evaluate (applyReplacements source [r1, r2])
`shouldThrow` (== OverlappingError [(r1, r2)])
it "Apply replacements (multiple overlapping)" $ do
let source = BC.replicate 30 'a'
range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 4)
range2 = SourceRange (SourceLocation 0 3) (SourceLocation 0 6)
range3 = SourceRange (SourceLocation 0 5) (SourceLocation 0 7)
replS = "repl"
r1 = Replacement range1 replS
r2 = Replacement range2 replS
r3 = Replacement range3 replS
evaluate (applyReplacements source [r1, r2, r3])
`shouldThrow` (== OverlappingError [(r1, r2), (r2, r3)])
it "Apply replacements (overlapping and out-of-order)" $ do
let source = BC.replicate 30 'a'
range1 = SourceRange (SourceLocation 0 2) (SourceLocation 0 4)
range2 = SourceRange (SourceLocation 0 3) (SourceLocation 0 6)
range3 = SourceRange (SourceLocation 0 5) (SourceLocation 0 7)
replS = "repl"
r1 = Replacement range1 replS
r2 = Replacement range2 replS
r3 = Replacement range3 replS
evaluate (applyReplacements source [r3, r2, r1])
`shouldThrow` (== OverlappingError [(r1, r2), (r2, r3)])
it "Apply replacements (invalid ranges; out of code)" $ do
let source = BC.replicate 30 'a'
range = SourceRange (SourceLocation 0 2) (SourceLocation 0 31)
repl = Replacement range ""
evaluate (applyReplacements source [repl])
`shouldThrow` (== InvalidRangeError)
it "Apply replacements (invalid ranges; invalid ordering of the parameters)"
$ do
let source = BC.replicate 30 'a'
range = SourceRange (SourceLocation 0 20) (SourceLocation 0 5)
repl = Replacement range ""
evaluate (applyReplacements source [repl])
`shouldThrow` (== InvalidRangeError)