U
    j@                     @   s  d dl Z d dlZd dlmZmZ d dlZd dlZd dlmZ d dlmZm	Z	m
Z
 d dlm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 d Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Z d/d0 Z!d1d2 Z"ej#$d3d4d5d6d7gZ%e%d8d9 Z&e%d:d; Z'd<d= Z(d>d? Z)ej*d@dA Z+dBdC Z,dDdE Z-dFdG Z.dHd ZdIdJ Z/dKdL Z0dMdN Z1dOdP Z2dQdR Z3dSdT Z4dUdV Z5ej#$dWe j6dXdYdZd[d\d]d^gd_d`dadb Z7ej#$dcddgdedf Z8dS )g    N)datetime	timedelta)prop)Calendar	ComponentEvent)tzid_from_dtc                 C   s   | st |  st dS )zCA component is like a dictionary with extra methods and attributes.N)AssertionErroris_emptycalendar_component r   A/tmp/pip-unpacked-wheel-g40nyxg1/icalendar/tests/test_unit_cal.pytest_cal_Component   s    r   c                 C   sR   d| d< |   rt| tddiks(tddg| d< | tddgddksNtdS )	z|Every key defines a property.A property can consist of either a
    single item. This can be set with a single value...
    z-//max m//icalendar.mxm.dk/prodidPRODIDMax MZ	RasmussenATTENDEE)r   r   N)r
   r	   r   r   r   r   r    test_nonempty_calendar_component   s    r   c                 C   s   |  dddg |  dd |  dd |  dddg | tdtdtdtdtdtdtdgiks|td	S )
zadd multiple values to a property.

    If you use the add method you don't have to considder if a value is
    a list or not.
    attendeeztest@test.comztest2@test.comzmaxm@mxm.dkztest@example.dkztest3@test.comztest4@test.comr   N)addr   r   vCalAddressr	   )Zevent_componentr   r   r   test_add_multiple_values"   s    r   c                 C   s8   |  dd | d tdks"t| ddks4tdS )z(You can get the values back directly ...r   z-//my product//s   -//my product//N)r   r   ZvTextr	   decodedcr   r   r   test_get_content_directly@   s    r   c                 C   s   |  dddkstdS )z/With default values for non existing propertiesversionz
No VersionN)r   r	   r   r   r   r   test_get_default_valueH   s    r   c                 C   s:   |  dtdddtdddg t| dtjs6td S )NZrdatei           )r   r   
isinstancer   r   Z	vDDDListsr	   r   r   r   r   test_default_list_exampleM   s     r#   c                 C   s    |  dd |  dkstdS )z7The component can render itself in the RFC 5545 format.r   r   s0   BEGIN:VCALENDAR
ATTENDEE:Max M
END:VCALENDAR
N)r   to_icalr	   r   r   r   r   test_render_componentR   s
    r%   c                 C   s   |   dkstdS )z-Check the ical string of the event component.sk   BEGIN:VEVENT
DTEND:20000102T000000
DTSTART:20000101T000000
SUMMARY:A brief history of time
END:VEVENT
Nr$   r	   filled_event_componentr   r   r   test_nested_component_event_ics[   s    r)   c                 C   s    t | jtddddg dS )zXComponents can be nested, so You can add a subcomponent. Eg a calendar
    holds events.20000102T00000020000101T000000A brief history of time)DTENDDTSTARTSUMMARYN)selfassertEqualsubcomponentsr   r   r(   r   r   r   test_nested_componentsd   s    r4   c                 C   s"   dd |   D ddgkstdS )z9We can walk over nested componentes with the walk method.c                 S   s   g | ]
}|j qS r   name.0ir   r   r   
<listcomp>w   s     z7test_walk_filled_calendar_component.<locals>.<listcomp>	VCALENDARVEVENTNwalkr	   r3   r   r   r   #test_walk_filled_calendar_componentu   s    r?   c                 C   s@   dd |  dD dgkstdd |  dD dgks<tdS )zYWe can also just walk over specific component types, by filtering
    them on their name.c                 S   s   g | ]
}|j qS r   r5   r7   r   r   r   r:   }   s     z$test_filter_walk.<locals>.<listcomp>r<   c                 S   s   g | ]}|d  qS dtstartr   r7   r   r   r   r:   ~   s     r+   Nr=   r3   r   r   r   test_filter_walkz   s    rB   c              	   C   s:   |  dd |  ddtdfddddd	d
gks6tdS )zOWe can enumerate property items recursively with the property_items
    method.r   r   BEGIN	   VCALENDARr   rD      VEVENTr-   r*   r.   r+   r/   r,   ENDrG   rL   rE   N)r   property_itemsr   r   r	   r3   r   r   r   test_recursive_property_items   s    rO   c                 C   s(   | j ddddtdfdgks$tdS )z>We can also enumerate property items just under the component.F	recursiverC   r   r   rM   N)rN   r   r   r	   r3   r   r   r   test_flat_property_items   s
    
