U
    kufo                  	   @   s2  d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ 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mZmZmZ d dlmZmZ e  ed d dlm Z  W 5 Q R X dd Z!dd Z"dd Z#G dd deZ$G dd deZ%G dd deZ&dS )    )redirect_stderrredirect_stdout)metadata)StringIO)JSONDecodeError)Path)dedent)TestCaseN)Draft4ValidatorDraft202012Validator)SchemaErrorValidationError_RefResolutionError)_LATEST_VERSIONvalidateignore)clic                     s"   t t  G  fddd}|S )Nc                       s,   e Zd Zdd Z fddZedd ZdS )z%fake_validator.<locals>.FakeValidatorc                 _   s   d S N )selfargskwargsr   r   =/tmp/pip-unpacked-wheel-k94ccfep/jsonschema/tests/test_cli.py__init__    s    z.fake_validator.<locals>.FakeValidator.__init__c                    s    r   S g S r   )popr   instanceerrorsr   r   iter_errors#   s    z1fake_validator.<locals>.FakeValidator.iter_errorsc                 S   s   d S r   r   r   schemar   r   r   check_schema(   s    z2fake_validator.<locals>.FakeValidator.check_schemaN)__name__
__module____qualname__r   r   classmethodr"   r   r   r   r   FakeValidator   s   r'   )listreversed)r   r'   r   r   r   fake_validator   s    r*   c                    s    fdd}|S )Nc                    s"     | }|d krt| t|S r   )getFileNotFoundErrorr   )pathcontentsall_contentsr   r   open0   s    
zfake_open.<locals>.openr   )r0   r1   r   r/   r   	fake_open/   s    r2   c              
   C   sJ   zt |  W n. tk
