
    Qi%                    B   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlmZ ddlZdZee	j                  vre	j                  j                  de       ddlmZmZ ddlmZ 	 	 d	 	 	 	 	 	 	 	 	 ddZ e       Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#y)uy  
tests/track_b/test_story_7_01.py

Story 7.01: ConflictDetector — Patch Contradiction Analysis

Black Box Tests (BB1–BB5):
    BB1  Two deltas with same path + different values → has_conflicts=True
    BB2  Two deltas touching different paths → has_conflicts=False, fast_merge returns both patches
    BB3  Empty deltas list → has_conflicts=False, non_conflicting_deltas=[]
    BB4  Single delta → has_conflicts=False
    BB5  Add at /x + Remove at /x → op_contradiction detected

White Box Tests (WB1–WB5):
    WB1  conflicting_paths contains the actual path string
    WB2  fast_merge returns flat list of all patches merged (concatenated)
    WB3  conflict_types list populated correctly
    WB4  non_conflicting_deltas excludes conflicting ones
    WB5  Handles StateDelta with tuple patch (converts to list internally)

Package Test:
    PKG  __init__.py imports work
    )annotationsN)datetimez/mnt/e/genesis-systemConflictDetectorConflictReport)
StateDeltac                P    t        | ||t        |      t        dddddd            S )z;Create a StateDelta with the given patch (stored as tuple).i           r   )agent_id
session_idversion_at_readpatchsubmitted_at)r   tupler   )r   r   r   versions       6/mnt/e/genesis-system/tests/track_b/test_story_7_01.py
make_deltar   4   s3     EldAr2q!4     c                    t        dddddg      } t        dddddg      }t        j                  | |g      }|j                  }d}||u }|st	        j
                  d	|fd
||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}x}}|j                  }t        |      }d}	||	kD  }
|
s t	        j
                  d|
