
    P1i7              
          d 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 ej                  j                  dej                  j                  ej                  j                  ej                  j                  e                         ddlmZ ddlmZ ddlmZ  G d dej$                        Zed	k(  r ej*                          yy)
a  
Comprehensive unit tests for calendar functionality including solar terms, lunar dates, jian chu, and leap flags.

This test suite validates the correctness of all calendar components using the positional binary format.
Test data is sourced from calendar10k/tests/test_data.txt
    Ndate)PositionalBinaryCalendarReader)!PositionalBinaryCalendarGenerator)test_safe_printc                       e Zd ZdZed        Zd Zd Zed        Zd Z	d Z
d Zd	 Zd
 Zd ZdedefdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d# Z&d$ Z'y%)&TestComprehensiveCalendarzKComprehensive tests for solar terms, lunar dates, jian chu, and leap flags.c           	      b   t        j                  d      | _        g d| _        t	        | j                        | _        i | _        | j                  D ]\  }| j
                  j                  |d      }|| j                  |<   t        d| dt        j                  j                  |       d       ^ t        | j                        | _        g | _        t        j                  j                  t        j                  j!                  t        j                  j!                  t        j                  j!                  t"                          dd	d
      }	 t%        |dd      5 }|D ]  }|j'                         }|s|j)                  d      r(|j+                  dd      }t-        |      dk(  sI|\  }}t/        j0                  |      }	| j                  j3                  |	|f        	 ddd       t        dt-        | j                         d       y# 1 sw Y   ,xY w# t4        $ r
 g | _        Y Aw xY w)zHSet up test data directory and generate binary files for multiple years.calendar_comprehensive_test_prefix)      %      i\  i  i        i      i  i  i  i  i  i  4.0.0z
Generated  (z bytes)ichingtestszyellow_black_test_data.txtrzutf-8)encoding#       NzLoaded z/ YBP test cases from yellow_black_test_data.txt)tempfilemkdtemptest_data_dir
test_yearsr   	generatorbinary_filesgenerate_positional_year_filer   ospathgetsizer   readerybp_test_datajoindirname__file__openstrip
startswithsplitlenr   fromisoformatappendFileNotFoundError)
clsyearbinary_fileybp_test_file_pathflinepartsdate_strexpected_god	test_dates
             O/home/cursorai/projects/iching/calendar10k/tests/test_comprehensive_calendar.py
setUpClassz$TestComprehensiveCalendar.setUpClass   s    %,,4RSI
 :#:K:KLNND--EEdGTK%0CT"jR8T7UU\]^ # 4C4E4EF
 WW\\GGOOBGGOOBGGOOH,EFGg;

	#(#@AD::<DDOOC$8 $

3 2u:?5:2Hl(,(:(:8(DI--44i5NO  A 	'#c&7&7"8!99hij A@ ! 	# "C	#s<   H H7H	 H*9H$H HH H.-H.c                    ddl }ddl} |j                  d      }t        |      }| j                  D ]  }|j                  |d        t        |      }t        | d      sg | _        | j                  j                  ||f       |S )a  Create a fresh reader with v4.0.0 format to avoid binary offset corruption.
        
        When binary structure changed from v3.0.0 to v4.0.0, all day data positions
        shifted by 18 bytes. Using fresh readers prevents cached offset issues.
        r   Ncalendar_test_fresh_r   r   _temp_readers)
r#   shutilr$   r   r&   r)   r   hasattrrH   r8   )selfr#   rI   temp_dirr'   r;   r-   s          rD   _get_fresh_readerz+TestComprehensiveCalendar._get_fresh_readerH   s     	 $8##+AB 6h?	OOD33D'B $ 09 t_-!#D!!68"45    c                     t        | d      rQ| j                  D ]:  \  }}t        j                  j	                  |      s&t        j                  |       < g | _        yy)z4Clean up any temporary readers created during tests.rH   N)rJ   rH   r*   r+   existsrI   rmtree)rK   r-   rL   s      rD   tearDownz"TestComprehensiveCalendar.tearDownc   sL    4)$($6$6 77>>(+MM(+ %7 "$D	 *rN   c                     t        | d      rbt        j                  j                  | j                        r8t        j                  | j                         t        d| j                          yyy)zClean up test data directory.r%   zTest cleanup: Removed N)rJ   r*   r+   rP   r%   rI   rQ   r   )r:   s    rD   tearDownClassz'TestComprehensiveCalendar.tearDownClassk   sU     3(RWW^^C<M<M-NMM#++,4S5F5F4GHI .O(rN   c                 ,   ddt        ddd      dfddt        ddd      d	fd
dt        dd
d      dfddt        dd
d      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfdd t        ddd!      d"fd#d$t        ddd      d%fd&d't        ddd!      d(fd)d*t        ddd      d+fd,d-t        ddd.      d/fd0d1t        ddd      d2fd3d4t        ddd5      d6fd7d8t        ddd      d9fd:d;t        ddd5      d<fdd=t        dd#d      d>fd?d@t        dd#d5      dAfddBt        dd&d      dCfd!dDt        dd&d.      dEfd.dFt        dd)d      dGfd5dHt        dd)d!      dIfg}| j                  d|       yJ)KzTest 2025 solar terms accuracy.r      小寒r   r!      z10:32:46   大寒   z04:00:07r"      立春   z22:10:28   雨水   z18:06:34      惊蛰z16:07:16   春分z17:01:29      清明z20:48:34      谷雨z03:56:01      立夏z13:57:11	      小满   z02:54:38
      芒种z17:56:31      夏至z10:42:16      小暑z04:04:59      大暑   z21:29:27      立秋z13:51:35      处暑   z04:33:51      白露z16:51:57      秋分z02:19:20   寒露z08:41:12      霜降z11:50:55   立冬z12:04:03   小雪z09:35:35   大雪z05:04:35   冬至z23:03:05Nr   _test_solar_terms_for_yearrK   expected_termss     rD   test_solar_terms_2025z/TestComprehensiveCalendar.test_solar_terms_2025v   s    4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4a+z:4a,z:4b!,z:4b"-z:4b!,z:4b"-z:4b!,z:4b"-z:1
6 	''n=rN   c           
         | j                         }| j                  D ]  }| j                  |      5  |j                  |      }| j	                  t        |      dd|        |D cg c]  }|d   	 }}| j	                  t        |      t        t        d            d|        ddd        yc c}w # 1 sw Y   xY w)z8Test that all years have complete set of 24 solar terms.r;      'Should have exactly 24 solar terms for jq_indexzShould have indices 0-23 for N)rM   r&   subTest"get_solar_terms_in_year_positionalassertEqualr6   setrange)rK   r-   r;   solar_termstermindicess         rD   test_solar_terms_completenessz7TestComprehensiveCalendar.test_solar_terms_completeness   s    '')OOD4($GGM  [!129`ae`f7gh 9DD4
