
    9                         d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ ddlm	Z	  G d de
      Zd	 Z G d
 de      Z G d de      Z G d de      Z G d de      Zd Z G d de      Zy)a  The mock module allows easy mocking of apitools clients.

This module allows you to mock out the constructor of a particular apitools
client, for a specific API and version. Then, when the client is created, it
will be run against an expected session that you define. This way code that is
not aware of the testing framework can construct new clients as normal, as long
as it's all done within the context of a mock.
    N)messages)base_api)encoding)
exceptionsc                       e Zd ZdZy)ErrorzExceptions for this module.N)__name__
__module____qualname____doc__     0lib/third_party/apitools/base/py/testing/mock.pyr   r   $   s    %r   r   c                    t        | t              rDt        |t              r4t        |       t        |      k7  ryt        d t	        | |      D              S t        | t
        j                        rt        |t
        j                        s| |k(  S | j                         D ]<  }t        | |j                        }t        ||j                        }t        ||      r< y y)a  Compare two protorpc messages for equality.

    Using python's == operator does not work in all cases, specifically when
    there is a list involved.

    Args:
      msg1: protorpc.messages.Message or [protorpc.messages.Message] or number
          or string, One of the messages to compare.
      msg2: protorpc.messages.Message or [protorpc.messages.Message] or number
          or string, One of the messages to compare.

    Returns:
      If the messages are isomorphic.
    Fc              3   :   K   | ]  \  }}t        ||        y wN)_MessagesEqual).0xys      r   	<genexpr>z!_MessagesEqual.<locals>.<genexpr>;   s     DODAq>!Q'Os   T)
isinstancelistlenallzipr   Message
all_fieldsgetattrnamer   )msg1msg2fieldfield1field2s        r   r   r   )   s     $*T4"8t9D	!DCdODDDtX--.4!1!12t|"uzz*uzz*ff-	 #
 r   c                        e Zd Z fdZ xZS )UnexpectedRequestExceptionc                    |\  }}|\  }}t        j                  |d      }t        j                  |d      }|j                         }	|j                         }
t        j                  |	|
      }dj                  |      }||k7  r8dj                  d      j                  ||||      }t        t        | '  |       y dj                  d      j                  ||||      }t        t        | '  |       y )NT	multiline
)z,expected: {expected_key}({expected_request})z,received: {received_key}({received_request}) )expected_keyexpected_requestreceived_keyreceived_request)zfor request to {key},zexpected: {expected_request}zreceived: {received_request}zdiff: {diff}r,   )keyr.   r0   diff)
r   MessageToRepr
splitlinesdifflibunified_diffjoinformatsuperr'   __init__)selfreceived_callexpected_callr-   r.   r/   r0   expected_reprreceived_reprexpected_linesreceived_lines
diff_linesr2   msg	__class__s                 r   r:   z#UnexpectedRequestException.__init__J   s   )6&&)6&& ... ... '113&113))..I
yy$<'))   v)!.)!.	  0	  ,d<SA))   v !.!.	    ,d<SAr   r	   r
   r   r:   __classcell__rD   s   @r   r'   r'   H   s    &B &Br   r'   c                        e Zd Z fdZ xZS )ExpectedRequestsExceptionc           	          d}|D ]0  \  }}|dj                  |t        j                  |d            z  }2 t        t        |   |       y )Nz
expected:
z{key}({request})
Tr)   )r1   request)r8   r   r3   r9   rI   r:   )r;   expected_callsrC   r1   rK   rD   s        r   r:   z"ExpectedRequestsException.__init__u   sZ    ,NS''.. ..w$G / I IC - 	'7<r   rE   rG   s   @r   rI   rI   s   s    = =r   rI   c                   >    e Zd ZdZddZed        Zed        Zd Zy)_ExpectedRequestResponsez@Encapsulation of an expected request and corresponding response.Nc                 2   || _         || _        |r|rt        j                  d      |r/t	        |t        j
                        rt        j                  d      |r/t	        |t        j
                        st        j                  d      || _        || _        y )Nz4Should specify at most one of response and exceptionz,Responses should not be an instance of Errorz%Exceptions must be instances of Error)_ExpectedRequestResponse__key!_ExpectedRequestResponse__requestr   ConfigurationValueErrorr   r   "_ExpectedRequestResponse__response#_ExpectedRequestResponse__exception)r;   r1   rK   response	exceptions        r   r:   z!_ExpectedRequestResponse.__init__   s    
 	44FH H