fd||	f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      t	        j                  |	      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}x}x}
}	y)uJ   BB1: Two deltas write to the same path with different values → conflict.agent-Areplace/statusactiveoppathvalueagent-BinactiveTisz5%(py2)s
{%(py2)s = %(py0)s.has_conflicts
} is %(py5)sreportpy0py2py5z"Expected a conflict to be detectedz
>assert %(py7)spy7Nr   )>)zV%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.conflicting_paths
})
} > %(py8)slenr'   py1py3r)   py8z&Expected at least one conflicting pathz
>assert %(py10)spy10)r   DETECTORdetecthas_conflicts
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationconflicting_pathsr,   )delta_adelta_br%   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_assert2@py_assert7@py_assert6@py_format9@py_format11s                r   (test_bb1_path_collision_different_valuesrK   L   su   IyS[%\$]^GIyS]%^$_`G__gw/0FM4M4'MMM4MMMMMM6MMM6MMMMMM4MMM)MMMMMMMM''V3'(V1V(1,VVV(1VVVVVV3VVV3VVVVVVvVVVvVVV'VVV(VVV1VVV.VVVVVVVVr   c                 	   t        dddddg      } t        dddddg      }t        j                  | |g      }|j                  }d	}||u }|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|j                  }t        |      }d}	||	k(  }
|
s
t	        j
                  d|
fd||	f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      t	        j                  |	      dz  }dd|iz  }t        t	        j                  |            dx}x}x}
}	t        j                  |j                        }t        |      }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|D ch c]  }|d   	 }}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndd z  }d!d"|iz  }t        t	        j                  |            dx}}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndd z  }d!d"|iz  }t        t	        j                  |            dx}}yc c}w )#uU   BB2: Two deltas writing to different paths → no conflict; fast_merge combines both.r   addz/foo   r   r    z/barr
   Fr"   r$   r%   r&   assert %(py7)sr*   N==)z\%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.non_conflicting_deltas
})
} == %(py8)sr,   r-   zassert %(py10)sr1   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)smergedr'   r.   r/   py6assert %(py8)sr0   r   inz%(py1)s in %(py3)spathsr.   r/   assert %(py5)sr)   )r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   non_conflicting_deltasr,   
fast_merge)r?   r@   r%   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rS   @py_assert5@py_format7r   rZ   @py_assert0@py_format4s                       r   $test_bb2_different_paths_no_conflictrc   W   s   E6A%N$OPGE6A%N$OPG__gw/0F(5(5((((5((((((6(((6((((((5(((((((,,23,-22-2222-22222232223222222v222v222,222-2222222222  !>!>?Fv;!;!;!33vv;!"()BRZ)E)6U?6U6UU6U?6U6UU *s   'S c                    t         j                  g       } | j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }g }||k(  }|st        j                  d	|fd
||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }g }||k(  }|st        j                  d	|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)uE   BB3: Empty deltas → has_conflicts=False, non_conflicting_deltas=[].Fr"   r$   r%   r&   rO   r*   NrP   z>%(py2)s
{%(py2)s = %(py0)s.non_conflicting_deltas
} == %(py5)s)z9%(py2)s
{%(py2)s = %(py0)s.conflicting_paths
} == %(py5)s)r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   r]   r>   )r%   rA   rB   rC   rD   rE   s         r   test_bb3_empty_listrf   h   sf   __R F(5(5((((5((((((6(((6((((((5(((((((((.B.(B....(B......6...6...(...B.......##)r)#r))))#r))))))6)))6)))#)))r)))))))r   c                 r   t        dddddg      } t        j                  | g      }|j                  }d}||u }|st	        j
                  d|fd||f      d	t        j                         v st	        j                  |      rt	        j                  |      nd	t	        j                  |      t	        j                  |      d
z  }dd|iz  }t        t	        j                  |            dx}x}}|j                  }| g}||k(  }|st	        j
                  d|fd||f      d	t        j                         v st	        j                  |      rt	        j                  |      nd	t	        j                  |      t	        j                  |      d
z  }dd|iz  }t        t	        j                  |            dx}x}}y)u+   BB4: Single delta → no conflict possible.zagent-XrM   z/k*   r   Fr"   r$   r%   r&   rO   r*   NrP   re   r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   r]   )deltar%   rA   rB   rC   rD   rE   s          r   test_bb4_single_deltark   q   s   y%#K"LME__eW%F(5(5((((5((((((6(((6((((((5(((((((((3UG3(G3333(G33333363336333(333G3333333r   c                    t        dddddg      } t        ddddg      }t        j                  | |g      }|j                  }d	}||u }|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}d}|j                  }||v }	|	st	        j
                  d|	fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}	}y)uF   BB5: One delta adds at /x, another removes at /x → op_contradiction.r   rM   z/xhellor   r    remove)r   r   Tr"   r$   r%   r&   rO   r*   Nop_contradictionrW   )z6%(py1)s in %(py5)s
{%(py5)s = %(py3)s.conflict_types
}r.   r/   r)   )r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   conflict_types)
r?   r@   r%   rA   rB   rC   rD   rE   ra   rF   s
             r   'test_bb5_add_vs_remove_op_contradictionrr   {   s&   E4'%R$STGHd%C$DEG__gw/0F'4'4''''4''''''6'''6''''''4'''''''6!6!66!66666!6666666666666666!66666666r   c                    t        dddddg      } t        dddddg      }t        j                  | |g      }d}|j                  }||v }|st	        j
                  d|fd	||f      t	        j                  |      d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}y)zFWB1: conflicting_paths contains the exact path string that conflicted.r   r   z/config/modefastr   r    slowrW   )z9%(py1)s in %(py5)s
{%(py5)s = %(py3)s.conflicting_paths
}r%   rp   rO   r*   N)r   r2   r3   r>   r5   r6   r:   r7   r8   r9   r<   r=   )r?   r@   r%   ra   rB   rF   rD   rE   s           r   /test_wb1_conflicting_paths_contains_path_stringrv      s    I~X^%_$`aGI~X^%_$`aG__gw/0F5V555>55555>5555>555555V555V55555555555r   c                    ddddddddg} ddddg}t        d	|       }t        d
|      }t        j                  ||g      }|j                  }d}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            dx}x}}t        j                  |j                        }
t        |
      }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |
      rt	        j                  |
      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|
D cg c]  }|d   	 }}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd |iz  }t        t	        j                  |            dx}}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd |iz  }t        t	        j                  |            dx}}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd |iz  }t        t	        j                  |            dx}}yc c}w )!zOWB2: fast_merge returns a flat list of all ops from all non-conflicting deltas.rM   z/arN   r   z/br
   z/c   r   r    Fr"   r$   r%   r&   rO   r*   NrP   rR   r,   rS   rT   rV   r0   r   rW   rY   rZ   r[   r\   r)   )r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   r^   r]   r,   )ops_aops_br?   r@   r%   rA   rB   rC   rD   rE   rS   rF   r_   r`   rI   r   rZ   ra   rb   s                      r   ,test_wb2_fast_merge_concatenates_all_patchesr{      s   4!4UD[\6]^E4!45EE*GE*G __gw/0F(5(5((((5((((((6(((6((((((5(((((((  !>!>?Fv;!;!;!33vv;!"()BRZ)E)45=4545545=4545545=45455 *s   =P;c                 h   t        dddddg      } t        dddddg      }t        j                  | |g      j                  }d}||u }|st	        j
                  d	|fd
||f      dt        j                         v st	        j                        rt	        j                        ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}fddD        }t        |      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }t        t	        j                  |            dx}}y)z?WB3: conflict_types list records the correct conflict category.r   r   z/val
   r   r       Tr"   r$   r%   r&   rO   r*   Nc              3  :   K   | ]  }|j                   v   y w)N)rq   ).0ctr%   s     r   	<genexpr>z>test_wb3_conflict_types_populated_correctly.<locals>.<genexpr>   s     brrV***bs   )semantic_contradictionpath_collisionz,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr'   r(   py4)r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   r   )	r?   r@   rA   rB   rC   rD   rE   @py_format5r%   s	           @r   +test_wb3_conflict_types_populated_correctlyr      s    IvPR%S$TUGIvPR%S$TUG__gw/0F'4'4''''4''''''6'''6''''''4'''''''b5abb3bbbbbbbbb3bbb3bbbbbbbbbbbbbbr   c                    t        dddddg      } t        dddddg      }t        dd	d
ddg      }t        j                  | ||g      }|j                  }d}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|j                  }||v }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}}|j                  }| |v}|st	        j
                  d|fd| |f      dt        j                         v st	        j                  |       rt	        j                  |       nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}}|j                  }||v}|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}}y)zVWB4: When 1-of-3 deltas conflicts with another, the clean third is in non_conflicting.r   r   z/sharedXr   r    Yzagent-CrM   z/uniquec   Tr"   r$   r%   r&   rO   r*   NrW   )z>%(py0)s in %(py4)s
{%(py4)s = %(py2)s.non_conflicting_deltas
}delta_cleanr   zassert %(py6)srU   )not in)zB%(py0)s not in %(py4)s
{%(py4)s = %(py2)s.non_conflicting_deltas
}delta_conflict_adelta_conflict_bri   )r   r   r   r%   rA   rB   rC   rD   rE   r   r`   s              r   4test_wb4_non_conflicting_deltas_excludes_conflictingr      s]   !)Y	\_.`-ab!)Y	\_.`-abYySU)V(WXK__.0@+NOF'4'4''''4''''''6'''6''''''4''''''' 777;77777;7777777;777;777777&777&77777777777#)#@#@@#@@@@@#@@@@@@@@@@@@@@@@6@@@6@@@#@@@@@@@@#)#@#@@#@@@@@#@@@@@@@@@@@@@@@@6@@@6@@@#@@@@@@@@r   c                    t        dddddg      } t        dddddg      }| j                  }t        |t              }|sdd	t	        j
                         v st        j                  t              rt        j                  t              nd	d
t	        j
                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            dx}}|j                  }t        |t              }|sdd	t	        j
                         v st        j                  t              rt        j                  t              nd	dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            dx}}t        j                  | |g      }|j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}y)zQWB5: StateDelta stores patch as a tuple; ConflictDetector converts it internally.r   rM   z/talphar   r    betazPassert %(py6)s
{%(py6)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.patch
}, %(py4)s)
}
isinstancer?   r   )r'   r.   r/   r   rU   Nr@   Tr"   r$   r%   r&   rO   r*   )r   r   r   r   r7   r8   r5   r9   r:   r<   r=   r2   r3   r4   r6   )r?   r@   rF   r_   r`   r%   rA   rB   rC   rD   rE   s              r   test_wb5_handles_tuple_patchr      s    E4'%R$STGE4&%Q$RSG mm+:mU++++++++:+++:++++++g+++g+++m++++++U+++U++++++++++mm+:mU++++++++:+++:++++++g+++g+++m++++++U+++U++++++++++ __gw/0F'4'4''''4''''''6'''6''''''4'''''''r   c                    ddl m} m} | t        u }|st        j                  d|fd| t        f      dt        j                         v st        j                  |       rt        j                  |       nddt        j                         v st        j                  t              rt        j                  t              nddz  }dd	|iz  }t        t        j                  |            d
}|t        u }|st        j                  d|fd|t        f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              nddz  }dd	|iz  }t        t        j                  |            d
}y
)zHPKG: core.merge __init__.py exports ConflictDetector and ConflictReport.r   r   r"   )z%(py0)s is %(py2)sCDr   )r'   r(   zassert %(py4)sr   NCRr   )
core.merger   r   r5   r6   r7   r8   r9   r:   r<   r=   )r   r   rA   @py_format3r   s        r   test_pkg_init_importsr      s    G!!!!!2!!!!!!!2!!!2!!!!!!!!!!!!!!!!!!222r   c                    t        dddddg      } t        dddddg      }t        j                  | |g      }|j                  }d}||u }|st	        j
                  d|fd	||f      d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}y)zGTwo deltas writing the same value to the same path should NOT conflict.r   r   r   okr   r    Fr"   r$   r%   r&   rO   r*   N)r   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   )r?   r@   r%   rA   rB   rC   rD   rE   s           r   test_same_value_no_conflictr      s    IySW%X$YZGIySW%X$YZG__gw/0F (5(5((((5((((((6(((6((((((5(((((((r   c                 z   t         j                  g       } g }| |k(  }|st        j                  d|fd| |f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)z.fast_merge with empty list returns empty list.rP   )z%(py0)s == %(py3)srS   )r'   r/   r\   r)   N)
r2   r^   r5   r6   r7   r8   r9   r:   r<   r=   )rS   rF   rA   rb   rD   s        r   test_fast_merge_empty_inputr      sj      $F6R<6R66Rr   )zsess-001rN   )
r   strr   z
list[dict]r   r   r   intreturnr   )$__doc__
__future__r   builtinsr7   _pytest.assertion.rewrite	assertionrewriter5   sysosr   pytestGENESIS_ROOTr   insertcore.merge.conflict_detectorr   r   core.coherence.state_deltar   r   r2   rK   rc   rf   rk   rr   rv   r{   r   r   r   r   r   r    r   r   <module>r      s   . #   
 	   'sxxHHOOA|$ J 1 !	  	
   W"*47 6&
cA (( )r   