o
    Ńó·i3V  ć                   @   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 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 dS  ty   Y dS w )NZtwistedFT)Ś
__import__ŚImportError© r   r   śaC:\Users\psant\Downloads\PAF backend\school\venv\Lib\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                    sP   t t|  ”  | jtjd d < tj ” | j }|D ]}tj|= qt	 
| j” d S ©N)r   r	   ŚtearDownr   r   r   r   r   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   2   s   z#_WritesPythonModules.makeImportablec                 C   s^   |   |”}| |”}t|jd}| t |”” W d    n1 s#w   Y  |  |jg”S )NŚw)r   ŚchildŚopenr   ŚwriteŚtextwrapŚdedentr   )r   Śsourcer   Ś
moduleNameŚ	directoryr"   Śfr   r   r   ŚwriteSourceInto5   s   

’z$_WritesPythonModules.writeSourceIntoc                 C   s"   t j |”\}}|  |||”| S r   )Śosr   Śsplitextr.   )r   r*   r   r+   ZpythonModuleNameŚ_r   r   r   Ś
makeModule@   s   z_WritesPythonModules.makeModulec                 C   s   dd |  ” D S )Nc                 S   s   i | ]}|j |qS r   )Śname)Ś.0Śattrr   r   r   Ś
<dictcomp>E   s    z9_WritesPythonModules.attributesAsDict.<locals>.<dictcomp>)ZiterAttributes)r   ZhasIterAttributesr   r   r   ŚattributesAsDictD   s   z%_WritesPythonModules.attributesAsDictc                 C   s   |  ”  |  |”S r   )Śloadr7   )r   r"   r   r   r   ŚloadModuleAsDictG   s   
z%_WritesPythonModules.loadModuleAsDictc                 C   s   |   |  |||””S r   )r9   r2   )r   r*   r   r3   r   r   r   ŚmakeModuleAsDictK   s   z%_WritesPythonModules.makeModuleAsDict)Ś__name__Ś
__module__Ś__qualname__Ś__doc__r   r   r   r.   r2   r7   r9   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                    ó$   t t|  ”  ddlm} || _d S )Né   )ŚisOriginalLocation)r   r@   r   Ś	_discoverrC   )r   rC   r   r   r   r   ]   ó   
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   ŚassertFalserC   )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)r2   r   r:   rF   rC   r7   )r   ŚoriginalSourceŚimportingSourceZimportingDictŚnestingObjectŚnestingObjectDictŚnestedObjectr   r   r   Śtest_failsWithDifferentModuleu   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   Ś
assertTruerC   r7   )r   ZmSourceZmDictrM   rN   rO   r   r   r   Śtest_succeedsWithSameModule   s   ’	
z1OriginalLocationTests.test_succeedsWithSameModule)	r;   r<   r=   r>   r   rH   rP   rR   r?   r   r   r   r   r@   O   s    &r@   c                       sr   e Zd ZdZ fddZdd Zd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}.
    c                    rA   )NrB   )ŚfindMachinesViaWrapper)r   rS   r   rD   rT   )r   rT   r   r   r   r   ½   rE   z!FindMachinesViaWrapperTests.setUpc                 C   ó>   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   ŚassertInr8   ŚlistrT   ©r   r*   rG   ŚrootMachiner   r   r   Śtest_yieldsMachineĆ   s   
žz.FindMachinesViaWrapperTests.test_yieldsMachineŚreturnNc                 C   rU   )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()
        rW   rX   NrY   r\   r   r   r   Śtest_yieldsTypeMachineÖ   s   
žz2FindMachinesViaWrapperTests.test_yieldsTypeMachinec                 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   rZ   r8   Ś_classMachiner[   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   rZ   r8   ŚNestedClassre   r[   rT   rf   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.
        rV   rW   rX   N)r2   r   r9   r8   rZ   r[   rT   )r   r*   r"   r]   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.
        ra   rb   rc   rd   N)r2   r   r9   r8   rZ   re   r[   rT   ©r   r*   r"   rg   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.
        ri   rj   rk   rl   N)	r2   r   r9   r8   rZ   rm   re   r[   rT   rp   r   r   r   Ś'test_yieldsMachineInNestedClassInModuleA  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©r2   r   rF   r[   rT   )r   rK   rL   ZimportingModuler   r   r   Śtest_ignoresImportedClassZ  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Śtouchr2   r   ŚsortedrT   ŚoperatorŚ
itemgetterr9   r8   re   ŚassertEqual)
r   Ś
pythonPathŚpackager*   ru   ŚmachinesrG   r]   rg   ŚexpectedMachinesr   r   r   Śtest_descendsIntoPackagess  s,   
’žžų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.pyNrs   )r   r*   r"   r   r   r   Śtest_infiniteLoop  s   z-FindMachinesViaWrapperTests.test_infiniteLoop)r_   N)r;   r<   r=   r>   r   r^   r`   rh   rn   ro   rq   rr   rt   r   r   r?   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ŚPythonAttributerB   )ŚwrapFQPNŚInvalidFQPNŚNoModuleŚNoObject)r   r   r   rD   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   r   r3   r;   ŚassertIsr8   )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   r   r3   r   r8   )r   ZattributeWrapperŚfqpnŚobjr   r   r   ŚassertAttributeWrapperRefersToĖ  s   z,WrapFQPNTests.assertAttributeWrapperRefersToc                 C   ó<   |   | j” |  d” W d   dS 1 sw   Y  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   óD   dD ]}|   | j” |  |” W d   q1 sw   Y  qdS )zl "
        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Ū  ó
   ’’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   Nr/   )r/   r   r   r   r   r8   )r   r/   r   r   r   r   Śtest_singleModuleä  s   
zWrapFQPNTests.test_singleModulec                 C   r   )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
  ó   ’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)r/   r   r   r   )r   r/   r   r   r   Śtest_singleModuleObject  r©   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   r   )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/  r   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 )NrB   )ŚfindMachinesru   rv   Z
subpackagerw   r"   )r   rÆ   r   rD   r°   r   r   r%   rz   r   r   r.   ŚSOURCEr   r{   r2   r9   ŚpackageDictrG   )r   r°   Z
packageDirZsubPackageDirr   r   r   r   L  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.
        ru   r   rx   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²   r8   rG   Z_machiner   )	r   r   ZtpRootLevelZtpPythonClassZmRLAttrZ
mRootLevelZmPCAttrZmPythonClassr   r   r   r   Śtest_discoverAllb  s$   

žü	öz-FindMachinesIntegrationTests.test_discoverAll)r;   r<   r=   r>   r±   r   r³   r?   r   r   r   r   rÆ   9  s
    rÆ   )r}   r/   r    r   r(   r   Zunittestr   r   r   r	   r@   rS   r   rÆ   r   r   r   r   Ś<module>   s&    	<d { 