rR   c                 C   s"   | j dddddddgkstdS )	zFlat enumeration on the event.FrP   rF   rH   rI   rJ   rK   N)rN   r	   r'   r   r   r   rR      s    
c                  C   s"   t  } d| d< |  dkstdS )zGText fields which span multiple mulitple lines require proper indentingzParagraph one

Paragraph twodescriptionsL   BEGIN:VCALENDAR
DESCRIPTION:Paragraph one\n\nParagraph two
END:VCALENDAR
N)r   r$   r	   r   r   r   r   test_indent   s
    rT   c                 C   s(   | t ddikst|  dks$tdS )z{INLINE properties have their values on one property line. Note the
    double quoting of the value with a colon in it.
    Z	RESOURCESzChair, Table, "Room: 42"sF   BEGIN:VCALENDAR
RESOURCES:Chair\, Table\, "Room: 42"
END:VCALENDAR
N)r   r	   r$   Zcalendar_with_resourcesr   r   r   test_INLINE_properties   s    
rV   c                 C   s    | j ddddddgkstdS )zXThe inline values must be handled by the get_inline() and
    set_inline() methods.
    	resourcesr   decodeZChairZTablezRoom: 42N
get_inliner	   rU   r   r   r   test_get_inline   s
    r\   c                 C   s    | j ddddddgkstdS )zThese can also be decodedrW      rX   s   Chairs   Tables   Room: 42NrZ   rU   r   r   r   test_get_inline_decoded   s
    r^   c                 C   sJ   | j dddddgdd | d dks(t| jdd	d
ddddgksFtdS )zYou can set them directly ...rW   AListZofzsome, recourcesr]   encodezA,List,of,"some, recources"r   rX   N)Z
set_inliner	   r[   rU   r   r   r   test_set_inline   s     
 rc   c                 C   sb   d| d< | j ddddddgks$t| j ddd}t|d d tsHtt|d d ts^td S )	NzM19970308T160000Z/PT3H,19970308T200000Z/PT1H,19970308T230000Z/19970309T000000Zfreebusyr   rX   z19970308T160000Z/PT3Hz19970308T200000Z/PT1Hz!19970308T230000Z/19970309T000000Zr]   )r[   r	   r"   r   r   )r   rd   r   r   r   test_inline_free_busy_inline   s    
re   c                 C   s   |  d|tddddddd |  dtdddddd |  d|tdddd	ddd |  d
|tdddddd |   }d|kstd|kstd|kstd|kstdS )zTest the for timezone correctness: dtstart should preserve it's
    timezone, created, dtstamp and last-modified must be in UTC.
    rA   i  
   r   zEurope/Viennacreated   Zdtstamp   zlast-modified   s*   DTSTART;TZID=Europe/Vienna:20101010T100000s   CREATED:20101010T120000Zs   DTSTAMP:20101010T120000Zs   LAST-MODIFIED:20101010T160000ZN)r   Zlocalizer   Zlocalize_utcr$   