+D  Ws59~A^_c^d?ef )( $ E )(s   5B6'B133B61B66B?	c                 ,   ddt        ddd      dfddt        ddd      d	fd
dt        dd
d      dfddt        dd
d      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfd d!t        ddd      d"fd#d$t        ddd      d%fd&d't        ddd      d(fd)d*t        ddd      d+fd,d-t        ddd.      d/fd0d1t        ddd      d2fd3d4t        ddd.      d5fd6d7t        dd d      d8fd9d:t        dd d.      d;fd<d=t        dd#d      d>fdd?t        dd#d.      d@fddAt        dd&d      dBfddCt        dd&dD      dEfdDdFt        dd)d      dGfd.dHt        dd)dD      dIfg}| j                  d|       yJ)KzTest 1965 solar terms accuracy.r   rV   r   r!   rW   z21:01:51rX   rY   z14:28:45r"   rZ   r^   z08:46:00r[   r\   r}   z04:47:42r_   ra   z03:00:31r`   ri   z04:04:37rb   z08:06:35rc   rd   z15:25:56re   rf   z01:41:24rg   rh   z14:50:06rj   rk   z06:01:59rl   rm   z22:55:34rn   ro   z16:21:15rp   rq   rw   z09:48:03rs   rt   z02:04:29ru   rv   z16:42:36rx   ry   z04:47:44rz   r{   z14:05:52r]   r|   z20:11:01r~   z23:09:50r   z23:06:26r   rr   z20:29:03r   z15:45:27r   z09:40:18Nr   r   s     rD   test_solar_terms_1965z/TestComprehensiveCalendar.test_solar_terms_1965       4a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94a+Z84a,j94b!,j94b"-z:4b!,j94b"-z:4b!,j94b"-z:1
6 	''n=rN   c                 ,   ddt        ddd      dfddt        ddd      d	fd
dt        dd
d      dfddt        dd
d      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfdd t        ddd      d!fd"d#t        ddd      d$fd%d&t        ddd'      d(fd)d*t        ddd      d+fd,d-t        ddd.      d/fd0d1t        ddd      d2fd3d4t        ddd.      d5fd6d7t        ddd      d8fd9d:t        ddd.      d;fd<d=t        dd"d      d>fdd?t        dd"d@      dAfddBt        dd%d      dCfd'dDt        dd%d.      dEfd.dFt        dd)d      dGfd@dHt        dd)d'      dIfg}| j                  d|       yJ)KzTest 2020 solar terms accuracy.r   rV   r   r!   ra   z05:30:06rX   rY   z22:54:40r"   rZ   r^   z17:03:20r[   r\   r}   z12:57:00r_   rW   z10:56:53r`   z11:49:37rb   z15:38:10rc   rd   z22:45:29re   rf   z08:51:23rg   rh   z21:49:17rj   rk   z12:58:26rl   rm   ri   z05:43:41rn   ro   z23:14:27rp   rq   rr   z16:36:53rs   rt   z09:06:12ru   rv   z23:44:56rx   ry   z12:08:03rz   r{   z21:30:39r]   r|   z03:55:16r~   rw   z06:59:32r   z07:13:55r   z04:39:46r   z00:09:30r   z18:02:20Nr   r   s     rD   test_solar_terms_2020z/TestComprehensiveCalendar.test_solar_terms_2020   r   rN   c                 ,   ddt        ddd      dfddt        ddd      d	fd
dt        dd
d      dfddt        dd
d      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfddt        ddd      dfd d!t        ddd      d"fd#d$t        ddd      d%fd&d't        ddd      d(fd)d*t        ddd      d+fd,d-t        ddd.      d/fd0d1t        ddd      d2fd3d4t        ddd.      d5fd6d7t        dd d      d8fd9d:t        dd d.      d;fdd<t        dd#d      d=fdd>t        dd#d?      d@fddAt        dd&d      dBfdCdDt        dd&dC      dEfd.dFt        dd)d      dGfd?dHt        dd)dC      dIfg}| j                  d|       yJ)KzTest 2085 solar terms accuracy.r   rV   r   r!   r^   z23:57:40rX   r}   z17:24:59r"   rZ   r[   z11:31:13r\   r]   z07:20:55r_   rW   z05:11:51r`   rY   z05:54:55ra   rb   z09:29:40rc   rd   z16:24:10re   rf   z02:14:24rg   rh   z15:00:21rj   rk   z05:55:58rl   rm   z22:34:13rn   ro   z15:57:43rp   rq   rr   z09:20:51rs   rt   z01:50:50ru   rv   z16:37:48rx   ry   z05:08:51rz   r{   z14:44:54r|   z21:21:49r~   rw   z00:41:34r   z01:09:00ri   r   z22:48:37r   z18:28:27r   z12:30:08Nr   r   s     rD   test_solar_terms_2085z/TestComprehensiveCalendar.test_solar_terms_2085   r   rN   c                     | j                         }g d}|j                  d      }t        |d       }|D cg c]  }|d   	 }}| j                  ||d       yc c}w )z2Test that solar term names are correct in Chinese.)rV   rX   rZ   r\   r_   r`   rb   rd   rf   rh   rk   rm   ro   rq   rt   rv   ry   r{   r|   r~   r   r   r   r   r   c                     | d   S )Nr    )xs    rD   <lambda>zCTestComprehensiveCalendar.test_solar_terms_naming.<locals>.<lambda>  s    :rN   )keynamez4Solar term names should match expected Chinese namesN)rM   r   sortedr   )rK   r-   expected_namesr   sorted_termsr   actual_namess          rD   test_solar_terms_namingz1TestComprehensiveCalendar.test_solar_terms_naming   sk    '')
 ??E k/FG1=>V>~N	P ?s   Ar;   r   c           
         | j                         }|j                  |      }| j                  t        |      dd|        |D ci c]  }|d   |
 }}|D ]  \  }}}	}
| j	                  |||      5  | j                  ||d| d|        ||   }| j                  |d   |d| d	|        | j                  |d
   |	d| d|        | j                  |d   |
