
    Vh3V                     H   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d Z	 G d de      Z
 e e	        d       G d de
             Z e e	        d       G d	 d
e
             Z e e	        d       G d de             Z e e	        d       G d de
             Zy)    N)skipIfTestCasec                  :    	 t        d       y# t        $ r Y yw xY w)NtwistedTF)
__import__ImportError     K/home/dcms/DCMS/lib/python3.12/site-packages/automat/_test/test_discover.pyisTwistedInstalledr   
   s(    9   s    	c                   P     e Zd ZdZ fdZ fdZd Zd Zd Zd Z	d Z
d	 Z xZS )
_WritesPythonModuleszG
    A helper that enables generating Python module test fixtures.
    c                 `   t         t        |           ddlm}m} ddlm} || _        || _        || _        t        t        j                  j                               | _        t        j                  d d  | _        t        j                          | _        | j%                  | j"                         y )Nr   )	getModule
PythonPath)FilePath)superr   setUptwisted.python.modulesr   r   twisted.python.filepathr   setsysmoduleskeysoriginalSysModulespathsavedSysPathtempfilemkdtemppathDirmakeImportable)selfr   r   r   	__class__s       r   r   z_WritesPythonModules.setUp   sx    "D/1@4"$ "%ckk&6&6&8"9HHQK'')DLL)r
   c                 (   t         t        |           | j                  t        j
                  d d  t        j                  j                         | j                  z
  }|D ]  }t        j                  |=  t        j                  | j                         y N)r   r   tearDownr   r   r   r   r   r   shutilrmtreer    )r"   modulesToDeletemoduler#   s      r   r&   z_WritesPythonModules.tearDown(   sn    "D24''++**,t/F/FF% 	$FF#	$ 	dll#r
   c                 B    t         j                  j                  |       y r%   )r   r   append)r"   r   s     r   r!   z#_WritesPythonModules.makeImportable2   s    r
   c                    | j                  |      }|j                  |      }t        |j                  d      5 }|j	                  t        j                  |             d d d        | j                  |j                  g      S # 1 sw Y   %xY w)Nw)r   childopenr   writetextwrapdedentr   )r"   sourcer   
moduleName	directoryr*   fs          r   writeSourceIntoz$_WritesPythonModules.writeSourceInto5   sr    MM$'	, &++s# 	-qGGHOOF+,	- 	/00	- 	-s   %BBc                 r    t         j                  j                  |      \  }}| j                  |||      |   S r%   )osr   splitextr8   )r"   r4   r   r5   pythonModuleName_s         r   
makeModulez_WritesPythonModules.makeModule@   s7     gg..z:!##FD*=>NOOr
   c                 ^    |j                         D ci c]  }|j                  | c}S c c}w r%   )iterAttributesname)r"   hasIterAttributesattrs      r   attributesAsDictz%_WritesPythonModules.attributesAsDictD   s'    ,=,L,L,NOD		4OOOs   *c                 D    |j                          | j                  |      S r%   )loadrD   )r"   r*   s     r   loadModuleAsDictz%_WritesPythonModules.loadModuleAsDictG   s    $$V,,r
   c                 F    | j                  | j                  |||            S r%   )rG   r>   )r"   r4   r   rA   s       r   makeModuleAsDictz%_WritesPythonModules.makeModuleAsDictK   s     $$T__VT4%HIIr
   )__name__
__module____qualname____doc__r   r&   r!   r8   r>   rD   rG   rI   __classcell__r#   s   @r   r   r      s3    * $	1PP-Jr
   r   zTwisted is not installed.c                   4     e Zd ZdZ fdZd Zd Zd Z xZS )OriginalLocationTestsa  
    Tests that L{isOriginalLocation} detects when a
    L{PythonAttribute}'s FQPN refers to an object inside the module
    where it was defined.

    For example: A L{twisted.python.modules.PythonAttribute} with a
    name of 'foo.bar' that refers to a 'bar' object defined in module
    'baz' does *not* refer to bar's original location, while a
    L{PythonAttribute} with a name of 'baz.bar' does.

    c                 D    t         t        |           ddlm} || _        y )N   )isOriginalLocation)r   rQ   r   	_discoverrT   )r"   rT   r#   s     r   r   zOriginalLocationTests.setUp]   s    #T022"4r
   c                     d}| j                  || j                  d      }| j                  | j                  |d                y)z
        L{isOriginalLocation} returns False when the attribute refers to an
        object whose source module cannot be determined.
        z~        class Fake(object):
            pass
        hasEmptyModule = Fake()
        hasEmptyModule.__module__ = None
        zempty_module_attr.pyz empty_module_attr.hasEmptyModuleN)rI   r    assertFalserT   )r"   r4   
moduleDicts      r   test_failsWithNoModulez,OriginalLocationTests.test_failsWithNoModulec   sF    
 **64<<AWX
##J/Q$RS	
r
   c                    d}d}| j                  || j                  d       | j                  || j                  d      }| j                  | j	                  |d                | j                  | j	                  |d                |d   }| j                  |      }|d   }| j                  | j	                  |             y	)
z
        L{isOriginalLocation} returns False when the attribute refers to
        an object outside of the module where that object was defined.
        z        class ImportThisClass(object):
            pass
        importThisObject = ImportThisClass()
        importThisNestingObject = ImportThisClass()
        importThisNestingObject.nestedObject = ImportThisClass()
        z        from original import (ImportThisClass,
                              importThisObject,
                              importThisNestingObject)
        original.pyimporting.pyzimporting.ImportThisClasszimporting.importThisObjectz!importing.importThisNestingObjectz.importing.importThisNestingObject.nestedObjectN)r>   r    rI   rW   rT   rD   )r"   originalSourceimportingSourceimportingDictnestingObjectnestingObjectDictnestedObjects          r   test_failsWithDifferentModulez3OriginalLocationTests.test_failsWithDifferentModuleu   s    
 	mD--T\\>
 	##M2M$NO	
 	##M2N$OP	
 &&IJ 11-@(<
 	00>?r
   c                 j   t        j                  d      }| j                  || j                  d      }| j	                  | j                  |d                | j	                  | j                  |d                |d   }| j                  |      }|d   }| j	                  | j                  |             y)z
        L{isOriginalLocation} returns True when the attribute refers to an
        object inside the module where that object was defined.
        z
        class ThisClassWasDefinedHere(object):
            pass
        anObject = ThisClassWasDefinedHere()
        aNestingObject = ThisClassWasDefinedHere()
        aNestingObject.nestedObject = ThisClassWasDefinedHere()
        zm.pyzm.ThisClassWasDefinedHerezm.aNestingObjectzm.aNestingObject.nestedObjectN)r2   r3   rI   r    
assertTruerT   rD   )r"   mSourcemDictr`   ra   rb   s         r   test_succeedsWithSameModulez1OriginalLocationTests.test_succeedsWithSameModule   s    
 //
 %%gt||VD//6Q0RST//6H0IJK01 11-@()HI//=>r
   )	rJ   rK   rL   rM   r   rY   rc   rh   rN   rO   s   @r   rQ   rQ   O   s    
