packages feed

phino-0.0.0.47: test/MergeSpec.hs

-- SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com
-- SPDX-License-Identifier: MIT

module MergeSpec where

import AST
import Control.Monad (forM_)
import Data.List (intercalate)
import Merge (merge)
import Parser (parseExpressionThrows)
import Test.Hspec (Spec, anyException, describe, it, shouldBe, shouldThrow)

spec :: Spec
spec = do
  describe "merge programs" $
    forM_
      [ ( ["[[ x -> 1 ]]", "[[ y -> 2 ]]"],
          "[[ x -> 1, y -> 2 ]]"
        ),
        ( ["[[ x -> [[ y -> 1 ]] ]]", "[[ x -> [[ z -> 2 ]] ]]"],
          "[[ x -> [[ y -> 1, z -> 2 ]] ]]"
        ),
        ( ["[[ x -> 1 ]]", "[[ x -> 1]]"],
          "[[ x -> 1]]"
        ),
        ( ["[[ org -> [[ eolang -> [[ number -> [[ ]] ]] ]] ]]", "[[ org -> [[ eolang -> [[ bytes -> [[ ]] ]] ]] ]]"],
          "[[ org -> [[ eolang -> [[ number -> [[ ]], bytes -> [[ ]] ]] ]] ]]"
        ),
        ( ["[[ x -> 1 ]]", "[[ y -> 2 ]]", "[[ z -> 3 ]]"],
          "[[ x -> 1, y -> 2, z -> 3 ]]"
        ),
        ( ["[[ x -> ? ]]", "[[ x -> ? ]]"],
          "[[ x -> ? ]]"
        ),
        ( ["[[ D> 42-, x -> [[ ]] ]]", "[[ D> 42-, y -> [[ ]] ]]"],
          "[[ x -> [[ ]], y -> [[ ]], D> 42- ]]"
        )
      ]
      ( \(exprs, res) -> it res $ do
          progs <- mapM (fmap Program . parseExpressionThrows) exprs
          merged <- merge progs
          res' <- fmap Program (parseExpressionThrows res)
          merged `shouldBe` res'
      )

  describe "fails to merge" $
    forM_
      [ ["Q", "$"],
        ["[[ x -> 1]]", "[[ x -> 2 ]]"],
        ["[[ x -> [[ y -> Q ]] ]]", "[[ x -> [[ y -> $ ]] ]]"]
      ]
      ( \exprs -> it (intercalate " and " exprs) $ do
          progs <- mapM (fmap Program . parseExpressionThrows) exprs
          merge progs `shouldThrow` anyException
      )