
    iNi              	          U d Z ddl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
mZ ddlmZmZmZ ddlZej"                  j%                  d e ee      j*                  j*                               dZee   ed<   	 ddlZedu Zej6                  j9                  ed	      Zd
ZdZdZ 	 	 d!dedede!de
fdZ"de
de
de#e
   fdZ$ G d d      Z% G d d      Z& G d d      Z' G d d      Z( G d d      Z) G d d       Z*y# e$ r Y w xY w)"u  TDD RED 단계: test_insurance_spider.py

Scrapling Spider ABC를 상속한 InsuranceSpider 클래스와
ResponseHistory 유틸리티에 대한 테스트 스위트.
(insurance_spider.py는 아직 구현되지 않음 - TDD RED 단계)

주의:
- 모든 테스트는 로컬에서 수행 (mock 사용). 외부 네트워크 호출 없음.
- 실제 크롤링 시 반드시 대상 사이트의 robots.txt를 확인하고 준수해야 합니다.
- 합법적 공개 데이터(보험사 공시 페이지 등)만을 대상으로 합니다.
    N)Path)
ModuleType)AnyOptional)	AsyncMock	MagicMockpatch_insurance_spideruH   insurance_spider.py 미구현 (TDD RED 단계 - 토르가 구현 예정))reasonu  
<html>
<body>
  <div class="product">
    <span class="name">화재보험</span>
    <span class="price">50000</span>
  </div>
  <div class="product">
    <span class="name">자동차보험</span>
    <span class="price">100000</span>
  </div>
  <div class="product">
    <span class="name">생명보험</span>
    <span class="price">30000</span>
  </div>
  <a class="next-page" href="/products?page=2">다음</a>
</body>
</html>
u   
<html>
<body>
  <table>
    <tr><th>보험명</th><th>보험료</th><th>가입기간</th></tr>
    <tr><td>화재보험</td><td>50000</td><td>1년</td></tr>
    <tr><td>자동차보험</td><td>100000</td><td>1년</td></tr>
  </table>
</body>
</html>
z
<html>
<body>
  <div class="product">
    <span class="name"></span>
    <span class="price"></span>
  </div>
</body>
</html>
htmlurlstatusreturnc                 D    ddl m}  || |d      }||_        i |_        |S )u   Selector를 Response 대용으로 사용 (Response는 Selector 상속).

    추가 속성(status, meta)만 동적으로 붙인다.
    r   )SelectorF)r   adaptive)scrapling.parserr   r   meta)r   r   r   r   sels        T/home/jay/workspace/.worktrees/task-2116-dev1/scripts/tests/test_insurance_spider.pymake_mock_responser   X   s(     *
4S5
1CCJCHJ    spiderresponsec                 p   K   g }| j                  |      2 3 d{   }|j                  |       7 6 |S w)u9   parse() async generator의 결과를 리스트로 수집.N)parseappend)r   r   resultsitems       r   collect_parse_resultsr    i   s=     Gll8,  dt,Ns   6313636c                       e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd	       Zedd
       Zy)TestResponseHistoryu$   ResponseHistory 클래스 테스트.Nc                 f    t         J t        j                         }|j                         g k(  sJ y)u:   기본 생성 시 히스토리가 비어 있어야 한다.N)r
   ResponseHistoryget_historyselfhistorys     r   test_default_initz%TestResponseHistory.test_default_inity   s5     !,,,#335""$***r   c                     t         J t        j                         }|j                  dd       |j                         }t	        |      dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y)u<   record() 후 get_history()에 항목이 나타나야 한다.Nhttps://example.com      r   r   r   r
   r$   recordr%   lenr'   r(   results      r   test_record_and_get_historyz/TestResponseHistory.test_record_and_get_history   s|     !,,,#335,c2$$&6{aay#8888ay"c)))r   c                 6   t         J t        j                         }|j                  dd       |j                  dd       |j                  dd       |j                         }t	        |      dk(  sJ |d	   d
   dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y)uM   여러 번 record() 시 모든 항목이 순서대로 보존되어야 한다.Nhttps://example.com/ar,   https://example.com/b-  zhttps://example.com/ci     r   r   r-   r      r.   r1   s      r   test_record_multiple_entriesz0TestResponseHistory.test_record_multiple_entries   s     !,,,#335.4.4.4$$&6{aay#::::ay"c)))ay"c)))r   c                     t         J t        j                         }|j                  dd       |j                  dd       |j                  d      }t	        |      dk\  sJ t        d |D              sJ y)uE   get_chain()은 특정 URL에 연결된 항목만 반환해야 한다.Nr5   r,   r6   r7   r-   c              3   ,   K   | ]  }|d    dk(    yw)r   r5   N ).0entrys     r   	<genexpr>z@TestResponseHistory.test_get_chain_single_url.<locals>.<genexpr>   s     Nu5<#::Ns   )r
   r$   r/   	get_chainr0   any)r'   r(   chains      r   test_get_chain_single_urlz-TestResponseHistory.test_get_chain_single_url   sq     !,,,#335.4.4!!"9:5zQNNNNNr   c                     t         J t        j                         }ddg}|j                  dd|       |j                  d      }t	        |      dk\  sJ |d   }d	|v sJ |d	   |k(  sJ y)