5
$$@L?r
   rQ   c                   `     e Zd ZdZ fdZd ZddZd Zd Zd Z	d Z
d	 Zd
 Zd Zd Z xZS )FindMachinesViaWrapperTestsz
    L{findMachinesViaWrapper} recursively yields FQPN,
    L{MethodicalMachine} pairs in and under a given
    L{twisted.python.modules.PythonModule} or
    L{twisted.python.modules.PythonAttribute}.
    c                 D    t         t        |           ddlm} || _        y )NrS   )findMachinesViaWrapper)r   rj   r   rU   rl   )r"   rl   r#   s     r   r   z!FindMachinesViaWrapperTests.setUp   s    )4686&<#r
   c                     d}| j                  || j                  d      }|d   }| j                  d|j                         ft	        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonAttribute} that refers
        directly to a L{MethodicalMachine}, L{findMachinesViaWrapper}
        yields that machine and its FQPN.
        a        from automat import MethodicalMachine

        rootMachine = MethodicalMachine()
        root.pyroot.rootMachineNrI   r    assertInrF   listrl   r"   r4   rX   rootMachines       r   test_yieldsMachinez.FindMachinesViaWrapperTests.test_yieldsMachine   s^     **64<<K
 !34!1!1!34,,[9:	
r
   c                     d}| j                  || j                  d      }|d   }| j                  d|j                         ft	        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonAttribute} that refers
        directly to a L{TypeMachine}, L{findMachinesViaWrapper} yields that
        machine and its FQPN.
        ae          from automat import TypeMachineBuilder
        from typing import Protocol, Callable
        class P(Protocol):
            def method(self) -> None: ...
        class C:...
        def buildBuilder() -> Callable[[C], P]:
            builder = TypeMachineBuilder(P, C)
            return builder.build()
        rootMachine = buildBuilder()
        ro   rp   Nrq   rt   s       r   test_yieldsTypeMachinez2FindMachinesViaWrapperTests.test_yieldsTypeMachine   s^    
 **64<<K
 !34!1!1!34,,[9:	
r
   c                     d}| j                  || j                  d      }|d   }| j                  d|j                         j                  ft        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a class that contains a L{MethodicalMachine} as a class
        variable, L{findMachinesViaWrapper} yields that machine and
        its FQPN.
                from automat import MethodicalMachine

        class PythonClass(object):
            _classMachine = MethodicalMachine()
        	clsmod.pyclsmod.PythonClass clsmod.PythonClass._classMachineN)rI   r    rr   rF   _classMachiners   rl   r"   r4   rX   PythonClasss       r   test_yieldsMachineInClassz5FindMachinesViaWrapperTests.test_yieldsMachineInClass   sd     **64<<M
 !56/1A1A1C1Q1QR,,[9:	
r
   c                     d}| j                  || j                  d      }|d   }| j                  d|j                         j                  j
                  ft        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a nested class that contains a L{MethodicalMachine} as a
        class variable, L{findMachinesViaWrapper} yields that machine
        and its FQPN.
                from automat import MethodicalMachine

        class PythonClass(object):
            class NestedClass(object):
                _classMachine = MethodicalMachine()
        nestedcls.pynestedcls.PythonClass/nestedcls.PythonClass.NestedClass._classMachineN)rI   r    rr   rF   NestedClassr~   rs   rl   r   s       r   test_yieldsMachineInNestedClassz;FindMachinesViaWrapperTests.test_yieldsMachineInNestedClass  so     **64<<P
 !89A  "..<< ,,[9:	
r
   c                     d}| j                  || j                  d      }| j                  |      d   j                         }| j	                  d|ft        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonModule} that refers to
        a module that contains a L{MethodicalMachine},
        L{findMachinesViaWrapper} yields that machine and its FQPN.
        rn   ro   rp   N)r>   r    rG   rF   rr   rs   rl   )r"   r4   r*   ru   s       r   test_yieldsMachineInModulez6FindMachinesViaWrapperTests.test_yieldsMachineInModule  sg    
 yA++F34FGLLN-tD4O4OPV4W/X	
r
   c                     d}| j                  || j                  d      }| j                  |      d   j                         }| j	                  d|j
                  ft        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonModule} that refers to
        the original module of a class containing a
        L{MethodicalMachine}, L{findMachinesViaWrapper} yields that
        machine and its FQPN.
        rz   r{   r|   r}   N)r>   r    rG   rF   rr   r~   rs   rl   r"   r4   r*   r   s       r   !test_yieldsMachineInClassInModulez=FindMachinesViaWrapperTests.test_yieldsMachineInClassInModule-  sm     {C++F34HINNP/1J1JK,,V45	
r
   c                    d}| j                  || j                  d      }| j                  |      d   j                         }| j	                  d|j
                  j                  ft        | j                  |                   y)z
        When given a L{twisted.python.modules.PythonModule} that refers to
        the original module of a nested class containing a
        L{MethodicalMachine}, L{findMachinesViaWrapper} yields that
        machine and its FQPN.
        r   r   r   r   N)	r>   r    rG   rF   rr   r   r~   rs   rl   r   s       r   'test_yieldsMachineInNestedClassInModulezCFindMachinesViaWrapperTests.test_yieldsMachineInNestedClassInModuleA  sx     ~F++F34KLQQSA''55 ,,V45	
r
   c                     d}d}| j                  || j                  d       | j                  || j                  d      }| j                  t        | j	                  |                   y)aM  
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a class imported from another module, any
        L{MethodicalMachine}s on that class are ignored.

        This behavior ensures that a machine is only discovered on a
        class when visiting the module where that class was defined.
        z
        from automat import MethodicalMachine

        class PythonClass(object):
            _classMachine = MethodicalMachine()
        z2
        from original import PythonClass
        r[   r\   Nr>   r    rW   rs   rl   )r"   r]   r^   importingModules       r   test_ignoresImportedClassz5FindMachinesViaWrapperTests.test_ignoresImportedClassZ  sZ     	mD///4<<Xd99/JKLr
   c                    | j                  | j                  g      }| j                  | j                        j                  d      }|j	                          |j                  d      j                          d}| j                  ||j                  d       |d   }t        | j                  |      t        j                  d            }| j                  |d         }|d   j                         }|d	   j                         }t        d|fd
|j                  fgt        j                  d            }	| j                  |	|       y)z`
        L{findMachinesViaWrapper} descends into packages to discover
        machines.
        test_package__init__.pyz
        from automat import MethodicalMachine


        class PythonClass(object):
            _classMachine = MethodicalMachine()


        rootMachine = MethodicalMachine()
        	module.pyr   keyr*   ztest_package.module.rootMachineztest_package.module.PythonClassz-test_package.module.PythonClass._classMachineN)r   r    r   r/   makedirstouchr>   r   sortedrl   operator
