{-# OPTIONS_GHC -Wall #-} module Main where import ALON.Diff.HTML import Test.HUnit import Text.HTML.Parser import qualified Data.Text as T import Data.Text.Lazy (toStrict) import Data.Text.Lazy.Encoding (decodeUtf8) import qualified Data.ByteString.Lazy as L import Data.List import qualified Data.Aeson as DA readUTF8File :: FilePath -> IO T.Text readUTF8File file = L.readFile file >>= return . toStrict . decodeUtf8 sourceHTMLIO :: IO T.Text sourceHTMLIO = readUTF8File "./test/source.html" targetHTMLIO :: IO T.Text targetHTMLIO = readUTF8File "./test/target.html" readDiffJSONIO :: IO T.Text readDiffJSONIO = readUTF8File "./test/diff.json" roundTripTokens :: [Token] -> [Token] -> Maybe [Token] roundTripTokens sourceTokens targetTokens = do sourceTree <- buildChunkTree sourceTokens targetTree <- buildChunkTree targetTokens let sourceMap = mapChunkTree sourceTree let diff = diffChunkTree sourceMap targetTree patchTreeToTokens sourceTree diff -- Round trip through diff and patch, to make sure reproduced token stream matches the normalized original roundTripTest :: Test roundTripTest = TestCase $ do sourceHTML <- sourceHTMLIO targetHTML <- targetHTMLIO -- We use the pre-normalized tokens, because normalization should be idempotent and happens anyway in chunk tree building. let sourceTokens = normalizeHTMLTokens $ parseTokens sourceHTML let targetTokens = normalizeHTMLTokens $ parseTokens targetHTML let patchedTokens = roundTripTokens sourceTokens targetTokens case patchedTokens of Just tokens -> do let foundMismatch = find ( \(x, y) -> x /= y ) $ zip targetTokens tokens case foundMismatch of Just (left,right) -> assertFailure (show left ++ " doesn't match " ++ show right) Nothing -> assertEqual "differing lengths for target and patched token lists " (length tokens) (length targetTokens) Nothing -> assertFailure "Couldn't round trip patch, likely malformed HTML" -- Tests that building a chunk tree of source succeeds buildChunkTreeTest :: Test buildChunkTreeTest = TestCase $ do sourceHTML <- sourceHTMLIO let sourceTokens = parseTokens sourceHTML let chunkTree = buildChunkTree sourceTokens case chunkTree of Just _ -> return () Nothing -> assertFailure "Couldn't build chunk tree for source HTML" -- Tests that saved JSON diff matches baseline. Note, baseline might change in future and have to be updated. diffJSONTest :: Test diffJSONTest = TestCase $ do sourceHTML <- sourceHTMLIO targetHTML <- targetHTMLIO savedDiff <- readDiffJSONIO let diff = diffHTML sourceHTML targetHTML let maybeJsonValue = diff >>= return . toStrict . decodeUtf8 . DA.encode case maybeJsonValue of Just jsonValue -> assertEqual "Expected saved JSON and newly produced JSON to be equivalent" jsonValue savedDiff Nothing -> assertFailure "Unable to make JSON diff" tests :: Test tests = TestList [ TestLabel "buildChunkTreeTest" buildChunkTreeTest, TestLabel "roundTripTest" roundTripTest, TestLabel "diffJSONTest" diffJSONTest ] main :: IO () main = do _ <- runTestTT tests return ()