d| d|        ddd        yc c}w # 1 sw Y   xY w)zUHelper method to test solar terms for a specific year with v4.0.0 HH:MM:SS precision.r   r   r   )r;   indexr   zSolar term index z not found in r   zName mismatch for z index r   zDate mismatch for r    jq_timezTime mismatch for N)rM   r   r   r6   r   assertIn)rK   r;   r   r-   r   r   terms_by_indexexpected_indexexpected_nameexpected_dateexpected_times              rD   r   z4TestComprehensiveCalendar._test_solar_terms_for_year  sF   '')??E[)21XY]X^/_` >II[T$z*D0[IKYGNM=-4~MRnn00@tfUW &n5  f}!3D6@PQS  f}!3D6=/JL  i-!3D6=/JL SR LZ J SRs   C02A3C55C>	c                 d   | j                         }t        ddd      }t        ddd      }|}||k  rs| j                  |      5  |j                  |      }| j	                  |d|        | j                  |d   d	d
|        ddd       ddlm} | |d	      z  }||k  rryy# 1 sw Y   #xY w)z=Test leap flag is 1 for 2025-07-25 to 2025-08-22 (inclusive).r   rc      re   rr   r   Should get date info for 	leap_flagr!   Leap flag should be 1 for Nr   	timedeltadaysrM   r   r   get_date_info_positionalassertIsNotNoner   datetimer   rK   r-   
start_dateend_datecurrent_date	date_infor   s          rD   test_leap_flag_2025_positivez6TestComprehensiveCalendar.test_leap_flag_2025_positive,      '')$2&
a$!h&<0";;LI	$$Y2KL>0Z[  ;!7!;L>JL 1 +I1--L h&00   A B&&B/c                 d   | j                         }t        ddd      }t        ddd      }|}||k  rs| j                  |      5  |j                  |      }| j	                  |d|        | j                  |d   d	d
|        ddd       ddlm} | |d	      z  }||k  rryy# 1 sw Y   #xY w)z=Test leap flag is 1 for 2020-05-23 to 2020-06-20 (inclusive).r   rW   rw   ra   rY   r   r   r   r!   r   Nr   r   r   r   r   s          rD   test_leap_flag_2020_positivez6TestComprehensiveCalendar.test_leap_flag_2020_positive?  r   r   c                    ddl m} t        ddd      }t        ddd      }|}d}||k  r|| j                  |      5  | j                  j                  |      }| j                  |d|        | j                  |d	   dd
| d       ddd       | |d      z  }|dz  }||k  r|| j                  |dd       y# 1 sw Y   4xY w)z*Test leap flag is 0 for all dates in 2011.r   r   r   r!   rn      r   r   r   Leap flag should be 0 for z (2011 has no leap month)Nr   m  z'Should have tested all 365 days of 2011r   r   r   r   r-   r   r   r   rK   r   r   r   r   	day_countr   s          rD   %test_leap_flag_2011_negative_all_daysz?TestComprehensiveCalendar.test_leap_flag_2011_negative_all_daysR      & $1%
b"%!	h&<0 KK@@N	$$Y2KL>0Z[  ;!7!;L>Ibce 1 I1--LNI h& 	C)RS 10   AB::Cc                    ddl m} t        ddd      }t        ddd      }|}d}||k  r|| j                  |      5  | j                  j                  |      }| j                  |d|        | j                  |d	   dd
| d       ddd       | |d      z  }|dz  }||k  r|| j                  |dd       y# 1 sw Y   4xY w)z*Test leap flag is 0 for all dates in 2065.r   r   r   r!   rn   r   r   r   r   r   z (2065 has no leap month)Nr   r   z'Should have tested all 365 days of 2065r   r   s          rD   %test_leap_flag_2065_negative_all_daysz?TestComprehensiveCalendar.test_leap_flag_2065_negative_all_daysi  r   r   c                 4   | j                         }g dt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd
      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fdt        ddd$      fdt        ddd%      fdt        ddd&      fdt        ddd'      fdt        ddd(      fdt        ddd)      fd	t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd
      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fdt        ddd$      fdt        ddd%      fdt        ddd&      fd	t        ddd'      fdt        ddd(      fdt        ddd*      fdt        ddd+      fdt        ddd,      fdt        ddd)      fdt        ddd      fdt        ddd      f}|D ]q  \  }}| j                  ||-      5  |j                  |      }| j	                  |d.|        |j                  |d/         }| j                  ||d0|        d1d1d1       s y1# 1 sw Y   ~xY w)2z=Test jian chu values for 2025 extended dataset (30+ records).   除r   r"   r[      满r^      平rW      定ra      执rc      破re      危rg      成rj      收rl      开rn      闭rp      建rs   ru   rx   rz   r]   r}   rY   ri   rr   rw   r   r            r!         r   r   jcr   jc_indexJian chu mismatch for NrM   r   r   r   r   get_jian_chu_namer   rK   r-   expected_jian_chuexpected_jc_namegregorian_dater   jc_names          rD   test_jian_chu_2025_extendedz5TestComprehensiveCalendar.test_jian_chu_2025_extended  s   '')
Dq!$%
*/dAq1A)B
GLdSWYZ\]N^F_
Dq!$%
*/dAq1A)B
GLdSWYZ\]N^F_
 Dq!$%
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&	
 +0dAr1B)C	
 HMdSWYZ\^N_F`	

 Dq"%&

 +0dAr1B)C

 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
  Dq"%&!
  +0dAr1B)C!
  HMdSWYZ\^N_F`!
" Dq"%&#
" +0dAr1B)C#
" HMdSWYZ\^N_F`#
$ Dq"%&%
$ +0dAr1B)C%
$ HMdSWYZ\^N_F`%
& Dq"%&'
& +0dAr1B)C'
& HMdSWYZ\^N_F`'
( Dq!$%)
( +0dAq1A)B)
( HMdSWYZ\]N^F_)
. 1B,n>6FG";;NK	$$Y2KNK[0\] !229Z3HI  *:!77GHJ HG 1BGGs   2APP	c                    | j                         }g dt        ddd      fdt        ddd      fdt        ddd      fdt        ddd	      fd
t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd
t        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fdt        ddd$      fdt        ddd%      fdt        ddd&      fdt        ddd'      fdt        ddd(      fdt        ddd)      fd
t        ddd*      fdt        ddd+      fdt        ddd,      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd	      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd
t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fd
t        ddd$      fdt        ddd%      fdt        ddd&      fdt        ddd'      f}|D ]q  \  }}| j                  ||-      5  |j                  |      }| j	                  |d.|        |j                  |d/         }| j                  ||d0|        d1d1d1       s y1# 1 sw Y   ~xY w)2z=Test jian chu values for 2020 extended dataset (30+ records).r   r   rW   r   ra   r   rc   r   re   r   rg   r   rj   r   rl   r   rn   r   rp   r   rs   r   ru   r   rx   rz   r]   r}   rY   ri   rr   rw   r   r   r   r   r   r   r   r   r!   r"   r[   r^   r   r   r   r   Nr   r   s          rD   test_jian_chu_2020_extendedz5TestComprehensiveCalendar.test_jian_chu_2020_extended  sS   '')
Dq!$%
*/dAq1A)B
GLdSWYZ\]N^F_
Dq!$%
*/dAq1A)B
GLdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&	
 +0dAr1B)C	
 HMdSWYZ\^N_F`	

 Dq"%&

 +0dAr1B)C

 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
  Dq"%&!
  +0dAr1B)C!
  HMdSWYZ\^N_F`!