uL   redirects 인자를 통해 리다이렉트 체인이 보존되어야 한다.Nzhttps://example.com/oldzhttps://example.com/redirectzhttps://example.com/newr,   )	redirectsr-   r   rF   )r
   r$   r/   rA   r0   )r'   r(   rF   rC   r?   s        r   test_redirect_chain_preservedz1TestResponseHistory.test_redirect_chain_preserved   s     !,,,#335.0NO	% 	 	

 !!";<5zQae###[!Y...r   c                     t         J t        j                         }ddd}|j                  dd|       |j                         }t	        |      dk(  sJ |d	   j                  d
      |k(  sJ y)u3   headers 인자가 기록에 포함되어야 한다.Nz	text/htmlvalue)zContent-TypezX-Customr+   r,   )headersr-   r   rJ   )r
   r$   r/   r%   r0   get)r'   r(   rJ   r2   s       r   test_record_with_headersz,TestResponseHistory.test_record_with_headers   sv     !,,,#335#.GD,c7C$$&6{aay}}Y'7222r   c                    t         J t        j                         }|j                  dd       |j                  dd       t        j                         5 }t        |      dz  }|j                  t        |             |j                         sJ t        j                  |j                  d            }t        |t              sJ t        |      dk(  sJ |d	   d
   dk(  sJ 	 ddd       y# 1 sw Y   yxY w)u=   save()는 히스토리를 JSON 파일로 저장해야 한다.Nr+   r,   zhttps://example.com/page2zhistory.jsonzutf-8)encodingr9   r   r   )r
   r$   r/   tempfileTemporaryDirectoryr   savestrexistsjsonloads	read_text
isinstancelistr0   )r'   r(   tmpdirpathdatas        r   test_save_to_json_filez*TestResponseHistory.test_save_to_json_file   s     !,,,#335,c22C8((* 	;f<.0DLLT#;;= =::dnngn>?DdD)))t9>!>75>%::::	; 	; 	;s   BC..C7c                     t         J t        j                         }|j                  dd       t        |j	                               dk(  sJ |j                          |j	                         g k(  sJ y)u4   clear() 후 히스토리가 비어 있어야 한다.Nr+   r,   r-   )r
   r$   r/   r0   r%   clearr&   s     r   
test_clearzTestResponseHistory.test_clear   si     !,,,#335,c27&&()Q...""$***r   r   N)__name__
__module____qualname____doc___skip_if_missingr)   r3   r:   rD   rG   rL   r\   r_   r=   r   r   r"   r"   v   s    .+ + * * * * O O / /  3 3 ; ;  + +r   r"   c                       e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd	       Zedd
       Zy)TestInsuranceSpiderInitu$   InsuranceSpider 초기화 테스트.Nc                 R    t         J t         j                  j                  dk(  sJ y)u/   name 속성이 'insurance_spider'여야 한다.Ninsurance_spider)r
   InsuranceSpidername)r'   s    r   test_name_attributez+TestInsuranceSpiderInit.test_name_attribute   s+     !,,, 00559KKKKr   c                     t         J t        j                  dg      }|j                  dk(  sJ |j                  dk(  sJ |j                  dk(  sJ y)u\   concurrent_requests=4, concurrent_requests_per_domain=2, download_delay=1.0이어야 한다.Nr+   
