@@ -6,15 +6,18 @@ import ProjectM36.Relation
66import ProjectM36.Transaction
77import ProjectM36.TransactionGraph
88import ProjectM36.Error
9+import ProjectM36.Key
10+import qualified ProjectM36.DisconnectedTransaction as Discon
11+import qualified ProjectM36.DatabaseContext as DBC
12+import ProjectM36.RelationalExpression
13+
914import qualified Data.ByteString.Lazy as BS
1015import System.Exit
1116import Data.Word
12−import ProjectM36.RelationalExpression
13−import qualified ProjectM36.DisconnectedTransaction as Discon
1417import qualified Data.UUID as U
1518import qualified Data.Set as S
1619import qualified Data.Map as M
17−import qualified ProjectM36.DatabaseContext as DBC
20+
1821import Control.Monad.State hiding (join)
1922
2023main :: IO ()
@@ -29,7 +32,8 @@ testList = TestList [
2932 testSubGraphToFirstAncestorMoreTransactions,
3033 testSelectedBranchMerge,
3134 testUnionMergeStrategy,
32− testUnionPreferMergeStrategy
35+ testUnionPreferMergeStrategy,
36+ testUnionMergeIncDepViolation
3337 ]
3438
3539-- | Create a transaction graph with two branches and no changes between them.
@@ -44,7 +48,7 @@ createTrans tid info ctx = Transaction tid info (Schemas ctx M.empty)
4448
4549basicTransactionGraph :: IO TransactionGraph
4650basicTransactionGraph = do
47− let bsGraph = bootstrapTransactionGraph uuidRoot DBC.empty --dateExamples
51+ let bsGraph = bootstrapTransactionGraph uuidRoot DBC.basicDatabaseContext
4852 rootTrans = case transactionForHead "master" bsGraph of
4953 Just trans -> trans
5054 Nothing -> error "bonk"
@@ -221,3 +225,38 @@ testUnionMergeStrategy = TestCase $ do
221225 case failingMerge of
222226 Right _ -> assertFailure "expected merge failure"
223227 Left err -> assertEqual "merge failure" err (MergeTransactionError StrategyViolatesRelationVariableMergeError)
228+
229+-- test that a merge will fail if a constraint is violated
230+testUnionMergeIncDepViolation :: Test
231+testUnionMergeIncDepViolation = TestCase $ do
232+ graph <- basicTransactionGraph
233+ assertGraph graph
234+
235+ branchBTrans <- assertMaybe (transactionForHead "branchB" graph) "failed to get branchB head"
236+ branchATrans <- assertMaybe (transactionForHead "branchA" graph) "failed to get branchA head"
237+
238+ --add relvar and key constraint to both branches
239+ let eRel val = mkRelationFromList (attributesFromList [Attribute "x" IntAtomType, Attribute "y" IntAtomType]) [[IntAtom 1, IntAtom val]]
240+ rvName = "x"
241+ Right branchArv = eRel 2
242+ Right branchBrv = eRel 3
243+ branchAContext = (concreteDatabaseContext branchBTrans) {relationVariables = M.singleton rvName branchArv}
244+ branchBContext = (concreteDatabaseContext branchBTrans) {relationVariables = M.singleton rvName branchBrv,
245+ inclusionDependencies = M.singleton incDepName incDep}
246+ incDepName = "x_key"
247+ incDep = inclusionDependencyForKey (AttributeNames (S.singleton "x")) (RelationVariable "x" ())
248+
249+
250+ --add the rv in new commits to both branches
251+ (_, graph') <- addTransaction "branchB" (createTrans (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) branchBContext) graph
252+
253+ (_, graph'') <- addTransaction "branchA" (createTrans (fakeUUID 4) (TransactionInfo (transactionId branchATrans) S.empty) branchAContext) graph'
254+
255+ --check that the union merge fails due to a violated constraint
256+ let eMerge = mergeTransactions (fakeUUID 5) (fakeUUID 3) UnionMergeStrategy ("branchA", "branchB") graph''
257+ case eMerge of
258+ Left (InclusionDependencyCheckError incDepName) -> pure ()
259+ Left err -> assertFailure ("other error: " ++ show err)
260+ Right trans -> do
261+ assertFailure "constraint violation missing"
262+