" Dq"%&#
" +0dAr1B)C#
" HMdSWYZ\^N_F`#
$ Dq"%&%
$ +0dAr1B)C%
$ HMdSWYZ\^N_F`%
& Dq"%&'
& +0dAr1B)C'
& HMdSWYZ\^N_F`'
, 1B,n>6FG";;NK	$$Y2KNK[0\] !229Z3HI  *:!77GHJ HG 1BGGs   AO!!O*	c                    | j                         }g dt        ddd      fdt        ddd      fdt        ddd      fdt        ddd	      fd
t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd
t        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fdt        ddd$      fdt        ddd%      fdt        ddd&      fdt        ddd'      fdt        ddd(      fdt        ddd)      fd
t        ddd*      fdt        ddd+      fdt        ddd,      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd	      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd
t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fd
t        ddd$      f}|D ]q  \  }}| j                  ||-      5  |j                  |      }| j	                  |d.|        |j                  |d/         }| j                  ||d0|        d1d1d1       s y1# 1 sw Y   ~xY w)2z=Test jian chu values for 1965 extended dataset (30+ records).r   r   re   r   rg   r   rj   r   rl   r   rn   r   rp   r   rs   r   ru   r   rx   r   rz   r   r]   r   r}   rY   ri   rr   rw   r   r   r   r   r   r   r   r   r!   r"   r[   r^   rW   ra   rc   r   r   r   r   Nr   r   s          rD   test_jian_chu_1965_extendedz5TestComprehensiveCalendar.test_jian_chu_1965_extended  s   '')
Dq!$%
*/dAq1A)B
GLdSWYZ\^N_F`
Dq"%&
*/dAr1B)C
GLdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&	
 +0dAr1B)C	
 HMdSWYZ\^N_F`	

 Dq"%&

 +0dAr1B)C

 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq!$%
 +0dAq1A)B
 HMdSWYZ\]N^F_
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
 Dq"%&
 +0dAr1B)C
 HMdSWYZ\^N_F`
  Dq"%&!
  +0dAr1B)C!
  HMdSWYZ\^N_F`!
" Dq"%&#
" +0dAr1B)C#
" HMdSWYZ\^N_F`#
$ Dq"%&%
$ +0dAr1B)C%
$ HMdSWYZ\^N_F`%
* 1B,n>6FG";;NK	$$Y2KNK[0\] !229Z3HI  *:!77GHJ HG 1BGGs   AN44N=	c                    | j                         }g dt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd
      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd      fdt        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fdt        ddd$      fdt        ddd%      fdt        ddd&      fdt        ddd'      fdt        ddd(      fd	t        ddd)      fdt        ddd*      fdt        ddd+      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd
      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fd	t        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd      fdt        ddd       fdt        ddd!      fdt        ddd"      fdt        ddd#      fd	t        ddd$      fdt        ddd%      fdt        ddd,      f}|D ]q  \  }}| j                  ||-      5  |j                  |      }| j	                  |d.|        |j                  |d/         }| j                  ||d0|        d1d1d1       s y1# 1 sw Y   ~xY w)2z=Test jian chu values for 2085 extended dataset (30+ records).r   r   rl   rc   r   re   r   rg   r   rj   r   r   rn   r   rp   r   rs   r   ru   r   rx   r   rz   r   r]   r}   rY   ri   rr   rw   r   r   r   r   r   r   r   r!   r"   r[   r^   rW   ra   r   r   r   r   r   Nr   r   s          rD   test_jian_chu_2085_extendedz5TestComprehensiveCalendar.test_jian_chu_2085_extended  s   '')
Dr1%&
*/dB1B)C
GLdSWY[]^N_F`
Dr2&'
*/dB1C)D
GLdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'	
 +0dB1C)D	
 HMdSWY[]_N`Fa	

 Dr2&'

 +0dB1C)D

 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr1%&
 +0dB1B)C
 HMdSWY[]^N_F`
 Dr1%&
 +0dB1B)C
 HMdSWY[]^N_F`
 Dr1%&
 +0dB1B)C
 HMdSWY[]^N_F`
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
 Dr2&'
 +0dB1C)D
 HMdSWY[]_N`Fa
  Dr2&'!
  +0dB1C)D!
  HMdSWY[]_N`Fa!