splitlinesr	   )comptzplinesr   r   r   test_cal_Component_add   s    "" ro   c                 C   sL   |  dd | j dddd td}|  d| | d dd|gksHtdS )z0Already encoded values should not be re-encoded.ZATTACHmeZyouFra   usN)r   r   ZvBinaryr	   )rl   binaryr   r   r   "test_cal_Component_add_no_reencode   s
    
rs   c                 C   s2   | j dddddd |   }d|ks.tdS )	zTest the for timezone correctness: dtstart should preserve it's
    timezone, crated, dtstamp and last-modified must be in UTC.
    zX-TEST-PROPztryout.Zval1Zval2)Zprop1Zprop2)
parameterss)   X-TEST-PROP;PROP1=val1;PROP2=val2:tryout.N)r   r$   rk   r	   )rl   rn   r   r   r   )test_cal_Component_add_property_parameter
  s    ru   zcomponent_name, property_name)r<   r.   )r<   r-   )r<   zRECURRENCE-ID)ZVTODOZDUEc                 C   sH   d|  d }||d 7 }|d|  7 }t |}t|| jdksDtdS )BCheck for proper handling of TZID parameter of datetime propertiesBEGIN:
z;TZID=America/Denver:20120404T073000
END:zAmerica/DenverN)r   	from_icalr   dtr	   Zcomponent_nameZproperty_namerm   component_str	componentr   r   r   test_cal_Component_from_ical  s
    
r   c                 C   sF   d|  d }||d 7 }|d|  7 }t |}|| jjdksBtdS )rv   rw   rx   :ry   N)r   rz   r{   tzinfor	   r|   r   r   r   test_cal_Component_from_ical_2(  s
    
r   c                  C   sj   dddddg} t d| }|  }|| ks6tt|t| ksJt|jdd }|| ksftd S )	N   BEGIN:VEVENTs   DTSTART:19970714T170000Zs   DTEND:19970715T035959Zs   SUMMARY:Bastille Day Party
   END:VEVENT   
Fsorted)r   rz   joinr$   rk   r	   setr}   r~   Z
sorted_strZpreserved_strr   r   r   )test_cal_Component_to_ical_property_order2  s    r   c                  C   s~   dddg} t d| }|  }|d | d ks:t|d dksJt|d | d ks^t|jd	d
 }|| ksztd S )Nr   s(   X-FOOBAR;C=one;A=two;B=three:helloworld.r   r   r   r]   s(   X-FOOBAR;A=two;B=three;C=one:helloworld.   Fr   )r   rz   r   r$   rk   r	   r   r   r   r   *test_cal_Component_to_ical_parameter_orderD  s    r   c                    s   G  fddd}|S )Nc                       sR   e Zd Z Zded< e Zded< e Zded< eddZ	e	
e e	
e dS )z!repr_example.<locals>.ReprExampleZvalue1key1ZVALUE1)r   N)__name__
__module____qualname__r~   r   calendarr   eventr   nestedadd_componentr   r   r   r   ReprExampleW  s   

r   r   )r   r   r   r   r   repr_exampleU  s    r   c                 C   s   t dt| jstdS )z"Test correct class representation.z#Component\({u?'KEY1': u?'value1'}\)N)rematchstrr~   r	   r   r   r   r   test_repr_componente  s    r   c                 C   s   t dt| jstd S )Nz#VCALENDAR\({u?'KEY1': u?'value1'}\))r   r   r   r   r	   r   r   r   r   test_repr_calendarj  s    r   c                 C   s   t dt| jstd S )Nz VEVENT\({u?'KEY1': u?'value1'}\))r   r   r   r   r	   r   r   r   r   test_repr_eventn  s    r   c                 C   s2   | j | j t| j tdt| js.tdS )z#Representation of nested ComponentszComponent\({u?'KEY1': u?'VALUE1'}, Component\({u?'KEY1': u?'value1'}\), VCALENDAR\({u?'KEY1': u?'value1'}, VEVENT\({u?'KEY1': u?'value1'}\)\)\)N)	r   r   r   printr   r   r   r   r	   r   r   r   r   r4   r  s    
c                 C   s&   | d }|dd}|  dks"tdS )z)Check the events in the component factoryr<   Z19700101r@   s,   BEGIN:VEVENT
DTSTART:19700101
END:VEVENT
Nr&   )factoryr~   r   r   r   r   test_component_factory_VEVENT  s    
r   c                 C   s   |  dtjjkstdS )z#Check the VCALENDAR in the factory.r;   N)get	icalendarcalr   r	   )r   r   r   r    test_component_factory_VCALENDAR  s    r   c               
   C   sj   t  } d| d< d| d< t }d|d< d|d< |d	td