start_urls   r9   g      ?)r
   rj   concurrent_requestsconcurrent_requests_per_domaindownload_delayr'   r   s     r   !test_concurrent_requests_defaultsz9TestInsuranceSpiderInit.test_concurrent_requests_defaults   s`     !,,,"22?T>UV))Q...44999$$+++r   c                 j    t         J ddg}t        j                  |      }|j                  |k(  sJ y)u=   생성자에서 start_urls를 설정할 수 있어야 한다.Nr5   r6   rn   )r
   rj   ro   )r'   urlsr   s      r   test_start_urls_setz+TestInsuranceSpiderInit.test_start_urls_set   s?     !,,,')@A"22dC  D(((r   c                 n    t         J ddh}t        j                  dg|      }|j                  |k(  sJ y)uB   생성자에서 allowed_domains를 설정할 수 있어야 한다.Nzexample.comzinsurance.co.krr+   )ro   allowed_domains)r
   rj   rz   )r'   domainsr   s      r   test_allowed_domains_setz0TestInsuranceSpiderInit.test_allowed_domains_set   sJ     !,,, "34"22-.#
 %%000r   c                     t         J t        j                  dg      }t        |j                        t        d      k(  sJ y)u7   output_dir 기본값은 'crawl_output'이어야 한다.Nr+   rn   crawl_outputr
   rj   r   