" Dr2&'#
" +0dB1C)D#
" HMdSWY[]_N`Fa#
$ Dr2&'%
$ +0dB1C)D%
$ HMdSWY[]_N`Fa%
& Dr2&''
, 1B,n>6FG";;NK	$$Y2KNK[0\] !229Z3HI  *:!77GHJ HG 1BGGs   'AOO	c           
         t        ddd      t        ddd      t        ddd      g}g d}|D ]  }| j                  |      5  | j                  j                  |      }| j	                  |d	|        |d
   }| j                  |dd|        | j                  |dd|        | j                  j                  |      }| j                  ||d| d|        ddd        y# 1 sw Y   xY w)z2Test that jian chu indices are within valid range.r   r"   rs   r[   rW   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   z"Jian chu index should be >= 0 for rl   z#Jian chu index should be <= 11 for zJian chu name 'z' should be valid for N)	r   r   r-   r   r   assertGreaterEqualassertLessEqualr   r   )rK   
test_datesjian_chu_namesrC   r   r   r   s          rD   test_jian_chu_index_rangez3TestComprehensiveCalendar.test_jian_chu_index_range  s    q"q!q!

 n#I9- KK@@K	$$Y2KI;0WX$Z0''!7YZcYd5ef$$Xr5XYbXc3de ++77Ag~	Qghqgr7st .- $--s   BC##C,	c                    g t        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd	      dd
ft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd       ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd      dd
ft        ddd      ddft        ddd	      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd	      dd
ft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd       ddft        ddd      ddft        ddd      ddft        ddd      ddf}|D ]  \  }}}| j                  |!      5  | j                  j                  |      }| j	                  |d"|        |d#   }|d$   }| j                  ||d%| d&| d'|        | j                  ||d(| d&| d'|        d)d)d)        y)# 1 sw Y   xY w)*zUTest ALL lunar dates for 2025 from test_data.txt using direct lunar month/day fields.r   r!   rn   r"   r[   r^   rW   ra   rc   re   rg   rj   rl   rp   rs   ru   rx   rz   r]   r}   rY   ri   rr   rw   r   r   r   r   r   r   r   r   r   r   lunar_month	lunar_dayLunar month mismatch for : expected , got Lunar day mismatch for Nr   r   r-   r   r   r   )rK   expected_lunar_dates_2025r   expected_lunar_monthexpected_lunar_dayr   r   r  s           rD   #test_lunar_dates_2025_comprehensivez=TestComprehensiveCalendar.test_lunar_dates_2025_comprehensive4  s     %
$1r1% %
*.tQ*:B)B %
GKDRSUVGWY[]^F_ %
$1r1% %
*.tQ*:B)B %
GKDRSUVGWY[]^F_ %
 $1r1% %
 +/tQ*:B)B %
 HLDRSUVGWY[]_F` %
 $2B'	 %
 +/tQ*;R)D	 %
 HLDRSUWGXZ\^`Fa	 %

 $2B' %

 +/tQ*;R)D %

 HLDRSUWGXZ\^`Fa %
 $2B' %
 +/tQ*;R)D %
 HLDRSUWGXZ\^`Fa %
 $2B' %
 +/tQ*;R)D %
 HLDRSUWGXZ\^`Fa %
 $2B' %
 +/tQ*;R)D %
 HLDRSUWGXZ\^`Fa %
 $2B' %
 +/tQ*;R)D %
 HLDRSUWGXZ\^`Fa %
 $2B' %
 +/tQ*;Q)B %
 HLDRSUWGXZ[]^F_ %
 $21% %
 +/tQ*:Aq)A %
 HLDRSUVGWYZ\]F^ %
 $1q!$ %
 +/tQ*:Aq)A %
 HLDRSUVGWYZ\]F^ %
 $1q!$ %
 +/tQ*:Ar)B %
 HLDRSUVGWYZ\^F_ %
 $1q"% %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
  $22&! %
  +/tQ*;Q)C! %
  HLDRSUWGXZ[]_F`! %
" $22&# %
" +/tQ*;Q)C# %
" HLDRSUWGXZ[]_F`# %
$ $22&% %
$ +/tQ*;Q)C% %
$ HLDRSUWGXZ[]_F`% %
& $22&' %
& +/tQ*;Q)C' %
& HLDRSUWGXZ[]_F`' %
( $22&) %
( +/tQ*;Q)B) %
( HLDRSUVGWYZ\]F^) %
* $1q!$+ %
* +/tQ*:Aq)A+ %
* HLDRSUVGWYZ\]F^+ %
, $1q!$- %
, +/tQ*:Aq)A- %
, HLDRSUVGWYZ\]F^- %
. $1q!$/ %
. +/tQ*:Ar)B/ %
. HLDRSUWGXZ[]_F`/ %
0 $22&1 %
0 +/tQ*;Q)C1 %
0 HLDRSUWGXZ[]_F`1 %
2 $22&3 %
2 +/tQ*;Q)C3 %
2 HLDRSUWGXZ[]_F`3 %
4 $22&5 %
4 +/tQ*;Q)C5 %
4 HLDRSUWGXZ[]_F`5 %
6 $22&7 %
6 +/tQ*;Q)C7 %
6 HLDRSUWGXZ[]_F`7 %
8 $22&9 %
8 +/tQ*;Q)C9 %
8 HLDRSUWGXZ[]_F`9 %
: $22&; %
: +/tQ*;Q)C; %
: HLDRSUWGXZ[]_F`; %
< $21%= %
< +/tQ*;Q)B= %
< HLDRSUWGXZ[]^F_= %
> $1q!$? %
> +/tQ*:Aq)A? %
> HLDRSUVGWYZ\]F^? %
!D IbDN02D>2 KK@@P	$$Y2KNK[0\] (6%k2	  .B!:>:J+VjUkkqr}q~A  ,>!88HTfSggmnwmxy{ 32 Ib22s   .A3Y,,Y5	c                    g t        ddd      ddft        ddd      ddft        ddd      ddft        ddd	      dd
ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd       ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd
ft        ddd	      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd
ft        ddd      ddft        ddd	      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd      ddft        ddd      ddft        ddd       ddft        dd	d      ddft        dd	d      ddft        dd	d      ddft        dd	d      ddft        dd	d      dd
ft        dd	d      ddf}|D ]  \  }}}| j                  |!      5  | j                  j                  |      }| j	                  |d"|        |d#   }|d$   }| j                  ||d%| d&| d'|        | j                  ||d(| d&| d'|        d)d)d)        y)# 1 sw Y   xY w)*zUTest ALL lunar dates for 2020 from test_data.txt using direct lunar month/day fields.r   rW   r^   rp   ra   rs   rc   ru   re   rx   rg   rz   rj   r]   rl   r}   rn   rY   ri   rr   rw   r   r   r   r   r   r   r   r!   r"   r[   r   r   r   r   r  r  r  r  r  Nr  )rK   expected_lunar_dates_2020r   r  r	  r   r   r  s           rD   #test_lunar_dates_2020_comprehensivez=TestComprehensiveCalendar.test_lunar_dates_2020_comprehensiveg  s   !%
$1q"%!%
*.tQ*:Ar)B!%
GKDRSUVGWYZ\^F_!%
$1q"%!%
*.tQ*:Ar)B!%
GKDRSUWGXZ[]_F`!%
 $22&!%
 +/tQ*;Q)C!%
 HLDRSUWGXZ[]_F`!%
 $22&	!%
 +/tQ*;Q)C	!%
 HLDRSUWGXZ[]_F`	!%

 $22&!%

 +/tQ*;Q)C!%

 HLDRSUWGXZ[]_F`!%
 $22&!%
 +/tQ*;Q)C!%
 HLDRSUWGXZ[]_F`!%
 $21%!%
 +/tQ*;Q)B!%
 HLDRSUWGXZ[]^F_!%
 $21%!%
 +/tQ*;Q)B!%
 HLDRSUWGXZ[]^F_!%
 $21%!%
 +/tQ*;Q)B!%
 HLDRSUWGXZ[]^F_!%
 $1q"%!%
 +/tQ*:Ar)B!%
 HLDRSUVGWYZ\^F_!%
 $1q"%!%
 +/tQ*:Ar)B!%
 HLDRSUVGWYZ\^F_!%
 $1q"%!%
 +/tQ*:Ar)B!%
 HLDRSUVGWYZ\^F_!%
 $22&!%
 +/tQ*;Q)C!%
 HLDRSUWGXZ[]_F`!%
 $22&!%
 +/tQ*;Q)C!%
 HLDRSUWGXZ[]_F`!%
 $22&!%
 +/tQ*;Q)C!%
 HLDRSUWGXZ[]_F`!%
  $22&!!%
  +/tQ*;Q)C!!%
  HLDRSUWGXZ[]^F_!!%
" $21%#!%
" +/tQ*;Q)B#!%
" HLDRSUWGXZ[]^F_#!%
$ $21%%!%
$ +/tQ*;Q)B%!%
$ HLDRSUWGXZ[]^F_%!%
& $21%'!%
& +/tQ*;Q)B'!%
& HLDRSUWGXZ[]_F`'!%
( $1q"%)!%
( +/tQ*:Ar)B)!%
( HLDRSUVGWYZ\^F_)!%
* $1q"%+!%
* +/tQ*:Ar)B+!%
* HLDRSUVGWYZ\^F_+!%
, $1q"%-!%
, +/tQ*:Ar)B-!%
, HLDRSUVGWYZ\^F_-!%
. $22&/!%
. +/tQ*;Q)C/!%
. HLDRSUWGXZ[]_F`/!%
0 $22&1!%
0 +/tQ*;Q)C1!%
0 HLDRSUWGXZ[]_F`1!%
2 $22&3!%
2 +/tQ*;Q)C3!%
2 HLDRSUWGXZ[]_F`3!%
4 $22&5!%
4 +/tQ*;Q)C5!%
4 HLDRSUWGXZ[]^F_5!%
6 $21%7!%
6 +/tQ*;Q)B7!%
6 HLDRSUWGXZ[]^F_7!%
8 $21%9!%
8 +/tQ*;Q)B9!%
8 HLDRSUWGXZ[]^F_9!%
: $21%;!%
: +/tQ*;Q)B;!%
: HLDRSUWGXZ[]_F`;!%
< $22&=!%
< +/tQ*:Ar)B=!%
< HLDRSUVGWYZ\^F_=!%
> $1q"%?!%
> +/tQ*:Ar)B?!%
> HLDRSUVGWYZ\^F_?!%
@ $1q"%A!%
!F IbDN02D>2 KK@@P	$$Y2KNK[0\] (6%k2	  .B!:>:J+VjUkkqr}q~A  ,>!88HTfSggmnwmxy{ 32 Ib22s   >A3Y<<Z	c                    g t        ddd      ddft        ddd      ddft        ddd      ddft        ddd	      dd
ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd       dd	ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd
ft        ddd	      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd       ddft        ddd      ddft        ddd      ddft        ddd      dd
ft        ddd      ddft        ddd	      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      dd ft        ddd      ddft        ddd      ddft        dd	d      ddft        dd	d      ddft        dd	d      dd	ft        dd	d      ddft        dd	d      ddft        dd	d       ddf}|D ]  \  }}}| j                  |!      5  | j                  j                  |      }| j	                  |d"|        |d#   }|d$   }| j                  ||d%| d&| d'|        | j                  ||d(| d&| d'|        d)d)d)        y)# 1 sw Y   xY w)*zUTest ALL lunar dates for 1965 from test_data.txt using direct lunar month/day fields.r   re   rc   rn   rg   rp   rj   rs   rl   ru   rx   rz   r]   r}   rY   ri   rr   rw   r   r   r   r   r   r   r   r!   r"   r[   r^   r   rW   ra   r   r   r   r  r  r  r  r  Nr  )rK   expected_lunar_dates_1965r   r  r	  r   r   r  s           rD   #test_lunar_dates_1965_comprehensivez=TestComprehensiveCalendar.test_lunar_dates_1965_comprehensive  s
    %