8Z-=-=>44>@ @Z	:3C3CD4479 9 #$r   c                     | j                   S r   )rP   r;   s    r   r1   z_ExpectedRequestResponse.key   s    zzr   c                     | j                   S r   )rQ   rX   s    r   rK   z _ExpectedRequestResponse.request   s    ~~r   c                     || j                   k7  s%| j                  |k(  s:t        || j                        s$t        ||f| j                   | j                  f      | j                  r| j                  | j
                  S )aT  Validate that key and request match expectations, and respond if so.

        Args:
          key: str, Actual key to compare against expectations.
          request: protorpc.messages.Message or [protorpc.messages.Message]
            or number or string, Actual request to compare againt expectations

        Raises:
          UnexpectedRequestException: If key or request dont match
              expectations.
          apitools_base.Error: If a non-None exception is specified to
              be thrown.

        Returns:
          The response that was specified to be returned.

        )rP   rQ   r   r'   rT   rS   )r;   r1   rK   s      r   ValidateAndRespondz+_ExpectedRequestResponse.ValidateAndRespond   so    $ $**T^^w%>%3GT^^%L,c7^.2jj$..-IK K """r   NN)	r	   r
   r   r   r:   propertyr1   rK   r[   r   r   r   rN   rN   ~   s7    J%"    r   rN   c                   .    e Zd ZdZd Zd Z	 	 ddZd Zy)_MockedMethodzA mocked API service method.c                 N   |j                   | _         || _        || _        || _        |j                  | _        | j	                         }t        | j                  j                  |j                        | _        t        | j                  j                  |j                        | _
        y r   )r	   _MockedMethod__key_MockedMethod__mocked_client_MockedMethod__real_methodmethod_configr   MESSAGES_MODULErequest_type_name_MockedMethod__request_typeresponse_type_name_MockedMethod__response_type)r;   r1   mocked_clientreal_methodconfigs        r   r:   z_MockedMethod.__init__   s    #,,
,((66##%%d&:&:&J&J&,&>&>@&t';';'K'K'-'@'@ Br   c           
          |rd}| j                   }nd}| j                  }t        ||      s:t        j                  dj                  || j                  |t        |                  y)a  Ensure the given message is of the expected type of this method.

        Args:
          msg: The message instance to check.
          is_request: True to validate against the expected request type,
             False to validate against the expected response type.

        Raises:
          exceptions.ConfigurationValueError: If the type of the message was
             not correct.
        rK   rU   z[Expected {} is not of the correct type for method [{}].
   Required: [{}]
   Given:    [{}]N)rg   ri   r   r   rR   r8   ra   type)r;   rC   
is_requestmode	real_types        r   
_TypeCheckz_MockedMethod._TypeCheck   si     D++ID,,I#y)44$$*F$**ic%<= = *r   Nc                     |r(| j                  |d       |r| j                  |d       | j                  j                  j                  t	        | j
                  |||             y)a#  Add an expectation on the mocked method.

        Exactly one of response and exception should be specified.

        Args:
          request: The request that should be expected
          response: The response that should be returned or None if
              exception is provided.
          exception: An exception that should be thrown, or None.
          enable_type_checking: When true, the message type of the request
              and response (if provided) will be checked against the types
              required by this method.
        T)ro   F)rU   rV   N)rr   rb   _request_responsesappendrN   ra   )r;   rK   rU   rV   enable_type_checkingunused_kwargss         r   Expectz_MockedMethod.Expect   s]    *  OOGO5U; 	//66$TZZ%,.6/8:	;r   c                 j   | j                   j                  r&| j                   j                  j                  d      }nt        | j                  |fd      |j                  | j                  |      }|@| j                  r4| j                  |      }t        t        j                  |dd             |S |S )Nr   r\   T)r*   shortstrings)