output_dirrt   s     r   test_output_dir_defaultz/TestInsuranceSpiderInit.test_output_dir_default  sB     !,,,"22?T>UVF%%&$~*>>>>r   c                     t         J t        j                  dgd      }t        |j                        t        d      k(  sJ y)u=   output_dir을 커스텀으로 설정할 수 있어야 한다.Nr+   z/tmp/test_outputro   r   r   rt   s     r   test_output_dir_customz.TestInsuranceSpiderInit.test_output_dir_custom  sJ     !,,,"22-.)
 F%%&$/A*BBBBr   c                 ^    t         J t        j                  dg      }|j                  J y)u4   extraction_config 기본값은 None이어야 한다.Nr+   rn   r
   rj   extraction_configrt   s     r   #test_extraction_config_default_nonez;TestInsuranceSpiderInit.test_extraction_config_default_none  s6     !,,,"22?T>UV''///r   c                 v    t         J ddddid}t        j                  dg|      }|j                  |k(  sJ y)	uD   extraction_config를 딕셔너리로 설정할 수 있어야 한다.Ncss.productrk   .namemodecss_selectorfieldsr+   ro   r   r   )r'   configr   s      r   test_extraction_config_setz2TestInsuranceSpiderInit.test_extraction_config_set  sQ     !,,,PWGXY"22-.$
 ''6111r   r`   )ra   rb   rc   rd   re   rl   ru   rx   r|   r   r   r   r   r=   r   r   rg   rg      s    .L L
 , , ) ) 1 1 ? ? C C 0 0 2 2r   rg   c                   |    e Zd ZdZed	d       Zed	d       Zed	d       Zed	d       Zed	d       Z	ed	d       Z
y)
TestInsuranceSpiderParseu,   InsuranceSpider.parse() 메서드 테스트.Nc                 B   t         J dddddd}t        j                  dg|	      }t        t        d
      }t	        j
                  t        ||            }|D cg c]  }t        |t              s| }}t        |      dk\  sJ d|d   v s
d|d   v sJ yyc c}w )uQ   CSS 모드에서 extraction_config 기반으로 아이템을 추출해야 한다.Nr   r   r   z.pricerk   pricer   r+   r   r   r-   rk   r   r   
r
   rj   r   HTML_PRODUCTSasynciorunr    rW   dictr0   r'   r   r   r   r   ritemss          r   "test_parse_css_mode_extracts_itemsz;TestInsuranceSpiderParse.test_parse_css_mode_extracts_items2  s     !,,,&&:

 #22-.$
 &m9NO++3FHEF#;qz!T':;;5zQq!Wa%888%8! <s   B4Bc                 @   t         J ddd}t        j                  dg|      }t        t        d      }t	        j
                  t        ||            }|D cg c]  }t        |t              s| }}t        |      dk\  sJ t        d |D              sJ yc c}w )	u>   table 모드에서 테이블 데이터를 추출해야 한다.Ntable)r   table_selectorr+   r   r   r-   c              3   0   K   | ]  }d |v xs d|v   yw)u	   보험명col_0Nr=   )r>   r   s     r   r@   zATestInsuranceSpiderParse.test_parse_table_mode.<locals>.<genexpr>X  s!     Ld;$&9'T/9Ls   )r
   rj   r   
HTML_TABLEr   r   r    rW   r   r0   rB   r   s          r   test_parse_table_modez.TestInsuranceSpiderParse.test_parse_table_modeG  s     !,,,%
 #22-.$
 &j6KL++3FHEF#;qz!T':;;5zQLeLLLL <s   B0Bc                     t         J ddddid}t        j                  dg|      }t        t        d	      }t	        j
                  t        ||            }t        |t              sJ y)
uA   similar 모드에서 유사 요소 추출이 동작해야 한다.Nsimilarr   rk   r   )r   reference_selectorr   r+   r   r   )	r
   rj   r   r   r   r   r    rW   rX   )r'   r   r   r   r   s        r   test_parse_similar_modez0TestInsuranceSpiderParse.test_parse_similar_modeZ  su     !,,,",w'

 #22-.$
 &m9NO++3FHEF'4(((r   c                 B   t         J ddddid}t        j                  dg|      }t        t        d	
      }t	        j
                  t        ||            }|D cg c]  }t        |t              sd|v s| }}t        |      dk\  sJ |d   d   d	k(  sJ yc c}w )uG   각 아이템에 _source_url 메타데이터가 첨부되어야 한다.Nr   r   rk   r   r   r+   r   https://example.com/productsr   _source_urlr-   r   r   r   s          r   #test_parse_adds_source_url_metadataz<TestInsuranceSpiderParse.test_parse_adds_source_url_metadatal  s     !,,,&w'

 #22-.$
 &m9WX++3FHEF#Rqz!T':}PQ?QRR5zQQx&*HHHH Ss   B3B8Bc                 $   t         J ddlm} ddddidd	}t        j                  d
g|      }t	        t
        d      }t        j                  t        ||            }|D cg c]  }t        ||      s| }}t        |      dk\  sJ yc c}w )uO   next_page_selector가 있으면 다음 페이지 Request를 yield해야 한다.Nr   Requestr   r   rk   r   z
.next-page)r   r   r   next_page_selectorr+   r   r   r   r-   )r
   scrapling.spidersr   rj   r   r   r   r   r    rW   r0   )r'   r   r   r   r   r   r   requestss           r   test_parse_next_page_followz4TestInsuranceSpiderParse.test_parse_next_page_follow  s     !,,,- &w'".	
 #22-.$
 &m9WX++3FHEF&A!*Q*@AAA8}!!! Bs   $B6Bc                    t         J t        j                  dgd      }t        t        d      }t	        j
                  t        ||            }|D cg c]  }t        |t              s| }}t        |      dk(  sJ yc c}w )uJ   extraction_config가 None이면 아이템을 yield하지 않아야 한다.Nr+   r   r   r   r   )r'   r   r   r   r   r   s         r   .test_parse_no_extraction_config_yields_nothingzGTestInsuranceSpiderParse.test_parse_no_extraction_config_yields_nothing  s     !,,,"22-."
 &m9NO++3FHEF#;qz!T':;;5zQ <s   B+Br`   )ra   rb   rc   rd   re   r   r   r   r   r   r   r=   r   r   r   r   /  s    69 9( M M$ ) )" I I$ " "* 
 