$1q"% %
*.tQ*:Ar)B %
GKDRSUWGXZ[]_F` %
$22& %
*.tQ*;Q)C %
GKDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22&	 %
 +/tQ*;Q)C	 %
 HLDRSUWGXZ[]_F`	 %

 $22& %

 +/tQ*;Q)C %

 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)B %
 HLDRSUWGXZ[]^F_ %
 $21% %
 +/tQ*;Q)B %
 HLDRSUWGXZ[]^F_ %
 $1q!$ %
 +/tQ*:Aq)A %
 HLDRSUVGWYZ\]F^ %
 $1q!$ %
 +/tQ*:Ar)B %
 HLDRSUVGWYZ\^F_ %
 $1q"% %
 +/tQ*:Ar)B %
 HLDRSUVGWYZ\^F_ %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
 $22& %
 +/tQ*;Q)C %
 HLDRSUWGXZ[]_F` %
  $22&! %
  +/tQ*;Q)C! %
  HLDRSUWGXZ[]_F`! %
" $21%# %
" +/tQ*;Q)B# %
" HLDRSUWGXZ[]^F_# %
$ $21%% %
$ +/tQ*;Q)B% %
$ HLDRSUWGXZ[]^F_% %
& $A1%' %
& +/tR*;Q)B' %
& HLDRTVWGXZ[]^F_' %
( $A2&) %
( +/tR*;Q)C) %
( HLDRTVWGXZ[]_F`) %
* $A2&+ %
* +/tR*;Q)C+ %
* HLDRTVWGXZ[]_F`+ %
, $BB'- %
, +/tR*<a)D- %
, HLDRTVXGY[\^`Fa- %
. $BB'/ %
. +/tR*<a)D/ %
. HLDRTVXGY[\^`Fa/ %
0 $BB'1 %
0 +/tR*<a)D1 %
0 HLDRTVXGY[\^`Fa1 %
2 $BB'3 %
2 +/tR*<a)D3 %
2 HLDRTVXGY[\^`Fa3 %
4 $BB'5 %
4 +/tR*<a)D5 %
4 HLDRTVXGY[]_`Fa5 %
6 $BQ'7 %
6 +/tR*<b!)D7 %
6 HLDRTVXGY[]_`Fa7 %
8 $BQ'9 %
8 +/tR*<b!)D9 %
8 HLDRTVXGY[]_`Fa9 %
: $BQ'; %
: +/tR*;R)C; %
: HLDRTVWGXZ\^`Fa; %
< $AB'= %
< +/tR*;R)D= %
< HLDRTVWGXZ\^`Fa= %
> $AB'? %
!D IbDN02D>2 KK@@P	$$Y2KNK[0\] (6%k2	  .B!:>:J+VjUkkqr}q~A  ,>!88HTfSggmnwmxy{ 32 Ib22s   A3YY	c                 0   g t        ddd      ddft        ddd      ddft        ddd      ddft        ddd	      dd
ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd
      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	d	ft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	d
ft        ddd	      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      d	dft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd
      ddft        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd      ddft        ddd      ddft        ddd      ddft        ddd      ddft        ddd       ddf}|D ]  \  }}}| j                  |!      5  | j                  j                  |      }| j	                  |d"|        |d#   }|d$   }| j                  ||d%| d&| d'|        | j                  ||d(| d&| d'|        d)d)d)        y)# 1 sw Y   xY w)*zUTest ALL lunar dates for 2085 from test_data.txt using direct lunar month/day fields.r   rl   rc   rg   rY   re   ri   rr   rj   rw   r   rn   r   rp   r   rs   r   ru   r   rx   r   rz   r!   r]   r"   r}   r[   r^   rW   ra   r   r   r   r   r   r  r  r  r  r  Nr  )rK   expected_lunar_dates_2085r   r  r	  r   r   r  s           rD   #test_lunar_dates_2085_comprehensivez=TestComprehensiveCalendar.test_lunar_dates_2085_comprehensive  s   %
$A2&%
+/b!+<a*D%
IMdTVXYIZ\]_aHb%
$BB'%
+/b"+=q"*E%
IMdTVXZI[]^`bHc%
 $BB'%
 ,0b"+=q"*E%
 JNdTVXZI[]^`bHc%
 $BB'	%
 ,0b"+=r1*E	%
 JNdTVXZI[]_abHc	%

 $BQ'%

 ,0b"+=r1*E%

 JNdTVXZI[]_abHc%
 $BQ'%
 ,0b"+=r1*E%
 JNdTVXZI[]_abHc%
 $BQ'%
 ,0b"+=r2*F%
 JNdTVXZI[]_acHd%
 $BR(%
 ,0b"+=r2*F%
 JNdTVXZI[]_acHd%
 $AB'%
 ,0b!+<b"*E%
 JNdTVXYIZ\^`bHc%
 $AB'%
 ,0b!+<b"*E%
 JNdTVXYIZ\^`bHc%
 $AB'%
 ,0b!+<b"*E%
 JNdTVXYIZ\^`bHc%
 $BR(%
 ,0b"+=r2*F%
 JNdTVXZI[]_acHd%
 $BR(%
 ,0b"+=r2*F%
 JNdTVXZI[]_acHd%
 $BR(%
 ,0b"+=r1*E%
 JNdTVXZI[]_abHc%
 $BQ'%
 ,0b"+=r1*E%
 JNdTVXZI[]_abHc%
  $BQ'!%
  ,0b"+=r1*E!%
  JNdTVXZI[]_abHc!%
" $BQ'#%
" ,0b"+=r2*F#%
" JNdTVXZI[]_acHd#%
$ $BR(%%
$ ,0b"+=r2*F%%
$ JNdTVXZI[]_acHd%%
& $BR('%
!, IbDN02D>2 KK@@P	$$Y2KNK[0\] (6%k2	  .B!:>:J+VjUkkqr}q~A  ,>!88HTfSggmnwmxy{ 32 Ib22s   A3PP	c                 $   t        ddd      ddft        ddd      ddft        ddd      ddft        ddd	      d
dft        ddd      d
dft        ddd      ddft        ddd      ddfg}|D ]  \  }}}| j                  |d      5  | j                  j                  |      }| j	                  |d|        |d   }|d   }| j                  ||d| d| d|        | j                  ||d| d| d|        ddd        y# 1 sw Y   xY w)z2Test specific edge cases and critical lunar dates.r   r[   r   r"   r   r!   r   rW   rw   r^   ra   rY   r   re   r   r   rl   rz   rj   critical)r   caser   r   r  z"Critical lunar month mismatch for r  r  z Critical lunar day mismatch for Nr  )rK   critical_casesr   r  r	  r   r   r  s           rD   )test_lunar_dates_comprehensive_edge_caseszCTestComprehensiveCalendar.test_lunar_dates_comprehensive_edge_cases  s    $22&$21%$21%$21%$22&$21%$BQ'
 IWDN02D>