r< } zt| W Y S d }~X Y n
X tdd S )Nz.Tried and failed to capture a JSON dump error.)jsonloadsr   strRuntimeError)Znon_jsonerrorr   r   r   _message_for8   s
    r8   c                   @   s  e Zd Zde df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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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%dHdI Z&dJdK Z'dLdM Z(dNdO Z)dPdQ Z*dRdS Z+dTdU Z,dVdW Z-dXdY Z.dZd[ Z/d\d] Z0dS )_TestCLINr   c           
      K   s   t |}|| | tt d t|p,i t _z$t t  }}t j||||d}	W 5 t `X | j	|	|t
d| d|	 d|  d|  d	d | | fS )	Nr1   )stdinstdoutstderrz.
                    Expected an exit code of z != z.

                    stdout: z

                    stderr: z
                )msg)r   
parse_argsupdateassertFalsehasattrr2   r1   r   runassertEqualr   getvalue)
r   argvfilesr:   	exit_codeoverride	argumentsr;   r<   Zactual_exit_coder   r   r   run_cliB   s:    


  zTestCLI.run_cli c                 K   s$   |  | jf |t|t|f d S r   )rC   rJ   r   )r   r;   r<   r   r   r   r   assertOutputsb   s    
zTestCLI.assertOutputsc                 C   s@   t ddd}| jtdt|jdt|gdddgd	d
d d S )NI am an error!   r   *{"does not": "matter since it is stubbed"}some_schemasome_instance-irS   rR      12: I am an error!
rF   	validatorrE   rG   r<   r   rL   dictr3   dumpsr   r*   r   r7   r   r   r   test_invalid_instanceh   s    
zTestCLI.test_invalid_instancec                 C   sD   t ddd}| jtdt|jdt|gdddd	d
gddd d S )NrM   rN   rO   rP   rQ   rT   rS   --outputprettyrR   rU   z                ===[ValidationError]===(some_instance)===

                I am an error!
                -----------------------------
            rW   rY   r\   r   r   r   #test_invalid_instance_pretty_outputw   s    
z+TestCLI.test_invalid_instance_pretty_outputc                 C   sD   t ddd}| jtdt|jdt|gdddd	d
gddd d S )NrM   rN   rO   rP   rQ   r^   plainrT   rS   rR   rU   rV   rW   rY   r\   r   r   r   +test_invalid_instance_explicit_plain_output   s    
z3TestCLI.test_invalid_instance_explicit_plain_outputc                 C   sP   d}t d|d}t d|d}| jtdt|dt||gddd	gd
dd d S )NrN   First errorrO   Second errorrP   rQ   rT   rS   rR   rU   zM                12: First error
                12: Second error
            rW   r   rL   rZ   r3   r[   r*   r   r   firstsecondr   r   r   %test_invalid_instance_multiple_errors   s    
z-TestCLI.test_invalid_instance_multiple_errorsc                 C   sT   d}t d|d}t d|d}| jtdt|dt||gddd	d
dgddd d S )NrN   rc   rO   rd   rP   rQ   rT   rS   r^   r_   rR   rU   a                  ===[ValidationError]===(some_instance)===

                First error
                -----------------------------
                ===[ValidationError]===(some_instance)===

                Second error
                -----------------------------
            rW   re   rf   r   r   r   3test_invalid_instance_multiple_errors_pretty_output   s    
z;TestCLI.test_invalid_instance_multiple_errors_pretty_outputc                 C   sl   d}t d|dt d|dg}d}t d|dg}| jtdt|t|dt||d	d
d	ddgddd d S )NrN   An errorrO   Another errorfooBOOMrP   rR   some_first_instancesome_second_instancerT   rp   rq   rR   rU   ze                12: An error
                12: Another error
                foo: BOOM
            rW   re   r   first_instanceZfirst_errorssecond_instanceZsecond_errorsr   r   r   test_multiple_invalid_instances   s,    

  z'TestCLI.test_multiple_invalid_instancesc              
   C   sp   d}t d|dt d|dg}d}t d|dg}| jtdt|t|dt||d	d
dddddgddd d S )NrN   rk   rO   rl   rm   rn   rP   ro   r^   r_   rT   rp   rq   rR   rU   a                  ===[ValidationError]===(some_first_instance)===

                An error
                -----------------------------
                ===[ValidationError]===(some_first_instance)===

                Another error
                -----------------------------
                ===[ValidationError]===(some_second_instance)===

                BOOM
                -----------------------------
            rW   re   rr   r   r   r   -test_multiple_invalid_instances_pretty_output   s0    

   z5TestCLI.test_multiple_invalid_instances_pretty_outputc              
   C   sp   d}t d|dt d|dg}d}t d|dg}| jtdt|t|dt||d	d
dddddgddd d S )NrN   rk   rO   rl   rm   rn   rP   ro   --error-format&:{error.message}._-_.{error.instance}:rT   rp   rq   rR   rU   z5:An error._-_.12::Another error._-_.12::BOOM._-_.foo:rW   re   rr   r   r   r   test_custom_error_format  s0    

   z TestCLI.test_custom_error_formatc                 C   s   | j tdddgddd d S )Nz{"type": 12}rR   rR   rU   O                12: 12 is not valid under any of the given schemas
            rF   rE   rG   r<   rL   rZ   r   r   r   r   test_invalid_schema.  s    zTestCLI.test_invalid_schemac              	   C   sh   ddi}|  t}t|dd W 5 Q R X t|j}| jtt|ddddgd	d
t| d d d S )NtyperN   rK   r!   r   rz   r^   r_   rR   rU   %===[SchemaError]===(some_schema)===


-----------------------------
r|   	assertRaisesr   r   r5   	exceptionrL   rZ   r3   r[   r   r!   er7   r   r   r   !test_invalid_schema_pretty_output9  s    
z)TestCLI.test_invalid_schema_pretty_outputc                 C   s   | j tdddgddd d S )Nz{"type": 12, "items": 57}rz   rR   rU   zF                57: 57 is not of type 'object', 'boolean'
            r|   r}   r~   r   r   r   #test_invalid_schema_multiple_errorsL  s    z+TestCLI.test_invalid_schema_multiple_errorsc              	   C   sj   ddd}|  t}t|dd W 5 Q R X t|j}| jtt|dddd	gd
dt| d d d S )NrN   9   )r   itemsrK   r   rz   r^   r_   rR   rU   r   r   r|   r   r   r   r   r   1test_invalid_schema_multiple_errors_pretty_outputW  s    

z9TestCLI.test_invalid_schema_multiple_errors_pretty_outputc                 C   s$   | j tddddddgddd	 d
S )zv
        "Validating" an instance that's invalid under an invalid schema
        just shows the schema error.
        z{"type": 12, "minimum": 30}Z13rQ   rT   rS   rR   rU   r{   r|   Nr}   r~   r   r   r   )test_invalid_schema_with_invalid_instancej  s    z1TestCLI.test_invalid_schema_with_invalid_instancec              	   C   s|   dddd }}|  t}t||d W 5 Q R X t|j}| jtt|t|dddd	d
dgddt| d d d S )N   rN      r   Zminimumr   rQ   r^   r_   rT   rS   rR   rU   r   r   r|   r   )r   r   r!   r   r7   r   r   r   7test_invalid_schema_with_invalid_instance_pretty_output|  s"    
z?TestCLI.test_invalid_schema_with_invalid_instance_pretty_outputc                 C   s4   | j tdddddddddgd	d
tdd d S )Nz{"minimum": 30}not valid JSON!Z12)rR   rs   rt   rT   rs   rt   rR   rU   zw                Failed to parse 'first_instance': {}
                12: 12 is less than the minimum of 30
            r|   )rL   rZ   formatr8   r~   r   r   r   -test_invalid_instance_continues_with_the_rest  s"      z5TestCLI.test_invalid_instance_continues_with_the_restc              	   C   sZ   dddd }}|  t t||d W 5 Q R X | jtt|dddd	gd
dd d S )Nr   rN   r   r   r   rz   rw   rx   rR   rU   z7:12 is not valid under any of the given schemas._-_.12:r|   )r   r   r   rL   rZ   r3   r[   )r   r   r!   r   r   r   1test_custom_error_format_applies_to_schema_errors  s     z9TestCLI.test_custom_error_format_applies_to_schema_errorsc                 C   s4   d}| j td|ddddgddt| d	d
 d S )Nr   {}rQ   rT   rS   rR   rU   z1                Failed to parse 'some_instance': 
            r|   rL   rZ   r8   r   r   r   r   test_instance_is_invalid_JSON  s    
z%TestCLI.test_instance_is_invalid_JSONc                 C   sL   | j tddddddddgd	d
\}}| | | d| | d| d S )Nr   r   rQ   r^   r_   rT   rS   rR   rU   rF   rE   rG   z7(some_instance)===

Traceback (most recent call last):
rJ   rZ   r@   assertInassertNotInr   r;   r<   r   r   r   +test_instance_is_invalid_JSON_pretty_output  s    


z3TestCLI.test_instance_is_invalid_JSON_pretty_outputc                 C   s4   d}| j tddt|dgddt| dd d S )	Nr   r   rz   rR   rU   z)                Failed to parse <stdin>: r   )rF   r:   rE   rG   r<   )rL   rZ   r   r8   r   r   r   r   &test_instance_is_invalid_JSON_on_stdin  s    z.TestCLI.test_instance_is_invalid_JSON_on_stdinc                 C   sL   | j tddtddddgdd\}}| | | d	| | d| d S )
Nr   rz   r   r^   r_   rR   rU   )rF   r:   rE   rG   z1(<stdin>)===

Traceback (most recent call last):
)rJ   rZ   r   r@   r   r   r   r   r   r   4test_instance_is_invalid_JSON_on_stdin_pretty_output  s    

z<TestCLI.test_instance_is_invalid_JSON_on_stdin_pretty_outputc                 C   s.   d}| j t|ddgddt| dd d S )Nr   rz   rR   rU   /                Failed to parse 'some_schema': r   r|   r   r    r   r   r   test_schema_is_invalid_JSON  s    z#TestCLI.test_schema_is_invalid_JSONc                 C   s:   | j tdddddgdd\}}| | | d| d S )	Nr   rz   r^   r_   rR   rU   r   5(some_schema)===

Traceback (most recent call last):
)rJ   rZ   r@   r   r   r   r   r   )test_schema_is_invalid_JSON_pretty_output  s    

z1TestCLI.test_schema_is_invalid_JSON_pretty_outputc                 C   s4   d\}}| j t||ddgddt| dd dS )	M
        Only the schema error is reported, as we abort immediately.
        )r   also not valid JSON!rQ   rR   rU   r   r   r|   Nr   r   r!   r   r   r   r   .test_schema_and_instance_are_both_invalid_JSON  s    
z6TestCLI.test_schema_and_instance_are_both_invalid_JSONc                 C   sL   | j tddddddddgd	d
\}}| | | d| | d| dS )r   r   r   rQ   r^   r_   rT   rS   rR   rU   r   r   Nr   r   r   r   r   <test_schema_and_instance_are_both_invalid_JSON_pretty_output"  s    


zDTestCLI.test_schema_and_instance_are_both_invalid_JSON_pretty_outputc                 C   s"   | j tdddddgddd d S )	Nr   rz   rT   nonexisting_instancerR   rU   zC                'nonexisting_instance' does not exist.
            r|   r}   r~   r   r   r   test_instance_does_not_exist7  s    z$TestCLI.test_instance_does_not_existc                 C   s&   | j tdddddddgdd	d
 d S )Nr   rz   r^   r_   rT   r   rR   rU   z                ===[FileNotFoundError]===(nonexisting_instance)===

                'nonexisting_instance' does not exist.
                -----------------------------
            r|   r}   r~   r   r   r   *test_instance_does_not_exist_pretty_outputB  s      z2TestCLI.test_instance_does_not_exist_pretty_outputc                 C   s   | j dgddd d S )Nnonexisting_schemarU   %'nonexisting_schema' does not exist.
rE   rG   r<   rL   r~   r   r   r   test_schema_does_not_existT  s
    z"TestCLI.test_schema_does_not_existc                 C   s   | j dddgddd d S )Nr^   r_   r   rU                   ===[FileNotFoundError]===(nonexisting_schema)===

                'nonexisting_schema' does not exist.
                -----------------------------
            r   r   r~   r   r   r   (test_schema_does_not_exist_pretty_output\  s
    z0TestCLI.test_schema_does_not_exist_pretty_outputc                 C   s   | j dddgddd d S )NrT   r   r   rU   r   r   r   r~   r   r   r   &test_neither_instance_nor_schema_existi  s
    z.TestCLI.test_neither_instance_nor_schema_existc                 C   s   | j dddddgddd d S )	Nr^   r_   rT   r   r   rU   r   r   r   r~   r   r   r   4test_neither_instance_nor_schema_exist_pretty_outputq  s      z<TestCLI.test_neither_instance_nor_schema_exist_pretty_outputc                 C   s$   | j tddddddgddd d S Nr   rQ   rT   rS   rR   rK   rF   rE   r;   r<   r}   r~   r   r   r   test_successful_validation  s    
z"TestCLI.test_successful_validationc                 C   s(   | j tddddddddgdd	d
 d S Nr   rQ   r^   r_   rT   rS   rR   z"===[SUCCESS]===(some_instance)===
rK   r   r}   r~   r   r   r   (test_successful_validation_pretty_output  s    
z0TestCLI.test_successful_validation_pretty_outputc                 C   s$   | j tddtddgddd d S )Nr   rz   rR   rK   rF   r:   rE   r;   r<   rL   rZ   r   r~   r   r   r   #test_successful_validation_of_stdin  s    z+TestCLI.test_successful_validation_of_stdinc                 C   s(   | j tddtddddgddd d S )	Nr   rz   r^   r_   rR   z===[SUCCESS]===(<stdin>)===
rK   r   r   r~   r   r   r   1test_successful_validation_of_stdin_pretty_output  s    z9TestCLI.test_successful_validation_of_stdin_pretty_outputc                 C   s$   | j tddddddgddd d S r   r}   r~   r   r   r   -test_successful_validation_of_just_the_schema  s    
z5TestCLI.test_successful_validation_of_just_the_schemac                 C   s(   | j tddddddddgdd	d
 d S r   r}   r~   r   r   r   ;test_successful_validation_of_just_the_schema_pretty_output  s    
zCTestCLI.test_successful_validation_of_just_the_schema_pretty_outputc                 C   sx   t jdd}|  | tj|j t|j}|d d|j d}| j	t
|dddd	d
|j d dgddd d S )NFdelete-{"definitions": {"num": {"type": "integer"}}}
{"$ref": "#/definitions/num"}1rQ   rT   rS   
--base-uri/rR   rK   r   tempfileNamedTemporaryFilecloseZ
addCleanuposremovenamer   
write_textrL   rZ   parentas_urir   Zref_schema_fileZref_pathr!   r   r   r   0test_successful_validation_via_explicit_base_uri  s"    


  z8TestCLI.test_successful_validation_via_explicit_base_uric                 C   sz   t jdd}|  | tj|j t|j}|d d|j d}| j	t
|dddd	d
|j d dgdddd d S )NFr   r   r   r   z"1"rQ   rT   rS   r   r   rR   rU   rK   z 1: '1' is not of type 'integer'
rF   rE   rG   r;   r<   r   r   r   r   r   2test_unsuccessful_validation_via_explicit_base_uri  s$    


  z:TestCLI.test_unsuccessful_validation_via_explicit_base_uric              	   C   sh   d}d}|  t.}| jt||ddddt  dgd W 5 Q R X t|j}| 	t
j d	| d S )
Nz4{"$ref": "someNonexistentFile.json#definitions/num"}r   rQ   rT   rS   r   rR   rF   rE   zsomeNonexistentFile.json')r   r   rL   rZ   r   cwdr   r5   r   r   r   sepr   r!   r   r   r7   r   r   r   ,test_nonexistent_file_with_explicit_base_uri  s"      

z4TestCLI.test_nonexistent_file_with_explicit_base_uric              	   C   sX   d}d}|  t&}| jt||ddddddgd	 W 5 Q R X t|j}| |d
 d S )Nz${"$ref": "foo.json#definitions/num"}r   rQ   rT   rS   r   znot@UR1rR   r   zunknown url type: 'foo.json')r   r   rL   rZ   r5   r   rC   r   r   r   r   test_invalid_explicit_base_uri  s(      
 z&TestCLI.test_invalid_explicit_base_uric                 C   s2   |  tt | jtddddddgddd	d
 d S )Nz{"const": "check"}z"a"rQ   rT   rS   rR   rU   rK   za: 'check' was expected
r   )assertIsr   r   rL   rZ   r~   r   r   r   =test_it_validates_using_the_latest_validator_when_unspecified  s    
zETestCLI.test_it_validates_using_the_latest_validator_when_unspecifiedc                 C   s.   d}d}| j t||ddddgddd	d
 dS )zG
        Specifically, `const` validation applies for Draft 7.
        z
            {
                "$schema": "http://json-schema.org/draft-07/schema#",
                "const": "check"
            }
        "foo"rQ   rT   rS   rR   rU   rK   zfoo: 'check' was expected
r   Nr}   r   r   r   r   -test_it_validates_using_draft7_when_specified  s    
z5TestCLI.test_it_validates_using_draft7_when_specifiedc                 C   s,   d}d}| j t||ddddgddd d	S )
zP
        Specifically, `const` validation *does not* apply for Draft 4.
        z
            {
                "$schema": "http://json-schema.org/draft-04/schema#",
                "const": "check"
            }
            r   rQ   rT   rS   rR   rK   r   Nr}   r   r   r   r   -test_it_validates_using_draft4_when_specified*  s    
z5TestCLI.test_it_validates_using_draft4_when_specified)rK   rK   )1r#   r$   r%   r   rJ   rL   r]   r`   rb   ri   rj   ru   rv   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r9   A   s`     
 
)		r9   c                   @   s:   e Zd Ze Zdd Zdd Zdd Zdd Zd	d
 Z	dS )
TestParserc                 C   s*   t dddddg}| |d | j d S )N--validatorz2jsonschema.tests.test_cli.TestParser.FakeValidator
--instancemem://some/instancemem://some/schemarX   )r   r>   r   r'   r   rI   r   r   r   2test_find_validator_by_fully_qualified_object_nameA  s     z=TestParser.test_find_validator_by_fully_qualified_object_namec                 C   s(   t dddddg}| |d t d S )Nr   r
   r   r   r   rX   )r   r>   r   r
   r   r   r   r   !test_find_validator_in_jsonschemaL  s      z,TestParser.test_find_validator_in_jsonschemac                 G   sf   t  t   }}t|: t|& | t t| W 5 Q R X W 5 Q R X W 5 Q R X | | fS r   )r   r   r   r   
SystemExitr   r>   rD   )r   rE   r;   r<   r   r   r   cli_output_forV  s
    (zTestParser.cli_output_forc                 C   s,   |  ddd\}}| d| | | d S )Nr^   rm   r   zinvalid choice: 'foo'r   r   r@   r   r   r   r   test_unknown_output]  s     zTestParser.test_unknown_outputc                 C   s0   |  ddddd\}}| d| | | d S )Nr^   r_   rw   rm   r   z3--error-format can only be used with --output plainr   r   r   r   r   test_useless_error_formate  s      z$TestParser.test_useless_error_formatN)
r#   r$   r%   r*   r'   r   r   r   r   r   r   r   r   r   r   =  s   
r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )TestCLIIntegrationc                 C   s,   t jtjddddgt jd}| d| d S )N-mpipshow
jsonschemar<   s   License: MIT)
subprocesscheck_outputsys
executableSTDOUTr   )r   outputr   r   r   test_licenses  s
    zTestCLIIntegration.test_licensec                 C   sB   t jtjdddddgt jd}|d }| |t	d d S )Nz-Wr   r   r   z	--versionr   zutf-8)
r   r   r   r   r   decodestriprC   r   version)r   r   r   r   r   test_versionz  s    zTestCLIIntegration.test_versionc                 C   sB   t jtjddgt jd}t jtjdddgt jd}| || d S )Nr   r   r   z--help)r   r   r   r   r   rC   )r   r   Zoutput_for_helpr   r   r   #test_no_arguments_shows_usage_notes  s    
z6TestCLIIntegration.test_no_arguments_shows_usage_notesN)r#   r$   r%   r   r  r  r   r   r   r   r   r  s   r   )'
contextlibr   r   	importlibr   ior   r3   r   pathlibr   textwrapr   Zunittestr	   r   r   r   r   warningsr   r
   r   Zjsonschema.exceptionsr   r   r   Zjsonschema.validatorsr   r   catch_warningssimplefilterr   r*   r2   r8   r9   r   r   r   r   r   r   <module>   s<   

		      5