r   r   c                       e Zd ZdZed
d       Zed
d       Zed
d       Zed
d       Zed
d       Z	ed
d       Z
ed
d	       Zy)TestInsuranceSpiderHooksu(   InsuranceSpider 훅 메서드 테스트.Nc                 4   t         J t        j                         5 }t        |      dz  }t        j                  dgt        |            }t        j                  |j                  d             |j                         sJ 	 ddd       y# 1 sw Y   yxY w)u0   on_start()는 output_dir을 생성해야 한다.Nspider_outputr+   r   Fresuming)
r
   rO   rP   r   rj   rR   r   r   on_startrS   )r'   rY   r   r   s       r    test_on_start_creates_output_dirz9TestInsuranceSpiderHooks.test_on_start_creates_output_dir  s     !,,,((* 	'ff7J&6612z?F KK78$$&&&	' 	' 	's   A'BBc                     t         J t        j                         5 }t        j                  dg|      }t	        j
                  |j                  d             ddd       y# 1 sw Y   yxY w)u@   on_start(resuming=True)는 예외 없이 실행되어야 한다.Nr+   r   Tr   )r
   rO   rP   rj   r   r   r   )r'   rY   r   s      r   test_on_start_resuming_flagz4TestInsuranceSpiderHooks.test_on_start_resuming_flag  se     !,,,((* 	8f&6612!F
 KK67	8 	8 	8s   >A$$A-c                    t         J t        j                         5 }t        j                  dg|      }|j                  j                  dd       t        j                  |j                  d             t        j                  |j                                t        t        |      j                  d            }t        |      dk\  sJ 	 ddd       y# 1 sw Y   yxY w)	u?   on_close()는 ResponseHistory를 파일로 저장해야 한다.Nr+   r   r,   Fr   z	*history*r-   )r
   rO   rP   rj   response_historyr/   r   r   r   on_closerX   r   globr0   )r'   rY   r   history_filess       r   test_on_close_saves_historyz4TestInsuranceSpiderHooks.test_on_close_saves_history  s     !,,,((* 	+f&6612!F
 ##**+@#FKK78KK)* f!2!2;!?@M}%***	+ 	+ 	+s   B0CC c                     t         J ddlm} t        j                  dg      } |d      }t	        d      }t        j                  |j                  ||             y)u:   on_error()는 예외 없이 에러를 로깅해야 한다.Nr   r   r+   rn   zConnection failed)r
   r   r   rj   ConnectionErrorr   r   on_error)r'   r   r   requesterrors        r   test_on_error_logs_errorz1TestInsuranceSpiderHooks.test_on_error_logs_error  sT     !,,,-"22?T>UV/0 34FOOGU34r   c                     t         J t        j                  dg      }ddd}t        j                  |j	                  |            }||k(  sJ y)u5   유효한 아이템은 그대로 반환해야 한다.Nr+   rn      화재보험50000r   r
   rj   r   r   on_scraped_itemr'   r   r   r2   s       r   &test_on_scraped_item_passes_valid_itemz?TestInsuranceSpiderHooks.test_on_scraped_item_passes_valid_item  sS     !,,,"22?T>UV&9V33D9:~~r   c                     t         J t        j                  dg      }ddd}t        j                  |j	                  |            }|J y)uR   모든 값이 None이나 빈 문자열이면 None을 반환해야 한다 (드롭).Nr+   rn    r   r   )r'   r   
