U
    ³[ÖeVU  ć                   @   sÜ   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 dl	Z	dd Z
G dd deZee
  dG dd	 d	eZee
  dG d
d deZee
  dG dd deZee
  dG dd deZdS )é    N)ŚskipIfŚTestCasec                   C   s,   zt d W n tk
r"   Y dS X dS d S )NZtwistedFT)Ś
__import__ŚImportError© r   r   ś]/var/www/html/services/stratfitenv/lib/python3.8/site-packages/automat/_test/test_discover.pyŚisTwistedInstalled   s
    r   c                       s\   e Zd ZdZ fddZ fddZdd Zdd	 Zd
d Zdd Z	dd Z
dd Z  ZS )Ś_WritesPythonModuleszG
    A helper that enables generating Python module test fixtures.
    c                    sv   t t|  ”  ddlm}m} ddlm} || _|| _|| _tt	j
 ” | _t	jd d  | _t ” | _|  | j” d S )Nr   )Ś	getModuleŚ
PythonPath)ŚFilePath)Śsuperr	   ŚsetUpŚtwisted.python.modulesr
   r   Ztwisted.python.filepathr   ŚsetŚsysŚmodulesŚkeysŚoriginalSysModulesŚpathŚsavedSysPathŚtempfileŚmkdtempŚpathDirŚmakeImportable)Śselfr
   r   r   ©Ś	__class__r   r   r      s    
z_WritesPythonModules.setUpc                    sR   t t|  ”  | jtjd d < t tj”| j	 }|D ]}tj|= q4t
 | j” d S ©N)r   r	   ŚtearDownr   r   r   ŚsixŚviewkeysr   r   ŚshutilŚrmtreer   )r   ZmodulesToDeleteŚmoduler   r   r   r   *   s    
z_WritesPythonModules.tearDownc                 C   s   t j |” d S r   )r   r   Śappend)r   r   r   r   r   r   4   s    z#_WritesPythonModules.makeImportablec              	   C   sJ   |   |”}| |”}t|jd}| t |”” W 5 Q R X |  |jg”S )NŚw)r   ŚchildŚopenr   ŚwriteŚtextwrapŚdedentr   )r   Śsourcer   Ś
moduleNameŚ	directoryr$   Śfr   r   r   ŚwriteSourceInto7   s
    