ddddd | | | jd  dksftdS )z7Setting up a minimal calendar component looks like thisz -//My calendar product//mxm.dk//r   z2.0r   z Python meeting about calendaringsummaryZ42uidrA   i        r   se   BEGIN:VEVENT
SUMMARY:Python meeting about calendaring
DTSTART:20050404T080000
UID:42
END:VEVENT
N)r   r   r   r   r   r2   r$   r	   )r   r   r   r   r   .test_minimal_calendar_component_with_one_event  s    
r   c                 C   s*   dd | j dD }|ddgks&tdS )Parsing a complete calendar from a string will silently ignore wrong
    events but adding the error information to the component's 'errors'
    attribute. The error in the following is the third EXDATE: it has an
    empty DATE.
    c                 S   s   g | ]}|d    qS )ZDESCRIPTION)r$   r8   er   r   r   r:     s    zItest_calendar_with_parsing_errors_includes_all_events.<locals>.<listcomp>r<   s   Perfectly OK events   Wrong eventNZparsing_errorr>   r	   )	calendarsZevent_descriptionsr   r   r   5test_calendar_with_parsing_errors_includes_all_events  s    
r   c                 C   s,   dd | j dD }|g dggks(tdS )r   c                 S   s   g | ]
}|j qS r   )errorsr   r   r   r   r:     s     zOtest_calendar_with_parsing_errors_has_an_error_in_one_event.<locals>.<listcomp>r<   )ZEXDATEz)Expected datetime, date, or time, got: ''Nr   )r   r   r   r   r   ;test_calendar_with_parsing_errors_has_an_error_in_one_event  s    r   c              	   C   s    t t | j W 5 Q R X dS )z1If components are damaged, we raise an exception.N)pytestZraises
ValueErrorparsing_error_in_UTC_offset)r   r   r   r   test_cal_strict_parsing  s    r   c                 C   s   | j  | j jkstdS )zMIf we diable the errors, we should be able to put the calendar back together.N)r   r$   Zraw_icsr	   )r   ZvUTCOffset_ignore_exceptionsr   r   r   test_cal_ignore_errors_parsing  s    r   )r   other_calendarZ%issue_156_RDATE_with_PERIOD_TZID_khalZ'issue_156_RDATE_with_PERIOD_TZID_khal_2Z)issue_178_custom_component_contains_otherZ'issue_178_custom_component_inside_otherissue_526_calendar_with_eventsZ(issue_526_calendar_with_different_eventsZ$issue_526_calendar_with_event_subsetr   )repeatc                 C   s(   | | | | k}||k}||ks$t d S N)r	   )r   r   r   rm   Zare_calendars_equalZare_calendars_actually_equalr   r   r   test_comparing_calendars  s    r   )r   shuffeled_calendar)r   Z(issue_526_calendar_with_shuffeled_eventsc                 C   s0   | | j | | j kst| | | | ks,td S r   )r2   r	   )r   r   r   r   r   r   Ctest_calendars_with_same_subcomponents_in_different_order_are_equal  s    r   )9	itertoolsr   r   r   r   r   r   Zicalendar.calr   r   r   Zicalendar.propr   r   r   r   r   r   r#   r%   r)   r4   r?   rB   rO   rR   rT   rV   r\   r^   rc   re   ro   rs   ru   markZparametrizeZ	comp_propr   r   r   r   Zfixturer   r   r   r   r   r   r   r   r   r   r   productr   r   r   r   r   r   <module>   s   				
	
	
	
	

	
	