itemgetterrG   rF   r~   assertEqual)
r"   
pythonPathpackager4   r   machinesrX   ru   r   expectedMachiness
             r   test_descendsIntoPackagesz5FindMachinesViaWrapperTests.test_descendsIntoPackagess  s-   
 __dll^4
---33NCm$**,	 	k:!.1''58;N;Nq;Q
 **<+AB
 !BCHHJ !BCHHJ!2K@C-- ##A&	
 	)84r
   c                     d}| j                  || j                  d      }| j                  t        | j	                  |                   y)z
        L{findMachinesViaWrapper} ignores infinite loops.

        Note this test can't fail - it can only run forever!
        zh
        class InfiniteLoop(object):
            pass

        InfiniteLoop.loop = InfiniteLoop
        zloop.pyNr   )r"   r4   r*   s      r   test_infiniteLoopz-FindMachinesViaWrapperTests.test_infiniteLoop  s?     yAd99&ABCr
   )returnN)rJ   rK   rL   rM   r   rv   rx   r   r   r   r   r   r   r   r   rN   rO   s   @r   rj   rj      sB    =
&
2
(
2
"
(
2M2*5XDr
   rj   c                   ^    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d Zd Zy)WrapFQPNTestsz
    Tests that ensure L{wrapFQPN} loads the
    L{twisted.python.modules.PythonModule} or
    L{twisted.python.modules.PythonAttribute} for a given FQPN.
    c                     ddl m}m} ddlm}m}m}m} || _        || _        || _        || _        || _        || _        y )Nr   )PythonModulePythonAttributerS   )wrapFQPNInvalidFQPNNoModuleNoObject)r   r   r   rU   r   r   r   r   )r"   r   r   r   r   r   r   s          r   r   zWrapFQPNTests.setUp  s8    HII(. &  r
   c                     | j                  || j                         | j                  |j                  |j                         | j                  |j                         |       y)zt
        Assert that a L{twisted.python.modules.PythonModule} refers to a
        particular Python module.
        N)assertIsInstancer   r   rA   rJ   assertIsrF   )r"   moduleWrapperr*   s      r   assertModuleWrapperRefersToz)WrapFQPNTests.assertModuleWrapperRefersTo  sK    
 	mT->->?++V__=m((*F3r
   c                     | j                  || j                         | j                  |j                  |       | j	                  |j                         |       y)zw
        Assert that a L{twisted.python.modules.PythonAttribute} refers to a
        particular Python object.
        N)r   r   r   rA   r   rF   )r"   attributeWrapperfqpnobjs       r   assertAttributeWrapperRefersToz,WrapFQPNTests.assertAttributeWrapperRefersTo  sJ    
 	.0D0DE)..5&++-s3r
   c                     | j                  | j                        5  | j                  d       ddd       y# 1 sw Y   yxY w)zO
        L{wrapFQPN} raises L{InvalidFQPN} when given an empty string.
         NassertRaisesr   r   r"   s    r   test_failsWithEmptyFQPNz%WrapFQPNTests.test_failsWithEmptyFQPN  s9     t//0 	MM"	 	 		   7A c                     dD ]7  }| j                  | j                        5  | j                  |       ddd       9 y# 1 sw Y   DxY w)zl "
        L{wrapFQPN} raises L{InvalidFQPN} when given a badly-dotted
        FQPN.  (e.g., x..y).
        )z.failszfails.zthis..failsNr   r"   bads     r   test_failsWithBadDottingz&WrapFQPNTests.test_failsWithBadDotting  sM    
 7 	#C""4#3#34 #c"# #	## #	   >A	c                     ddl }| j                  d      }| j                  || j                         | j	                  |j                         |       y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the single module a dotless FQPN describes.
        r   Nr:   )r:   r   r   r   r   rF   )r"   r:   r   s      r   test_singleModulezWrapFQPNTests.test_singleModule  sB    
 	d+mT->->?m((*B/r
   c                     | j                  | j                        5  | j                  d       ddd       y# 1 sw Y   yxY w)z~
        L{wrapFQPN} raises L{NoModule} when given a dotless FQPN that does
        not refer to a module or package.
        zthis is not an acceptable name!N)r   r   r   r   s    r   *test_failsWithMissingSingleModuleOrPackagez8WrapFQPNTests.test_failsWithMissingSingleModuleOrPackage  s8    
 t}}- 	=MM;<	= 	= 	=r   c                 N    ddl }| j                  | j                  d      |       y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the single package a dotless FQPN describes.
        r   Nxml)r   r   r   r"   r   s     r   test_singlePackagez WrapFQPNTests.test_singlePackage  s     
 	((u)=sCr
   c                 b    ddl }| j                  | j                  d      |j                         y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the deepest package described by dotted FQPN.
        r   Nz	xml.etree)	xml.etreer   r   etreer   s     r   test_multiplePackagesz#WrapFQPNTests.test_multiplePackages  s$    
 	(({)CSYYOr
   c                 v    ddl }| j                  | j                  d      |j                  j                         y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the deepest module described by dotted FQPN.
        r   Nzxml.etree.ElementTree)xml.etree.ElementTreer   r   r   ElementTreer   s     r    test_multiplePackagesFinalModulez.WrapFQPNTests.test_multiplePackagesFinalModule
  s.    
 	%((MM12CII4I4I	
r
   c                 d    ddl }| j                  | j                  d      d|j                         y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonAttribute}
        referring to the deepest object an FQPN names, traversing one module.
        r   Nzos.path)r:   r   r   r   )r"   r:   s     r   test_singleModuleObjectz%WrapFQPNTests.test_singleModuleObject  s)    
 	++MM)$i	
