packages feed

phino-0.0.0.53: 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
      )