C KK@@P	$$Y2KNK[0\] (6%k2	  .B!CNCSS^_s^ttz  |G  {H   IJ  ,>!A.AQQ\]o\ppv  xA  wB   CD DC IWCCs   A3DD	c           
         t        ddd      ddft        ddd      ddft        ddd      dd	ft        ddd      dd
fg}|D ]  \  }}}| j                  |      5  | j                  j                  |      }| j	                  |d|        |d   }|d   }| j                  ||d| d|        | j                  ||d| d|        ddd        y# 1 sw Y   xY w)zXTest that lunar dates progress correctly day by day using direct lunar month/day fields.r   r"   r[   r!   ra   r^   rc   rW   re   rg   r   r   r   r  zLunar month should be z for zLunar day should be Nr  )rK   r   r   r  r	  r   r   r  s           rD   test_lunar_date_progressionz5TestComprehensiveCalendar.test_lunar_date_progression  s    $1q!$$1q!$$1q!$$1q!$	

 ISDN02D>2 KK@@P	$$Y2KNK[0\] (6%k2	  .B!78L7MUSaRbce  ,>!56H5I~N^_a 32 IS22s   A-CC	c           	         | j                   s| j                  d       d}t        | j                         }g }| j                   D ]  \  }}|j                  | j                  v s| j                  ||      5  | j                  j                  |      }|r>d|v r:ddlm	} |j                  |d         }||k(  r|dz  }n)|j                  |||f       n|j                  ||df       ddd        |dkD  r||z  d	z  }	t        d
| d| d|	dd       |rVt        d       |dd D ]  \  }}
}t        d| d|
 d|         t        |      dkD  rt        dt        |      dz
   d       | j                  |dd       |dkD  xs% t        |D cg c]  }|d   dk7  s| c}      dkD  }| j                  |d       |dk\  r| j                  |	dd|	dd       yy| j                  d       y# 1 sw Y   xY wc c}w )zATest YBP data accuracy against all test data from binary storage.No YBP test data availabler   r   expected	ybp_indexbzr!   zNo YBP dataNd   z
YBP Binary Storage Accuracy: /r   z.1fz%)zMismatches:rj   z  r  r  z
  ... and z more mismatchesz-Should have at least some correct YBP matchesr"   z+Should have YBP data stored in binary filesg      @z%YBP binary storage accuracy too low: %z%No YBP test cases found in test years)r.   skipTestr6   r;   r&   r   r-   r   iching.utilsr!  getYellowBlackPathGodr8   r   printassertGreater
assertTrue)rK   correct_counttotal_count
mismatchesrC   rB   r   r!  
actual_godaccuracyr  actualmhas_ybp_datas                 rD   test_ybp_data_storage_accuracyz8TestComprehensiveCalendar.test_ybp_data_storage_accuracy,  s1   !!MM67$,,-
'+'9'9#I|~~0\\y<\H $ D DY OI [I%=3%'%=%=i>T%U
%5)Q.M&--y,
.ST"))9lM*RS IH (:$ ?%3s:H=m_Ak]Z\]efi\jjlmnm$3=cr?/IxBykXJfVHMN 4Cz?R'Js:';&<<LMN }a1`a )1,i
4d
1aPQdVcNcQ
4d0ehi0iLOOL*WX b ""8S4YZbcfYggh2ij ! MMABM IH> 5es   5A0G,G9G9,G6	c                    g d}g }| j                   D ]1  \  }}|j                  | j                  v s|j                  ||f       3 |s| j	                  d       t               }t               }|D ]  \  }}| j                  j                  |      }|s$d|v s)|d   }|j                  |       ddl	m
}	 |	j                  |      }
|j                  |
       | j                  |dd|        | j                  |dd|        | j                  |
|d	|
         t        d
t!        |       dt#        |              t        d
t!        |       dt#        |              y)zSTest that all 12 YBP god names are correctly stored and retrieved from binary data.)   青龙   明堂   天刑   朱雀   金匮   天德   白虎   玉堂   天牢   玄武   司命   勾陈)No YBP test dates available in test yearsr  r   r   YBP index should be >= 0 for rl   YBP index should be <= 11 for zInvalid god name from binary: zFound z$ unique YBP indices in binary data: z! unique YBP gods in binary data: N)r.   r;   r&   r8   r%  r   r-   r   addr&  r!  r'  r   r   r   r   r6   r   )rK   expected_godsr   rC   rB   found_indices
found_godsr   r  r!  r.  s              rD   test_ybp_god_names_from_binaryz8TestComprehensiveCalendar.test_ybp_god_names_from_binary`  sm   
 
'+'9'9#I|~~0!!9l";< (: MMEF U
'1#I|<<YGI[I5%k2	!!),+55i@
z* ''	18UV_U`6ab$$Y6TU^T_4`a j-;YZdYe9fg (2" 	&]!3 44XY_`mYnXopq&Z 11RSYZdSeRfghrN   c                 f   g d}g d}g }| j                   D ]1  \  }}|j                  | j                  v s|j                  ||f       3 |s| j	                  d       d}d}|D ]  \  }}| j
                  j                  |      }|s$d|v s)ddlm}	 |	j                  |d         }