z$_WritesPythonModules.writeSourceIntoc                 C   s"   t j |”\}}|  |||”| S r   )Śosr   Śsplitextr0   )r   r,   r   r-   ZpythonModuleNameŚ_r   r   r   Ś
makeModuleB   s    z_WritesPythonModules.makeModulec                 C   s   dd |  ” D S )Nc                 S   s   i | ]}|j |qS r   )Śname)Ś.0Śattrr   r   r   Ś
<dictcomp>G   s      z9_WritesPythonModules.attributesAsDict.<locals>.<dictcomp>)ZiterAttributes)r   ZhasIterAttributesr   r   r   ŚattributesAsDictF   s    z%_WritesPythonModules.attributesAsDictc                 C   s   |  ”  |  |”S r   )Śloadr9   )r   r$   r   r   r   ŚloadModuleAsDictI   s    z%_WritesPythonModules.loadModuleAsDictc                 C   s   |   |  |||””S r   )r;   r4   )r   r,   r   r5   r   r   r   ŚmakeModuleAsDictM   s    z%_WritesPythonModules.makeModuleAsDict)Ś__name__Ś
__module__Ś__qualname__Ś__doc__r   r   r   r0   r4   r9   r;   r<   Ś__classcell__r   r   r   r   r	      s   
r	   zTwisted is not installed.c                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  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                    s$   t t|  ”  ddlm} || _d S )Né   )ŚisOriginalLocation)r   rB   r   Ś	_discoverrD   )r   rD   r   r   r   r   ^   s    zOriginalLocationTests.setUpc                 C   s,   d}|   || jd”}|  |  |d ”” dS )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)r<   r   ŚassertFalserD   )r   r,   Ś
moduleDictr   r   r   Śtest_failsWithNoModulec   s    ž’z,OriginalLocationTests.test_failsWithNoModulec                 C   s~   d}d}|   || jd” |  || jd”}|  |  |d ”” |  |  |d ”” |d }|  |”}|d }|  |  |”” d	S )
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)r4   r   r<   rF   rD   r9   )r   ŚoriginalSourceŚimportingSourceZimportingDictŚnestingObjectŚnestingObjectDictŚnestedObjectr   r   r   Śtest_failsWithDifferentModulev   s.    ž’’’’
’z3OriginalLocationTests.test_failsWithDifferentModulec                 C   sp   t  d”}|  || jd”}|  |  |d ”” |  |  |d ”” |d }|  |”}|d }|  |  |”” dS )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)r*   r+   r<   r   Ś
assertTruerD   r9   )r   ZmSourceZmDictrM   rN   rO   r   r   r   Śtest_succeedsWithSameModule   s    
’
z1OriginalLocationTests.test_succeedsWithSameModule)	r=   r>   r?   r@   r   rH   rP   rR   rA   r   r   r   r   rB   Q   s
   %rB   c                       sl   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Z  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}.
    aŹ  
    from automat import MethodicalMachine


    class PythonClass(object):
        _classMachine = MethodicalMachine()

        class NestedClass(object):
            _nestedClassMachine = MethodicalMachine()

        ignoredAttribute = "I am ignored."

        def ignoredMethod(self):
            "I am also ignored."

    rootLevelMachine = MethodicalMachine()
    ignoredPythonObject = PythonClass()
    anotherIgnoredPythonObject = "I am ignored."
    c                    s$   t t|  ”  ddlm} || _d S )NrC   )ŚfindMachinesViaWrapper)r   rS   r   rE   rT   )r   rT   r   r   r   r   Ļ   s    z!FindMachinesViaWrapperTests.setUpc                 C   s>   d}|   || jd”}|d }|  d| ” ft|  |”” dS )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)r<   r   ŚassertInr:   ŚlistrT   )r   r,   rG   ŚrootMachiner   r   r   Śtest_yieldsMachineŌ   s    ’z.FindMachinesViaWrapperTests.test_yieldsMachinec                 C   s@   d}|   || jd”}|d }|  d| ” jft|  |”” dS )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)r<   r   rX   r:   Ś_classMachinerY   rT   ©r   r,   rG   ŚPythonClassr   r   r   Śtest_yieldsMachineInClasså   s    ’žz5FindMachinesViaWrapperTests.test_yieldsMachineInClassc                 C   sB   d}|   || jd”}|d }|  d| ” jjft|  |”” dS )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)r<   r   rX   r:   ŚNestedClassr`   rY   rT   ra   r   r   r   Śtest_yieldsMachineInNestedClassų   s    ž
’žz;FindMachinesViaWrapperTests.test_yieldsMachineInNestedClassc                 C   sD   d}|   || jd”}|  |”d  ” }|  d|ft|  |”” dS )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.
        rU   rV   rW   N)r4   r   r;   r:   rX   rY   rT   )r   r,   r$   rZ   r   r   r   Śtest_yieldsMachineInModule  s    
’z6FindMachinesViaWrapperTests.test_yieldsMachineInModulec                 C   sF   d}|   || jd”}|  |”d  ” }|  d|jft|  |”” dS )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.
        r\   r]   r^   r_   N)r4   r   r;   r:   rX   r`   rY   rT   ©r   r,   r$   rb   r   r   r   Ś!test_yieldsMachineInClassInModule  s    ’’’žz=FindMachinesViaWrapperTests.test_yieldsMachineInClassInModulec                 C   sH   d}|   || jd”}|  |”d  ” }|  d|jjft|  |”” dS )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.
        rd   re   rf   rg   N)	r4   r   r;   r:   rX   rh   r`   rY   rT   rk   r   r   r   Ś'test_yieldsMachineInNestedClassInModule3  s    ’’’žzCFindMachinesViaWrapperTests.test_yieldsMachineInNestedClassInModulec                 C   s@   d}d}|   || jd” |   || jd”}|  t|  |”” dS )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
        rI   rJ   N©r4   r   rF   rY   rT   )r   rK   rL   ZimportingModuler   r   r   Śtest_ignoresImportedClassI  s    	žz5FindMachinesViaWrapperTests.test_ignoresImportedClassc           
      C   sĄ   |   | jg”}|  | j” d”}| ”  | d” ”  d}|  ||jd” |d }t|  	|”t
 d”d}|  |d ”}|d  ” }|d	  ” }td|fd
|jfgt
 d”d}	|  |	|” dS )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Śtouchr4   r   ŚsortedrT   ŚoperatorŚ
itemgetterr;   r:   r`   ŚassertEqual)
r   Ś
pythonPathŚpackager,   rp   ŚmachinesrG   rZ   rb   ŚexpectedMachinesr   r   r   Śtest_descendsIntoPackagesd  s0    