rb   rt   popr'   ra   r[   rc   printr   r3   )r;   rK   rw   request_responserU   s        r   __call__z_MockedMethod.__call__  s     22#33FFJJ1M,W%|5 5 $66tzz7K 2 2))'2H(((Dt= >Or   )NNT)r	   r
   r   r   r:   rr   rx   r~   r   r   r   r_   r_      s#    &
B=4 8<$( ;Fr   r_   c           
           G d dt         j                        }|j                         D ]6  }d }|rt        ||      }t	        ||t        | dz   |z   dz   |z   ||             8 |S )Nc                       e Zd Zy))_MakeMockedService.<locals>.MockedServiceNr	   r
   r   r   r   r   MockedServicer   "  s    r   r   .)r   BaseApiServiceGetMethodsListr   setattrr_   )api_namecollection_namemock_clientservicereal_servicer   methodrk   s           r   _MakeMockedServicer      su    //  ((*!,7Khn>DvM))+	,	 + r   c                   8    e Zd ZdZd	dZd Zd Zd Zd
dZd Z	y)ClientzMock an apitools client.Nc                     |s	 |d      }| j                   | _        || _        i | _        || _        g | _        d| _        y)a  Mock an apitools API, given its class.

        Args:
          client_class: The class for the API. eg, if you
                from apis.sqladmin import v1beta3
              then you can pass v1beta3.SqladminV1beta3 to this class
              and anything within its context will use your mocked
              version.
          real_client: apitools Client, The client to make requests
              against when the expected response is None.

        Fget_credentialsN)rD   _Client__orig_class_Client__client_class_Client__real_service_classes_Client__real_clientrt   _Client__real_include_fields)r;   client_classreal_clients      r   r:   zClient.__init__5  sE     &u=K NN*&(#("$%)"r   c                 "    | j                         S r   )MockrX   s    r   	__enter__zClient.__enter__N  s    yy{r   c           
      *   | j                   xs | j                  d      } G d d| j                  | j                        }|| _        t        | j                        D ]  }t	        | j                  |      }t        |t              s*t        |t        j                        sE|| j                  |<   |j                  }| j                  j                  d| j                  j                  }t        ||| || j                   r ||      nd      }t        | j                  ||       t        | | ||               | j                  j                   | _        | j                   | j                  _        |j$                  | _        |j&                  | _        | S )z/Stub out the client class with mocked services.Fr   c                       e Zd Zy)Client.Mock.<locals>.PatchedNr   r   r   r   Patchedr   V  s    r   r   _N)r   r   rD   dirr   r   rn   
issubclassr   r   r   _NAME_PACKAGE_URL_VERSIONr   r   IncludeFieldsr   _url_http)r;   clientr   r    service_classr   r   mocked_service_classs           r   r   zClient.MockQ  sd   ## #t':':! (; (#	dnnd&9&9 	 ++,D#D$7$7>MmT2mX-D-DE0=D''-+11O"&"5"5">">"&"5"5"B"BDH#5/4)-););f%$G 
 D''/CDD/+?+EF' -* &*%8%8%F%F",0,>,>) KK	\\
r   c                 b    |d u}| j                  |       |rt        j                  |||       y)N)suppressT)Unmocksixreraise)r;   exc_typevalue	tracebackis_active_exceptions        r   __exit__zClient.__exit__x  s2    #4/01KK%3r   c                    | j                   | _        | j                  j                         D ]2  \  }}t	        | j
                  ||       t        | |j                         4 i | _        | `| `	| j                  | j
                  _        d | _
        | j                  D cg c]  }|j                  |j                  f }}g | _        |r&|s#t        j                          d   t#        |      y y y c c}w )N   )r   rD   r   itemsr   r   delattrr   r   r   r   r   rt   r1   rK   sysexc_inforI   )r;   r   r    r   rq_rsrequestss         r   r   zClient.Unmock  s    **#'#>#>#D#D#FD-D''}=D---. $G ')#IJ,0,F,F)%)" "&!8!8:!8 YY.!8 	 :"$H):)B+H55 *CH8	:s   C-c                 T    | j                   r| j                  | j                   |      S y r   )r   r   )r;   include_fieldss     r   r   zClient.IncludeFields  s.    --d.@.@.<> > r   r   )F)
r	   r
   r   r   r:   r   r   r   r   r   r   r   r   r   r   1  s$    "*2%N6&>r   r   )r   r5   r   r   apitools.base.protorpcliter   apitools.base.pyr   r   r   	Exceptionr   r   r'   rI   objectrN   r_   r   r   r   r   r   <module>r      s|      
 
 / % % '&I &
>(B (BV= =8v 8vdF dN"d>V d>r   