r
   c                     ddl }ddl}d|j                  j                  j                  fd|j
                  j                  ffD ]'  \  }}| j                  | j                  |      ||       ) y)z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonAttribute}
        referring to the deepest object described by an FQPN,
        descending through several packages.
        r   Nz xml.etree.ElementTree.fromstringz!automat.MethodicalMachine.__doc__)	r   automatr   r   
fromstringMethodicalMachinerM   r   r   )r"   r   r   r   r   s        r   test_multiplePackagesObjectz)WrapFQPNTests.test_multiplePackagesObject   sl     	% 01F1F1Q1QR0'2K2K2S2ST
 	PID# //d0CT3O		Pr
   c                     dD ]7  }| j                  | j                        5  | j                  |       ddd       9 y# 1 sw Y   DxY w)z
        L{wrapFQPN} raises L{NoObject} when given an FQPN that contains a
        missing attribute, module, or package.
        )zxml.etree.nope!z*xml.etree.nope!.but.the.rest.is.believableN)r   r   r   r   s     r   4test_failsWithMultiplePackagesMissingModuleOrPackagezBWrapFQPNTests.test_failsWithMultiplePackagesMissingModuleOrPackage/  sL    
 U 	#C""4==1 #c"# #	## #r   N)rJ   rK   rL   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r	   r
   r   r   r     sK    	!44#