empty_itemr2   s       r   'test_on_scraped_item_filters_empty_itemz@TestInsuranceSpiderHooks.test_on_scraped_item_filters_empty_item  sQ     !,,,"22?T>UV.2R%@
V33J?@~~r   c                     t         J t        j                  dg      }ddd}t        j                  |j	                  |            }|J |d   dk(  sJ y)uG   일부 값만 비어 있는 경우 아이템을 통과시켜야 한다.Nr+   rn   r   r   rk   r   r   s       r   )test_on_scraped_item_partial_empty_passeszBTestInsuranceSpiderHooks.test_on_scraped_item_partial_empty_passes  se     !,,,"22?T>UV&6V33D9:!!!f~///r   r`   )ra   rb   rc   rd   re   r   r   r   r   r   r   r   r=   r   r   r   r     s    2
' 
' 	8 	8 + +  	5 	5     0 0r   r   c                   X    e Zd ZdZedd       Zedd       Zedd       Zedd       Zy)TestInsuranceSpiderRunu<   InsuranceSpider.run() 메서드 및 출력 형식 테스트.Nc                 D   t         J ddlm}m}m} t        j
                  dg      } | |dd       |d	d
ig            }t        j                  |d|      5 }|j                         }|j                          t        ||      sJ 	 ddd       y# 1 sw Y   yxY w)uD   run()은 start()를 호출하고 CrawlResult를 반환해야 한다.Nr   CrawlResult
CrawlStatsItemListr+   rn   r-   r9   requests_countitems_scrapedrk   u   보험Astatsr   startreturn_value)r
   scrapling.spiders.resultr   r   r   rj   r	   objectr   assert_called_oncerW   )r'   r   r   r   r   mock_result
mock_startr2   s           r   -test_run_calls_start_and_returns_crawl_resultzDTestInsuranceSpiderRun.test_run_calls_start_and_returns_crawl_result  s     !,,,NN"22?T>UV!AQ?VY/01
 \\&'D 	3
ZZ\F))+fk222	3 	3 	3s   /BBc                    t         J ddlm}m}m} t        j                         5 }t        j                  dg|      } |ddiddig      } | |d	d	
      |      }t        j                  |d|      5  |j                  d       ddd       t        t        |      j                  d            }t        |      dk\  sJ 	 ddd       y# 1 sw Y   FxY w# 1 sw Y   yxY w)uB   run(output_format='jsonl')은 JSONL 파일로 내보내야 한다.Nr   r   r+   r   rk   r   u   자동차보험r9   r   r   r   r   jsonloutput_formatz*.jsonlr-   r
   r   r   r   r   rO   rP   rj   r	   r   r   rX   r   r   r0   )	r'   r   r   r   rY   r   
mock_itemsr   jsonl_filess	            r   test_run_exports_jsonlz-TestInsuranceSpiderRun.test_run_exports_jsonl  s     !,,,NN((* 	)f&6612!F "FN#;fFW=X"YZJ% C K fgKH 2


12 tF|00;<K{#q(((	) 	)2 2	) 	)s$   AC8C;CC	CC%c                    t         J ddlm}m}m} t        j                         5 }t        j                  dg|      } |ddig      } | |dd	      |
      }t        j                  |d|      5  |j                  d       ddd       t        t        |      j                  d            }t        |      dk\  sJ 	 ddd       y# 1 sw Y   FxY w# 1 sw Y   yxY w)u@   run(output_format='json')은 JSON 파일로 내보내야 한다.Nr   r   r+   r   rk   r   r-   r   r   r   r   rT   r   z*.jsonr   )	r'   r   r   r   rY   r   r   r   
