@@ -4,6 +4,7 @@ import Test.HUnit
44import ProjectM36.Base
55import ProjectM36.TransactionGraph
66import ProjectM36.TransactionGraph.Show
7+import ProjectM36.TransactionGraph.Show.Dot
78import ProjectM36.DateExamples
89import ProjectM36.Error
910import qualified Data.ByteString.Lazy as BS
@@ -12,6 +13,7 @@ import Data.Word
1213import ProjectM36.RelationalExpression
1314import qualified Data.UUID as U
1415import qualified Data.Set as S
16+import qualified Data.Map as M
1517import qualified ProjectM36.DatabaseContext as DBC
1618import Control.Monad.State hiding (join)
1719import ProjectM36.Relation (relationTrue)
@@ -24,9 +26,10 @@ main = do
2426
2527testList :: Test
2628testList = TestList [
27− testSubGraphToFirstAncestorBasic,
28− testSubGraphToFirstAncestorSnipBranch,
29− testSelectedBranchMerge
29+ --testSubGraphToFirstAncestorBasic,
30+ --testSubGraphToFirstAncestorSnipBranch,
31+ --testSelectedBranchMerge,
32+ testUnionMergeStrategy
3033 ]
3134
3235-- | Create a transaction graph with two branches and no changes between them.
@@ -45,12 +48,12 @@ basicTransactionGraph = do
4548 uuidB = fakeUUID 11
4649 uuidRoot = fakeUUID 1
4750 rootContext = transactionContext rootTrans
48− (_, bsGraph') <- addTransaction "branchA" uuidA rootContext uuidRoot bsGraph
49− (_, bsGraph'') <- addTransaction "branchB" uuidB rootContext uuidRoot bsGraph'
51+ (_, bsGraph') <- addTransaction "branchA" (Transaction uuidA (TransactionInfo uuidRoot S.empty) rootContext) bsGraph
52+ (_, bsGraph'') <- addTransaction "branchB" (Transaction uuidB (TransactionInfo uuidRoot S.empty) rootContext) bsGraph'
5053 pure bsGraph''
5154
52−addTransaction :: HeadName -> U.UUID -> DatabaseContext -> U.UUID -> TransactionGraph -> IO (Transaction, TransactionGraph)
53−addTransaction headName newTransUUID context parentTransId graph = case addTransactionToGraph headName parentTransId newTransUUID context graph of
55+addTransaction :: HeadName -> Transaction -> TransactionGraph -> IO (Transaction, TransactionGraph)
56+addTransaction headName transaction graph = case addTransactionToGraph headName transaction graph of
5457 Left err -> assertFailure (show err) >> error ""
5558 Right (t,g) -> pure (t,g)
5659
@@ -92,7 +95,7 @@ testSubGraphToFirstAncestorSnipBranch = TestCase $ do
9295 transA <- assertMaybe (transactionForHead "branchA" baseGraph) "failed to get branchA"
9396 transB <- assertMaybe (transactionForHead "branchB" baseGraph) "failed to get branchB"
9497 rootTrans <- assertEither (transactionForUUID (fakeUUID 1) baseGraph)
95− (_, graph) <- addTransaction "branchC" (fakeUUID 12) (transactionContext transA) (fakeUUID 1) baseGraph
98+ (_, graph) <- addTransaction "branchC" (Transaction (fakeUUID 12) (TransactionInfo (fakeUUID 1) S.empty) (transactionContext transA)) baseGraph
9699 subgraph <- assertEither $ subGraphOfFirstCommonAncestor graph (transactionHeadsForGraph baseGraph) transA transB S.empty
97100 assertGraph subgraph
98101 assertEqual "failed to snip branch" baseGraph subgraph
@@ -108,7 +111,8 @@ testSubGraphToFirstAncestorMoreTransactions = TestCase $ do
108111 updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (transactionContext branchBTrans) of
109112 (Just err, _) -> assertFailure (show err) >> undefined
110113 (Nothing, context) -> pure context
111− (_, graph') <- addTransaction "branchB" (fakeUUID 3) updatedBranchBContext (transactionUUID branchBTrans) graph
114+ (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionUUID branchBTrans) S.empty) updatedBranchBContext) graph
115+ --FINISH ME
112116 pure ()
113117
114118
@@ -122,8 +126,7 @@ testSelectedBranchMerge = TestCase $ do
122126 updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (transactionContext branchBTrans) of
123127 (Just err, _) -> assertFailure (show err) >> undefined
124128 (Nothing, context) -> pure context
125− (_, graph') <- addTransaction "branchB" (fakeUUID 3) updatedBranchBContext (transactionUUID branchBTrans) graph
126−
129+ (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionUUID branchBTrans) S.empty) updatedBranchBContext) graph
127130 --create the merge transaction in the graph
128131 let eGraph' = mergeTransactions (fakeUUID 4) (fakeUUID 10) (SelectedBranchMergeStrategy "branchA") ("branchA", "branchB") graph'
129132
@@ -136,8 +139,8 @@ testSelectedBranchMerge = TestCase $ do
136139 assertEqual "head of merged transaction was removed" (transactionUUID branchBTrans) (fakeUUID 3)
137140
138141 --validate that the branchB relvar does *not* appear in the merge because branchA was selected
139− mergeTrans <- assertMaybe (transactionForUUID (fakeUUID 4) graph'')
140− assertTrue "branchOnlyRelvar is present in merge" (M.notMember "branchBOnlyRelvar" (relationVariables (transactionContext mergeTrans)))
142+ mergeTrans <- assertEither (transactionForUUID (fakeUUID 4) graph'')
143+ assertBool "branchOnlyRelvar is present in merge" (M.notMember "branchBOnlyRelvar" (relationVariables (transactionContext mergeTrans)))
141144
142145-- try various individual component conflicts and check for resolution
143146testUnionPreferMergeStrategy :: Test
@@ -149,14 +152,30 @@ testUnionMergeStrategy = TestCase $ do
149152 graph <- basicTransactionGraph
150153 assertGraph graph
151154
152−
153155 branchBTrans <- assertMaybe (transactionForHead "branchB" graph) "failed to get branchB head"
154156 branchATrans <- assertMaybe (transactionForHead "branchA" graph) "failed to get branchA head"
155157 -- add another relvar to branchB - branchBOnlyRelvar should appear in the merge
156158 -- add inclusion dependency in branchA
157159
158− let updatedBranchBContext = branchBTrans {relationVariables = M.insert "branchBOnlyRelVar" (relationVariables branchBTrans) }
159− let updatedBranchAContext = branchATrans {inclusionDependencies = M.insert "branchAOnlyIncDep" (inclusionDependencies branchATrans) }
160+ let updatedBranchBContext = (transactionContext branchBTrans) {relationVariables = M.insert branchBOnlyRelVarName branchBOnlyRelVar (relationVariables (transactionContext branchBTrans)) }
161+ updatedBranchAContext = (transactionContext branchATrans) {inclusionDependencies = M.insert "branchAOnlyIncDep" branchAOnlyIncDep (inclusionDependencies (transactionContext branchATrans)) }
162+ branchBOnlyRelVar = relationTrue
163+ branchBOnlyRelVarName = "branchBOnlyRelVar"
164+ branchAOnlyIncDep = InclusionDependency (ExistingRelation relationTrue) (ExistingRelation relationTrue)
165+ assertMergeError mergeResult = case mergeResult of
166+ Left err -> assertEqual "incorrect merge failure" err (MergeTransactionError StrategyViolatesRelationVariableMergeError)
167+ Right (_, g) -> do
168+ putStrLn (graphAsDot g)
169+ assertFailure "expected merge failure"
170+
171+ (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionUUID branchBTrans) S.empty) updatedBranchBContext) graph
172+ ((DisconnectedTransaction _ mergeContext1), mergedGraph1) <- assertEither $ mergeTransactions (fakeUUID 5) (fakeUUID 1) UnionMergeStrategy ("branchA", "branchB") graph'
173+ assertEqual "branchBOnlyRelVar should appear in the merge" (M.lookup branchBOnlyRelVarName (relationVariables mergeContext1)) (Just relationTrue)
174+ --putStrLn (graphAsDot graph')
175+
176+ (_, graph'') <- addTransaction "branchA" (Transaction (fakeUUID 4) (TransactionInfo (transactionUUID branchATrans) S.empty) updatedBranchAContext) graph'
177+ let eMergeGraph = mergeTransactions (fakeUUID 5) (fakeUUID 1) UnionMergeStrategy ("branchA", "branchB") graph''
178+ --putStrLn (showGraphStructure graph'')
179+ pure ()
160180
161− (_, graph') <- addTransaction "branchB" (fakeUUID 3) updatedBranchBContext (transactionUUID branchBTrans) graph
162181