0=DP	
	
P#r
   r   c                   ,     e Zd ZdZdZ fdZd Z xZS )FindMachinesIntegrationTestszs
    Integration tests to check that L{findMachines} yields all
    machines discoverable at or below an FQPN.
    z
    from automat import MethodicalMachine

    class PythonClass(object):
        _machine = MethodicalMachine()
        ignored = "i am ignored"

    rootLevel = MethodicalMachine()

    ignored = "i am ignored"
    c                    t         t        |           ddlm} || _        | j                  | j                        j                  d      }|j                          | j                  | j                  g      | _
        | j                  | j                  |j                  d       |j                  d      }|j                          |j                  d      j                          | j                  | j                  |j                  d       | j!                  | j                  d         | _        | j!                  | j                  d   d   d         | _        y )NrS   )findMachinesr   r   
subpackager   r*   )r   r   r   rU   r   r   r    r/   r   r   r   r8   SOURCEr   r   r>   rG   packageDictrX   )r"   r   
packageDirsubPackageDirr#   s       r   r   z"FindMachinesIntegrationTests.setUpL  s   *D79,(]]4<<066~F
//4<<.9T[[*//=I"((6 M*002]%7%7E001PQ//OON+L9(C
r
   c                    t        | j                  d      t        j                  d            }| j                  d   j                         }| j                  d   j                         }| j                  d   }|j                         }| j                  d   }|j                         }t        d|fd|j                  fd|fd	|j                  fgt        j                  d            }| j                  ||       y
)z
        Given a top-level package FQPN, L{findMachines} discovers all
        L{MethodicalMachine} instances in and below it.
        r   r   r   ztest_package.rootLevelztest_package.PythonClassz(test_package.subpackage.module.rootLevelz*test_package.subpackage.module.PythonClassz!test_package.PythonClass._machinez3test_package.subpackage.module.PythonClass._machineN)	r   r   r   r   r   rF   rX   _machiner   )	r"   r   tpRootLeveltpPythonClassmRLAttr
mRootLevelmPCAttrmPythonClassr   s	            r   test_discoverAllz-FindMachinesIntegrationTests.test_discoverAllb  s    
 $++N;ATATUVAWX&&'?@EEG(()CDIIK//"LM\\^
//"NO||~!);74m6L6LM;ZHI ))	 ##A&
 	)84r
   )rJ   rK   rL   rM   r   r   r   rN   rO   s   @r   r   r   9  s    

F
,5r
   r   )r   r:   r'   r   r2   r   unittestr   r   r   r   rQ   rj   r   r   r	   r
   r   <module>r      s     	  
   %9J8 9Jx   "=>a?0 a? ?a?H   "=>wD"6 wD ?wDt   "=>F#H F# ?F#R   "=>D5#7 D5 ?D5r
   