json_filess	            r   test_run_exports_jsonz,TestInsuranceSpiderRun.test_run_exports_json-  s     !,,,NN((* 	(f&6612!F "FN#;"<=J% C K fgKH 1


01d6l//9:Jz?a'''	( 	(1 1	( 	(s$   AC5C;CC	CC"c                     t         J t         j                  j                  ddgdddd      }t        |t              sJ |d	   dk(  sJ |d
   dgk(  sJ |d   dk(  sJ d|v sJ y)uZ   create_cron_config()는 cokacdir --cron 연동 설정 딕셔너리를 반환해야 한다.Nz	0 6 * * *zhttps://example.com/insurancez/data/insurancer   r   )r   r   )schedulero   r   r   r   ro   r   r   )r
   rj   create_cron_configrW   r   )r'   r   s     r   test_create_cron_configz.TestInsuranceSpiderRun.test_create_cron_configB  s     !,,,"22EE 78(',jI	 F 
 &$'''j![000l#(G'HHHHl#'8888"f,,,r   r`   )	ra   rb   rc   rd   re   r   r   r   r  r=   r   r   r   r     sS    F3 3 ) )* ( (( - -r   r   c                   X    e Zd ZdZedd       Zedd       Zedd       Zedd       Zy)TestCheckpointIntegrationu&   Checkpoint(crawldir) 통합 테스트.Nc                     t         J t        j                         5 }t        |      dz  }t        j                  dgt        |            }|j                  |k(  sJ 	 ddd       y# 1 sw Y   yxY w)uC   crawldir을 지정하면 Spider.crawldir에 반영되어야 한다.Ncheckpointsr+   )ro   crawldir)r
   rO   rP   r   rj   rR   r  )r'   rY   r  r   s       r   test_crawldir_is_setz.TestCheckpointIntegration.test_crawldir_is_set[  sr     !,,,((* 	/fF|m3H&6612XF ??h...	/ 	/ 	/s   AA((A1c                 ^    t         J t        j                  dg      }|j                  J y)u?   crawldir 미지정 시 Spider.crawldir이 None이어야 한다.Nr+   rn   )r
   rj   r  rt   s     r   test_crawldir_none_by_defaultz7TestCheckpointIntegration.test_crawldir_none_by_defaultg  s4     !,,,"22?T>UV&&&r   c                 f    t         J t        j                  dgd      }|j                  dk(  sJ y)uD   interval 파라미터가 _interval 속성에 반영되어야 한다.Nr+   g     @)ro   intervalr
   rj   	_intervalrt   s     r   test_checkpoint_interval_setz6TestCheckpointIntegration.test_checkpoint_interval_setn  s?     !,,,"22-.
 5(((r   c                 d    t         J t        j                  dg      }|j                  dk(  sJ y)u,   interval 기본값은 300.0이어야 한다.Nr+   rn   g     r@r  rt   s     r    test_checkpoint_interval_defaultz:TestCheckpointIntegration.test_checkpoint_interval_defaultx  s8     !,,,"22?T>UV5(((r   r`   )	ra   rb   rc   rd   re   r  r	  r  r  r=   r   r   r  r  X  sS    0	/ 	/ ' ' ) ) ) )r   r  )r+   r,   )+rd   r   rT   sysrO   pathlibr   typesr   typingr   r   unittest.mockr   r   r	   pytestrZ   insertrR   __file__parentr
   __annotations__ri   ModuleNotFoundError_MISSINGmarkskipifre   r   r   HTML_EMPTY_ITEMSintr   rX   r    r"   rg   r   r   r   r  r=   r   r   <module>r!     s^  
   
      5 5  3tH~,,334 5 +/ 8J' .	0 $;;%%U &  (

	  %
	  		" s tCy c+ c+VF2 F2\q qrT0 T0xL- L-h%) %)s  		s   =D D	D	