’’’žüz5FindMachinesViaWrapperTests.test_descendsIntoPackagesc                 C   s,   d}|   || jd”}|  t|  |”” dS )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.pyNrn   )r   r,   r$   r   r   r   Śtest_infiniteLoop  s    z-FindMachinesViaWrapperTests.test_infiniteLoop)r=   r>   r?   r@   ZTEST_MODULE_SOURCEr   r[   rc   ri   rj   rl   rm   ro   r   r   rA   r   r   r   r   rS   ³   s   &rS   c                   @   sx   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )ŚWrapFQPNTestsz
    Tests that ensure L{wrapFQPN} loads the
    L{twisted.python.modules.PythonModule} or
    L{twisted.python.modules.PythonAttribute} for a given FQPN.
    c                 C   sP   ddl m}m} ddlm}m}m}m} || _|| _|| _|| _|| _|| _d S )Nr   )ŚPythonModuleŚPythonAttributerC   )ŚwrapFQPNŚInvalidFQPNŚNoModuleŚNoObject)r   r   r   rE   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   ¢  s    zWrapFQPNTests.setUpc                 C   s2   |   || j” |  |j|j” |  | ” |” dS )zt
        Assert that a L{twisted.python.modules.PythonModule} refers to a
        particular Python module.
        N)ŚassertIsInstancer   rz   r5   r=   ŚassertIsr:   )r   ŚmoduleWrapperr$   r   r   r   ŚassertModuleWrapperRefersTo­  s    z)WrapFQPNTests.assertModuleWrapperRefersToc                 C   s0   |   || j” |  |j|” |  | ” |” dS )zw
        Assert that a L{twisted.python.modules.PythonAttribute} refers to a
        particular Python object.
        N)r   r   rz   r5   r   r:   )r   ZattributeWrapperŚfqpnŚobjr   r   r   ŚassertAttributeWrapperRefersTo¶  s    z,WrapFQPNTests.assertAttributeWrapperRefersToc              	   C   s&   |   | j” |  d” W 5 Q R X dS )zO
        L{wrapFQPN} raises L{InvalidFQPN} when given an empty string.
        Ś N©ŚassertRaisesr   r   ©r   r   r   r   Śtest_failsWithEmptyFQPNæ  s    z%WrapFQPNTests.test_failsWithEmptyFQPNc              
   C   s0   dD ]&}|   | j” |  |” W 5 Q R X qdS )zk"
        L{wrapFQPN} raises L{InvalidFQPN} when given a badly-dotted
        FQPN.  (e.g., x..y).
        )z.failszfails.zthis..failsNr   ©r   Śbadr   r   r   Śtest_failsWithBadDottingĘ  s    z&WrapFQPNTests.test_failsWithBadDottingc                 C   s4   ddl }|  d”}|  || j” |  | ” |” dS )z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the single module a dotless FQPN describes.
        r   Nr1   )r1   r   r   r   r   r:   )r   r1   r   r   r   r   Śtest_singleModuleĻ  s    