|	j                  |
      }|
|v r| j                  |d|
 d       |d	z  }t|
|v sy| j                  |d
|
 d       |d	z  } t        d| d| d       | j                  |dd       | j                  |dd       y)z@Test YBP good/bad classification using data from binary storage.)r5  r6  r9  r:  r<  r?  )r7  r8  r;  r=  r>  r@  rA  r   r  r   goodz should be classified as goodr!   badz should be classified as badzTested z good days and z bad days from binary dataz!Should have tested some good daysz Should have tested some bad daysN)r.   r;   r&   r8   r%  r-   r   r&  r!  r'  isYellowBlackPathGoodr   r   r)  )rK   	good_godsbad_godsr   rC   rB   
good_count	bad_countr   r!  r.  classifications               rD   ,test_ybp_good_bad_classification_from_binaryzFTestComprehensiveCalendar.test_ybp_good_bad_classification_from_binary  sR   P	O 
'+'9'9#I|~~0!!9l";< (: MMEF
	'1#I|<<YGI[I5+55i6LM
!#!9!9*!E*$$^V
|Kh=ij!OJ8+$$^UzlJf<ghNI (2 	'*_YKGabc:q*MN9a)KLrN   c                 &   | j                   s| j                  d       t        ddd      dft        ddd      d	ft        d
dd      dft        ddd      dft        ddd      dfg}d}|D ]   \  }}||f| j                   v s|j                  | j                  v s1| j                  ||      5  | j                  j                  |      }| j                  |d|        | j                  d|d|        ddl
m} |j                  |d         }|t        ddd      k(  r#||k7  rt        d| d| d|        	 ddd       | j                  ||d| d| d|        |dz  }ddd        |dk(  r| j                  d       yy# 1 sw Y   &xY w) z,Test specific YBP cases from binary storage.r  r   r!   rz   r@  r   r^   rw   r6  r   ra   r   r5  r   rW   r7  r   r?  r   r  r   r  zShould have YBP data for r   zKnown mismatch in binary data: z
 expected r  Nz YBP mismatch in binary data for r  z.No specific test cases available in test years)r.   r%  r   r;   r&   r   r-   r   r   r   r&  r!  r'  r(  r   )rK   specific_casestested_casesrC   rB   r   r!  r.  s           rD   (test_ybp_specific_test_cases_from_binaryzBTestComprehensiveCalendar.test_ybp_specific_test_cases_from_binary  s   !!MM67 $2)$2)$2)$1x($1x(
 '5#I|<(D,>,>>9>>UYUdUdCd\\y<\H $ D DY OI((6OPY{4[\MM+y<UV_U`:ab/!#!9!9)K:P!QJ !Dq!$44|9S ?	{*UaTbbhishtuv  IH $$Z%Ei[P[\h[iiopzo{#|~ A%L IH (6& 1MMJK # IHs   .BF!FF	c                    g }| j                   D ]/  \  }}|j                  | j                  v s|j                  |       1 |s| j	                  d       t               }|dd D ]  }| j                  |      5  | j                  j                  |      }|rd|v r|d   }| j                  |dd|        | j                  |dd	|        |j                  |       dd
lm} |j                  |      }| j                  |d|        | j!                  |t"        d|        ddd        t%        dt'        |              | j)                  t+        |      dd       y# 1 sw Y   xY w)z<Test that YBP indices in binary data are within valid range.rA  NrY   r   r  r   rB  rl   rC  r   zShould get god name for index z$God name should be string for index z(Found valid YBP indices in binary data: z(Should have found some valid YBP indices)r.   r;   r&   r8   r%  r   r   r-   r   r   r   rD  r&  r!  r'  r   assertIsInstancestrr   r   r)  r6   )	rK   r   rC   _valid_indicesr   r  r!  god_names	            rD   test_ybp_index_range_in_binaryz8TestComprehensiveCalendar.test_ybp_index_range_in_binary  sl    
 ..LIq~~0!!), / MMEF#CRI9- KK@@K		!9 )+ 6I++Iq<YZcYd:ef((B:XYbXc8de!%%i0 0!77	BH((5ST]S^3_`))(C;_`i_j9kl .- ) 	B6-CXBYZ[3}-q2\] .-s   8B*E  E*	c                    t        ddd      }| j                  j                  |      }| j                  |d|        g d}|D ]  }| j	                  ||d|         | j                  j                  |d         }| j                  |dd	|        |d
   }| j                  |t        d       ddl	}d}| j                  ||d       | j	                  |d   ddgd       y)zATest that all calendar components are consistent with each other.r   r"   rs   r   )r   
lunar_dater   r   r   r  zMissing required field: r   r   u   Expected jian chu '建' for r_  z2Lunar date should be a string in positional formatr   Nz^\d{4}-\d{2}-\d{2}$z)Lunar date should be in YYYY-MM-DD formatr   r!   zLeap flag should be 0 or 1)r   r-   r   r   r   r   r   rX  rY  reassertRegex)	rK   rC   r   required_fieldsfieldr   r_  r`  date_patterns	            rD   test_data_consistencyz/TestComprehensiveCalendar.test_data_consistency  s    q"%	KK88C	Y*CI;(OP c$EMM%.Fug,NO % ++//	*0EF%+G	{)ST |,
j#/cd 	-\3^_ 	i,q!f6RSrN   c           	          | j                   D ]a  }| j                  |      5  t        |dd      }| j                  j	                  |      }|r| j                  |d   dd| d       ddd       c y# 1 sw Y   nxY w)	zHTest that all generated files use the correct positional format version.r   ra   ru   versionr   zYear zC should use positional format version 4.0.0 with HH:MM:SS precisionN)r&   r   r   r-   r   r   )rK   r;   rC   r   s       rD   test_file_format_versionz2TestComprehensiveCalendar.test_file_format_version  sw    OOD4( q"-	 KK@@K	$$Yy%97%*4&0s#tv )( $((s   AA22A;	N)(__name__
__module____qualname____doc__classmethodrE   rM   rR   rT   r   r   r   r   r   r   intlistr   r   r   r   r   r   r   r   r   r   r
  r  r  r  r  r  r3  rH  rR  rV  r]  re  rh  r   rN   rD   r	   r	      s    U+k +kZ6$ J J>>
g>>>>>>P(Ls LD L4.&.&T.T6$JL#JJ"JH#JJu81{f2{h1{f%{ND6a82Ch&iP!MF#LJ^FT8
vrN   r	   __main__)rl  unittestr*   sysr#   rI   r   r   r+   insertr0   r1   !calendar10k.scripts.binary_readerr   #calendar10k.scripts.binary_calendarr   iching.utils.utilsr   TestCaser	   ri  mainr   rN   rD   <module>ry     s     	 
    277??277??277??83L#MN O L Q .Bv 1 1 BvH  zHMMO rN   