zWrapFQPNTests.test_singleModulec              	   C   s&   |   | j” |  d” W 5 Q R X dS )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   r   r   r   Ś*test_failsWithMissingSingleModuleOrPackageŪ  s    z8WrapFQPNTests.test_failsWithMissingSingleModuleOrPackagec                 C   s   ddl }|  |  d”|” dS )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   r   r   r   Śtest_singlePackageć  s    z WrapFQPNTests.test_singlePackagec                 C   s    ddl }|  |  d”|j” dS )z
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the deepest package described by dotted FQPN.
        r   Nz	xml.etree)Z	xml.etreer   r   Śetreer   r   r   r   Śtest_multiplePackagesė  s    z#WrapFQPNTests.test_multiplePackagesc                 C   s"   ddl }|  |  d”|jj” dS )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   r   r   r   Ś test_multiplePackagesFinalModuleó  s
     ’z.WrapFQPNTests.test_multiplePackagesFinalModulec                 C   s"   ddl }|  |  d”d|j” dS )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)r1   r   r   r   )r   r1   r   r   r   Śtest_singleModuleObjectü  s      ’z%WrapFQPNTests.test_singleModuleObjectc                 C   sL   ddl }ddl}d|jjjfd|jjffD ]\}}|  |  |”||” q*dS )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   Ś
fromstringZMethodicalMachiner@   r   r   )r   r   r¢   r   r   r   r   r   Śtest_multiplePackagesObject  s    ’’ž  ’z)WrapFQPNTests.test_multiplePackagesObjectc              
   C   s0   dD ]&}|   | j” |  |” W 5 Q R X qdS )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   r   r   r   Ś4test_failsWithMultiplePackagesMissingModuleOrPackage  s    zBWrapFQPNTests.test_failsWithMultiplePackagesMissingModuleOrPackageN)r=   r>   r?   r@   r   r   r   r   r   r   r   r   r   r    r”   r¤   r„   r   r   r   r   r     s   					r   c                       s,   e Zd ZdZdZ fddZdd Z  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                    s¾   t t|  ”  ddlm} || _|  | j” d”}| ”  |  	| jg”| _
|  | j|jd” | d”}| ”  | d” ”  |  | j|jd” |  | j
d ”| _|  | j
d d d ”| _d S )NrC   )ŚfindMachinesrp   rq   Z
subpackagerr   r$   )r   r¦   r   rE   r§   r   r   r'   ru   r   r{   r0   ŚSOURCEr   rv   r4   r;   ŚpackageDictrG   )r   r§   Z
packageDirZsubPackageDirr   r   r   r   3  s"    
’’z"FindMachinesIntegrationTests.setUpc           	      C   s   t |  d”t d”d}| jd  ” }| jd  ” }| jd }| ” }| jd }| ” }t d|fd|jfd|fd	|jfgt d”d}|  ||” d
S )z
        Given a top-level package FQPN, L{findMachines} discovers all
        L{MethodicalMachine} instances in and below it.
        rp   r   rs   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)	rw   r§   rx   ry   r©   r:   rG   Z_machinerz   )	r   r}   ZtpRootLevelZtpPythonClassZmRLAttrZ
mRootLevelZmPCAttrZmPythonClassr~   r   r   r   Śtest_discoverAllI  s(    
’

’żśz-FindMachinesIntegrationTests.test_discoverAll)r=   r>   r?   r@   rØ   r   rŖ   rA   r   r   r   r   r¦      s   r¦   )rx   r1   r"   r   r*   r   Zunittestr   r   r    r   r	   rB   rS   r   r¦   r   r   r   r   Ś<module>   s&   	<a g 