lib-x17-fintech 2.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
  2. lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
  3. lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
  4. lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
  5. lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
  6. xfintech/__init__.py +0 -0
  7. xfintech/connect/__init__.py +18 -0
  8. xfintech/connect/artifact/__init__.py +5 -0
  9. xfintech/connect/artifact/artifact.py +168 -0
  10. xfintech/connect/artifact/tests/__init__.py +3 -0
  11. xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
  12. xfintech/connect/common/__init__.py +12 -0
  13. xfintech/connect/common/connect.py +49 -0
  14. xfintech/connect/common/connectref.py +119 -0
  15. xfintech/connect/common/error.py +62 -0
  16. xfintech/connect/common/tests/__init__.py +1 -0
  17. xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
  18. xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
  19. xfintech/connect/common/tests/test_class_errors_all.py +524 -0
  20. xfintech/connect/instance/__init__.py +7 -0
  21. xfintech/connect/instance/macos.py +121 -0
  22. xfintech/connect/instance/s3.py +176 -0
  23. xfintech/connect/instance/tests/__init__.py +1 -0
  24. xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
  25. xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
  26. xfintech/data/__init__.py +20 -0
  27. xfintech/data/common/__init__.py +15 -0
  28. xfintech/data/common/cache.py +186 -0
  29. xfintech/data/common/coolant.py +171 -0
  30. xfintech/data/common/metric.py +138 -0
  31. xfintech/data/common/paginate.py +132 -0
  32. xfintech/data/common/params.py +162 -0
  33. xfintech/data/common/retry.py +201 -0
  34. xfintech/data/common/tests/__init__.py +1 -0
  35. xfintech/data/common/tests/test_class_cache_all.py +681 -0
  36. xfintech/data/common/tests/test_class_coolant_all.py +534 -0
  37. xfintech/data/common/tests/test_class_metric_all.py +705 -0
  38. xfintech/data/common/tests/test_class_paginate_all.py +508 -0
  39. xfintech/data/common/tests/test_class_params_all.py +891 -0
  40. xfintech/data/common/tests/test_class_retry_all.py +714 -0
  41. xfintech/data/job/__init__.py +17 -0
  42. xfintech/data/job/errors.py +112 -0
  43. xfintech/data/job/house.py +156 -0
  44. xfintech/data/job/job.py +247 -0
  45. xfintech/data/job/joblike.py +47 -0
  46. xfintech/data/job/tests/__init__.py +1 -0
  47. xfintech/data/job/tests/test_class_errors_all.py +275 -0
  48. xfintech/data/job/tests/test_class_house_all.py +801 -0
  49. xfintech/data/job/tests/test_class_job_all.py +684 -0
  50. xfintech/data/job/tests/test_class_joblike_all.py +482 -0
  51. xfintech/data/relay/__init__.py +7 -0
  52. xfintech/data/relay/client.py +114 -0
  53. xfintech/data/relay/clientlike.py +45 -0
  54. xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
  55. xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
  56. xfintech/data/source/__init__.py +7 -0
  57. xfintech/data/source/baostock/__init__.py +21 -0
  58. xfintech/data/source/baostock/job/__init__.py +5 -0
  59. xfintech/data/source/baostock/job/job.py +217 -0
  60. xfintech/data/source/baostock/job/tests/__init__.py +0 -0
  61. xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
  62. xfintech/data/source/baostock/session/__init__.py +8 -0
  63. xfintech/data/source/baostock/session/relay.py +223 -0
  64. xfintech/data/source/baostock/session/session.py +241 -0
  65. xfintech/data/source/baostock/session/tests/__init__.py +0 -0
  66. xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
  67. xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
  68. xfintech/data/source/baostock/stock/__init__.py +0 -0
  69. xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
  70. xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
  71. xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
  72. xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
  73. xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
  74. xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
  75. xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
  76. xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
  77. xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
  78. xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
  79. xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
  80. xfintech/data/source/baostock/stock/stock/constant.py +55 -0
  81. xfintech/data/source/baostock/stock/stock/stock.py +149 -0
  82. xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
  83. xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
  84. xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
  85. xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
  86. xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
  87. xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
  88. xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
  89. xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
  90. xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
  91. xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
  92. xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
  93. xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
  94. xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
  95. xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
  96. xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
  97. xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
  98. xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
  99. xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
  100. xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
  101. xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
  102. xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
  103. xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
  104. xfintech/data/source/tushare/__init__.py +61 -0
  105. xfintech/data/source/tushare/job/__init__.py +5 -0
  106. xfintech/data/source/tushare/job/job.py +257 -0
  107. xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
  108. xfintech/data/source/tushare/session/__init__.py +5 -0
  109. xfintech/data/source/tushare/session/relay.py +231 -0
  110. xfintech/data/source/tushare/session/session.py +239 -0
  111. xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
  112. xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
  113. xfintech/data/source/tushare/stock/__init__.py +55 -0
  114. xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
  115. xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
  116. xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
  117. xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
  118. xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
  119. xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
  120. xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
  121. xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
  122. xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
  123. xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
  124. xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
  125. xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
  126. xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
  127. xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
  128. xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
  129. xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
  130. xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
  131. xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
  132. xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
  133. xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
  134. xfintech/data/source/tushare/stock/company/__init__.py +19 -0
  135. xfintech/data/source/tushare/stock/company/company.py +188 -0
  136. xfintech/data/source/tushare/stock/company/constant.py +92 -0
  137. xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
  138. xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
  139. xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
  140. xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
  141. xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
  142. xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
  143. xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
  144. xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
  145. xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
  146. xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
  147. xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
  148. xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
  149. xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
  150. xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
  151. xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
  152. xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
  153. xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
  154. xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
  155. xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
  156. xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
  157. xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
  158. xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
  159. xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
  160. xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
  161. xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
  162. xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
  163. xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
  164. xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
  165. xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
  166. xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
  167. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
  168. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
  169. xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
  170. xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
  171. xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
  172. xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
  173. xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
  174. xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
  175. xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
  176. xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
  177. xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
  178. xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
  179. xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
  180. xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
  181. xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
  182. xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
  183. xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
  184. xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
  185. xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
  186. xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
  187. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
  188. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
  189. xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
  190. xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
  191. xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
  192. xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
  193. xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
  194. xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
  195. xfintech/data/source/tushare/stock/stock/constant.py +105 -0
  196. xfintech/data/source/tushare/stock/stock/stock.py +193 -0
  197. xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
  198. xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
  199. xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
  200. xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
  201. xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
  202. xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
  203. xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
  204. xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
  205. xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
  206. xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
  207. xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
  208. xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
  209. xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
  210. xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
  211. xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
  212. xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
  213. xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
  214. xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
  215. xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
  216. xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
  217. xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
  218. xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
  219. xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
  220. xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
  221. xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
  222. xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
  223. xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
  224. xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
  225. xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
  226. xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
  227. xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
  228. xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
  229. xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
  230. xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
  231. xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
  232. xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
  233. xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
  234. xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
  235. xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
  236. xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
  237. xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
  238. xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
  239. xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
  240. xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
  241. xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
  242. xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
  243. xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
  244. xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
  245. xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
  246. xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
  247. xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
  248. xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
  249. xfintech/fabric/__init__.py +18 -0
  250. xfintech/fabric/column/__init__.py +7 -0
  251. xfintech/fabric/column/info.py +202 -0
  252. xfintech/fabric/column/kind.py +102 -0
  253. xfintech/fabric/column/tests/__init__.py +0 -0
  254. xfintech/fabric/column/tests/test_class_info_all.py +207 -0
  255. xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
  256. xfintech/fabric/table/__init__.py +5 -0
  257. xfintech/fabric/table/info.py +263 -0
  258. xfintech/fabric/table/tests/__init__.py +0 -0
  259. xfintech/fabric/table/tests/test_class_info_all.py +547 -0
  260. xfintech/serde/__init__.py +35 -0
  261. xfintech/serde/common/__init__.py +9 -0
  262. xfintech/serde/common/dataformat.py +78 -0
  263. xfintech/serde/common/deserialiserlike.py +38 -0
  264. xfintech/serde/common/error.py +182 -0
  265. xfintech/serde/common/serialiserlike.py +38 -0
  266. xfintech/serde/common/tests/__init__.py +1 -0
  267. xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
  268. xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
  269. xfintech/serde/common/tests/test_class_errors_all.py +518 -0
  270. xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
  271. xfintech/serde/deserialiser/__init__.py +7 -0
  272. xfintech/serde/deserialiser/pandas.py +113 -0
  273. xfintech/serde/deserialiser/python.py +68 -0
  274. xfintech/serde/deserialiser/tests/__init__.py +1 -0
  275. xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
  276. xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
  277. xfintech/serde/serialiser/__init__.py +7 -0
  278. xfintech/serde/serialiser/pandas.py +116 -0
  279. xfintech/serde/serialiser/python.py +71 -0
  280. xfintech/serde/serialiser/tests/__init__.py +1 -0
  281. xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
  282. xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
@@ -0,0 +1,534 @@
1
+ import time
2
+ from unittest.mock import patch
3
+
4
+ from xfintech.data.common.coolant import Coolant
5
+
6
+ # ==================== Coolant Initialization Tests ====================
7
+
8
+
9
+ def test_coolant_init_defaults():
10
+ """Test Coolant initialization with default values"""
11
+ coolant = Coolant()
12
+
13
+ assert coolant.interval == 0
14
+ assert coolant.use_jitter is False
15
+ assert coolant.jitter_min == 0.0
16
+ assert coolant.jitter_max == 0.0
17
+
18
+
19
+ def test_coolant_init_with_interval():
20
+ """Test Coolant initialization with custom interval"""
21
+ coolant = Coolant(interval=5)
22
+
23
+ assert coolant.interval == 5
24
+ assert coolant.use_jitter is False
25
+ assert coolant.jitter_min == 0.0
26
+ assert coolant.jitter_max == 0.0
27
+
28
+
29
+ def test_coolant_init_with_jitter():
30
+ """Test Coolant initialization with jitter enabled"""
31
+ coolant = Coolant(use_jitter=True)
32
+
33
+ assert coolant.interval == 0
34
+ assert coolant.use_jitter is True
35
+ assert coolant.jitter_min == 0.1
36
+ assert coolant.jitter_max == 3.0
37
+
38
+
39
+ def test_coolant_init_custom_jitter_range():
40
+ """Test Coolant initialization with custom jitter range"""
41
+ coolant = Coolant(use_jitter=True, jitter_min=0.5, jitter_max=2.5)
42
+
43
+ assert coolant.use_jitter is True
44
+ assert coolant.jitter_min == 0.5
45
+ assert coolant.jitter_max == 2.5
46
+
47
+
48
+ def test_coolant_init_complete():
49
+ """Test Coolant initialization with all parameters"""
50
+ coolant = Coolant(interval=3, use_jitter=True, jitter_min=0.2, jitter_max=1.5)
51
+
52
+ assert coolant.interval == 3
53
+ assert coolant.use_jitter is True
54
+ assert coolant.jitter_min == 0.2
55
+ assert coolant.jitter_max == 1.5
56
+
57
+
58
+ def test_coolant_init_jitter_without_flag():
59
+ """Test jitter params ignored when use_jitter is False"""
60
+ coolant = Coolant(use_jitter=False, jitter_min=1.0, jitter_max=2.0)
61
+
62
+ assert coolant.use_jitter is False
63
+ assert coolant.jitter_min == 0.0
64
+ assert coolant.jitter_max == 0.0
65
+
66
+
67
+ def test_coolant_init_interval_zero():
68
+ """Test Coolant initialization with zero interval"""
69
+ coolant = Coolant(interval=0)
70
+
71
+ assert coolant.interval == 0
72
+
73
+
74
+ def test_coolant_init_interval_negative():
75
+ """Test Coolant initialization with negative interval"""
76
+ coolant = Coolant(interval=-5)
77
+
78
+ assert coolant.interval == -5
79
+
80
+
81
+ # ==================== Class Constants Tests ====================
82
+
83
+
84
+ def test_coolant_default_constants():
85
+ """Test class default constants are set correctly"""
86
+ assert Coolant.DEFAULT_INTERVAL == 0
87
+ assert Coolant.DEFAULT_JITTER_MIN == 0.1
88
+ assert Coolant.DEFAULT_JITTER_MAX == 3.0
89
+
90
+
91
+ # ==================== Resolve Methods Tests ====================
92
+
93
+
94
+ def test_coolant_resolve_interval_with_value():
95
+ """Test _resolve_interval with explicit value"""
96
+ coolant = Coolant()
97
+ result = coolant._resolve_interval(10)
98
+
99
+ assert result == 10
100
+
101
+
102
+ def test_coolant_resolve_interval_none():
103
+ """Test _resolve_interval with None returns default"""
104
+ coolant = Coolant()
105
+ result = coolant._resolve_interval(None)
106
+
107
+ assert result == Coolant.DEFAULT_INTERVAL
108
+
109
+
110
+ def test_coolant_resolve_jitter_min_with_jitter_enabled():
111
+ """Test _resolve_jitter_min with jitter enabled"""
112
+ coolant = Coolant(use_jitter=True)
113
+ result = coolant._resolve_jitter_min(0.5)
114
+
115
+ assert result == 0.5
116
+
117
+
118
+ def test_coolant_resolve_jitter_min_with_jitter_disabled():
119
+ """Test _resolve_jitter_min with jitter disabled"""
120
+ coolant = Coolant(use_jitter=False)
121
+ result = coolant._resolve_jitter_min(0.5)
122
+
123
+ assert result == 0.0
124
+
125
+
126
+ def test_coolant_resolve_jitter_min_none_with_jitter():
127
+ """Test _resolve_jitter_min returns default when None and jitter enabled"""
128
+ coolant = Coolant(use_jitter=True)
129
+ result = coolant._resolve_jitter_min(None)
130
+
131
+ assert result == Coolant.DEFAULT_JITTER_MIN
132
+
133
+
134
+ def test_coolant_resolve_jitter_max_with_jitter_enabled():
135
+ """Test _resolve_jitter_max with jitter enabled"""
136
+ coolant = Coolant(use_jitter=True)
137
+ result = coolant._resolve_jitter_max(2.5)
138
+
139
+ assert result == 2.5
140
+
141
+
142
+ def test_coolant_resolve_jitter_max_with_jitter_disabled():
143
+ """Test _resolve_jitter_max with jitter disabled"""
144
+ coolant = Coolant(use_jitter=False)
145
+ result = coolant._resolve_jitter_max(2.5)
146
+
147
+ assert result == 0.0
148
+
149
+
150
+ def test_coolant_resolve_jitter_max_none_with_jitter():
151
+ """Test _resolve_jitter_max returns default when None and jitter enabled"""
152
+ coolant = Coolant(use_jitter=True)
153
+ result = coolant._resolve_jitter_max(None)
154
+
155
+ assert result == Coolant.DEFAULT_JITTER_MAX
156
+
157
+
158
+ def test_coolant_resolve_jitter_min_int_conversion():
159
+ """Test _resolve_jitter_min converts int to float"""
160
+ coolant = Coolant(use_jitter=True)
161
+ result = coolant._resolve_jitter_min(1)
162
+
163
+ assert result == 1.0
164
+ assert isinstance(result, float)
165
+
166
+
167
+ def test_coolant_resolve_jitter_max_int_conversion():
168
+ """Test _resolve_jitter_max converts int to float"""
169
+ coolant = Coolant(use_jitter=True)
170
+ result = coolant._resolve_jitter_max(3)
171
+
172
+ assert result == 3.0
173
+ assert isinstance(result, float)
174
+
175
+
176
+ # ==================== Jitter Method Tests ====================
177
+
178
+
179
+ @patch("time.sleep")
180
+ @patch("random.uniform")
181
+ def test_coolant_jitter_enabled(mock_uniform, mock_sleep):
182
+ """Test jitter() with jitter enabled"""
183
+ mock_uniform.return_value = 1.5
184
+ coolant = Coolant(use_jitter=True, jitter_min=0.5, jitter_max=2.0)
185
+
186
+ coolant.jitter()
187
+
188
+ mock_uniform.assert_called_once_with(0.5, 2.0)
189
+ mock_sleep.assert_called_once_with(1.5)
190
+
191
+
192
+ @patch("time.sleep")
193
+ @patch("random.uniform")
194
+ def test_coolant_jitter_disabled(mock_uniform, mock_sleep):
195
+ """Test jitter() with jitter disabled does nothing"""
196
+ coolant = Coolant(use_jitter=False)
197
+
198
+ coolant.jitter()
199
+
200
+ mock_uniform.assert_not_called()
201
+ mock_sleep.assert_not_called()
202
+
203
+
204
+ @patch("time.sleep")
205
+ @patch("random.uniform")
206
+ def test_coolant_jitter_rounding(mock_uniform, mock_sleep):
207
+ """Test jitter() rounds to 1 decimal place"""
208
+ mock_uniform.return_value = 1.567
209
+ coolant = Coolant(use_jitter=True)
210
+
211
+ coolant.jitter()
212
+
213
+ mock_sleep.assert_called_once_with(1.6)
214
+
215
+
216
+ @patch("time.sleep")
217
+ @patch("random.uniform")
218
+ def test_coolant_jitter_uses_configured_range(mock_uniform, mock_sleep):
219
+ """Test jitter() uses configured min/max range"""
220
+ mock_uniform.return_value = 0.75
221
+ coolant = Coolant(use_jitter=True, jitter_min=0.3, jitter_max=0.8)
222
+
223
+ coolant.jitter()
224
+
225
+ mock_uniform.assert_called_once_with(0.3, 0.8)
226
+
227
+
228
+ @patch("time.sleep")
229
+ @patch("random.uniform")
230
+ def test_coolant_jitter_default_range(mock_uniform, mock_sleep):
231
+ """Test jitter() uses default range when not specified"""
232
+ mock_uniform.return_value = 1.0
233
+ coolant = Coolant(use_jitter=True)
234
+
235
+ coolant.jitter()
236
+
237
+ mock_uniform.assert_called_once_with(0.1, 3.0)
238
+
239
+
240
+ # ==================== Cool Method Tests ====================
241
+
242
+
243
+ @patch("time.sleep")
244
+ def test_coolant_cool_zero_interval_no_jitter(mock_sleep):
245
+ """Test cool() with zero interval and no jitter returns immediately"""
246
+ coolant = Coolant(interval=0, use_jitter=False)
247
+
248
+ coolant.cool()
249
+
250
+ mock_sleep.assert_not_called()
251
+
252
+
253
+ @patch("time.sleep")
254
+ @patch("random.uniform")
255
+ def test_coolant_cool_zero_interval_with_jitter(mock_uniform, mock_sleep):
256
+ """Test cool() with zero interval but jitter enabled applies jitter"""
257
+ mock_uniform.return_value = 1.5
258
+ coolant = Coolant(interval=0, use_jitter=True)
259
+
260
+ coolant.cool()
261
+
262
+ # Should only call sleep once for jitter
263
+ assert mock_sleep.call_count == 1
264
+ mock_sleep.assert_called_with(1.5)
265
+
266
+
267
+ @patch("time.sleep")
268
+ def test_coolant_cool_with_interval_no_jitter(mock_sleep):
269
+ """Test cool() with interval but no jitter"""
270
+ coolant = Coolant(interval=3, use_jitter=False)
271
+
272
+ coolant.cool()
273
+
274
+ mock_sleep.assert_called_once_with(3)
275
+
276
+
277
+ @patch("time.sleep")
278
+ @patch("random.uniform")
279
+ def test_coolant_cool_with_interval_and_jitter(mock_uniform, mock_sleep):
280
+ """Test cool() with both interval and jitter"""
281
+ mock_uniform.return_value = 0.5
282
+ coolant = Coolant(interval=2, use_jitter=True, jitter_min=0.1, jitter_max=1.0)
283
+
284
+ coolant.cool()
285
+
286
+ # Should call sleep twice: once for interval, once for jitter
287
+ assert mock_sleep.call_count == 2
288
+ calls = mock_sleep.call_args_list
289
+ assert calls[0][0][0] == 2 # interval
290
+ assert calls[1][0][0] == 0.5 # jitter
291
+
292
+
293
+ @patch("time.sleep")
294
+ def test_coolant_cool_negative_interval(mock_sleep):
295
+ """Test cool() with negative interval applies jitter if enabled"""
296
+ coolant = Coolant(interval=-1, use_jitter=False)
297
+
298
+ coolant.cool()
299
+
300
+ # Negative interval treated as <= 0, so should return early
301
+ mock_sleep.assert_not_called()
302
+
303
+
304
+ @patch("time.sleep")
305
+ def test_coolant_cool_interval_rounding(mock_sleep):
306
+ """Test cool() rounds interval to 1 decimal place"""
307
+ coolant = Coolant(interval=5, use_jitter=False)
308
+
309
+ coolant.cool()
310
+
311
+ mock_sleep.assert_called_once_with(5)
312
+
313
+
314
+ @patch("time.sleep")
315
+ @patch("random.uniform")
316
+ def test_coolant_cool_order_of_operations(mock_uniform, mock_sleep):
317
+ """Test cool() applies interval before jitter"""
318
+ mock_uniform.return_value = 0.3
319
+ coolant = Coolant(interval=1, use_jitter=True)
320
+
321
+ coolant.cool()
322
+
323
+ # Verify order: interval sleep, then jitter sleep
324
+ calls = mock_sleep.call_args_list
325
+ assert len(calls) == 2
326
+ assert calls[0][0][0] == 1 # First call is interval
327
+ assert calls[1][0][0] == 0.3 # Second call is jitter
328
+
329
+
330
+ # ==================== Integration Tests ====================
331
+
332
+
333
+ def test_coolant_cool_actual_timing_no_jitter():
334
+ """Test cool() actually waits for the specified interval"""
335
+ coolant = Coolant(interval=0.1, use_jitter=False)
336
+
337
+ start = time.time()
338
+ coolant.cool()
339
+ elapsed = time.time() - start
340
+
341
+ assert 0.09 <= elapsed <= 0.2 # Allow some tolerance
342
+
343
+
344
+ def test_coolant_cool_actual_timing_with_jitter():
345
+ """Test cool() waits for interval plus jitter"""
346
+ coolant = Coolant(interval=0.1, use_jitter=True, jitter_min=0.1, jitter_max=0.2)
347
+
348
+ start = time.time()
349
+ coolant.cool()
350
+ elapsed = time.time() - start
351
+
352
+ # Should be at least interval + jitter_min
353
+ assert elapsed >= 0.19 # 0.1 interval + 0.1 jitter min (with tolerance)
354
+ # Should be at most interval + jitter_max (with some tolerance)
355
+ assert elapsed <= 0.4
356
+
357
+
358
+ def test_coolant_cool_zero_interval_actual():
359
+ """Test cool() with zero interval completes quickly"""
360
+ coolant = Coolant(interval=0, use_jitter=False)
361
+
362
+ start = time.time()
363
+ coolant.cool()
364
+ elapsed = time.time() - start
365
+
366
+ assert elapsed < 0.01 # Should be nearly instant
367
+
368
+
369
+ def test_coolant_multiple_cool_calls():
370
+ """Test multiple sequential cool() calls"""
371
+ coolant = Coolant(interval=0.05, use_jitter=False)
372
+
373
+ start = time.time()
374
+ coolant.cool()
375
+ coolant.cool()
376
+ coolant.cool()
377
+ elapsed = time.time() - start
378
+
379
+ # 0.05 rounds to 0.1, so 3 * 0.1 = 0.3 seconds
380
+ assert 0.28 <= elapsed <= 0.35
381
+
382
+
383
+ def test_coolant_reuse():
384
+ """Test Coolant instance can be reused"""
385
+ coolant = Coolant(interval=0.05, use_jitter=False)
386
+
387
+ # First use
388
+ start = time.time()
389
+ coolant.cool()
390
+ elapsed1 = time.time() - start
391
+
392
+ # Second use
393
+ start = time.time()
394
+ coolant.cool()
395
+ elapsed2 = time.time() - start
396
+
397
+ # 0.05 rounds to 0.1 when sleeping
398
+ assert 0.09 <= elapsed1 <= 0.15
399
+ assert 0.09 <= elapsed2 <= 0.15
400
+
401
+
402
+ def test_coolant_different_instances():
403
+ """Test different Coolant instances are independent"""
404
+ coolant1 = Coolant(interval=0.1, use_jitter=False)
405
+ coolant2 = Coolant(interval=0.2, use_jitter=False)
406
+
407
+ start = time.time()
408
+ coolant1.cool()
409
+ elapsed1 = time.time() - start
410
+
411
+ start = time.time()
412
+ coolant2.cool()
413
+ elapsed2 = time.time() - start
414
+
415
+ assert 0.09 <= elapsed1 <= 0.15
416
+ assert 0.19 <= elapsed2 <= 0.25
417
+ assert elapsed2 > elapsed1
418
+
419
+
420
+ # ==================== Edge Cases and Special Scenarios ====================
421
+
422
+
423
+ def test_coolant_jitter_min_equals_max():
424
+ """Test jitter with min equal to max"""
425
+ coolant = Coolant(use_jitter=True, jitter_min=1.0, jitter_max=1.0)
426
+
427
+ assert coolant.jitter_min == 1.0
428
+ assert coolant.jitter_max == 1.0
429
+
430
+
431
+ @patch("time.sleep")
432
+ @patch("random.uniform")
433
+ def test_coolant_jitter_min_equals_max_sleep(mock_uniform, mock_sleep):
434
+ """Test jitter sleep when min equals max"""
435
+ mock_uniform.return_value = 1.0
436
+ coolant = Coolant(use_jitter=True, jitter_min=1.0, jitter_max=1.0)
437
+
438
+ coolant.jitter()
439
+
440
+ mock_uniform.assert_called_once_with(1.0, 1.0)
441
+ mock_sleep.assert_called_once_with(1.0)
442
+
443
+
444
+ def test_coolant_very_small_interval():
445
+ """Test coolant with very small interval"""
446
+ coolant = Coolant(interval=0.01, use_jitter=False)
447
+
448
+ start = time.time()
449
+ coolant.cool()
450
+ elapsed = time.time() - start
451
+
452
+ assert elapsed < 0.05
453
+
454
+
455
+ def test_coolant_jitter_only():
456
+ """Test coolant with only jitter, no base interval"""
457
+ coolant = Coolant(interval=0, use_jitter=True, jitter_min=0.05, jitter_max=0.1)
458
+
459
+ start = time.time()
460
+ coolant.cool()
461
+ elapsed = time.time() - start
462
+
463
+ # Should only apply jitter
464
+ assert 0.04 <= elapsed <= 0.15
465
+
466
+
467
+ @patch("time.sleep")
468
+ def test_coolant_cool_preserves_state(mock_sleep):
469
+ """Test cool() doesn't modify instance state"""
470
+ coolant = Coolant(interval=2, use_jitter=True, jitter_min=0.5, jitter_max=1.5)
471
+
472
+ original_interval = coolant.interval
473
+ original_jitter = coolant.use_jitter
474
+ original_min = coolant.jitter_min
475
+ original_max = coolant.jitter_max
476
+
477
+ coolant.cool()
478
+
479
+ assert coolant.interval == original_interval
480
+ assert coolant.use_jitter == original_jitter
481
+ assert coolant.jitter_min == original_min
482
+ assert coolant.jitter_max == original_max
483
+
484
+
485
+ def test_coolant_rate_limiting_scenario():
486
+ """Test coolant for rate limiting scenario"""
487
+ coolant = Coolant(interval=0.05, use_jitter=False)
488
+
489
+ operations = []
490
+ start_time = time.time()
491
+
492
+ for i in range(3):
493
+ operations.append(time.time() - start_time)
494
+ if i < 2: # Don't cool after last operation
495
+ coolant.cool()
496
+
497
+ # Check spacing between operations
498
+ assert operations[1] - operations[0] >= 0.04
499
+ assert operations[2] - operations[1] >= 0.04
500
+
501
+
502
+ def test_coolant_api_throttling_scenario():
503
+ """Test coolant for API throttling with jitter"""
504
+ coolant = Coolant(interval=0.05, use_jitter=True, jitter_min=0.01, jitter_max=0.05)
505
+
506
+ call_times = []
507
+ start = time.time()
508
+
509
+ for i in range(3):
510
+ call_times.append(time.time() - start)
511
+ if i < 2:
512
+ coolant.cool()
513
+
514
+ # Each gap should be at least interval + jitter_min
515
+ for i in range(1, len(call_times)):
516
+ gap = call_times[i] - call_times[i - 1]
517
+ assert gap >= 0.05 # At least the interval
518
+
519
+
520
+ @patch("time.sleep")
521
+ @patch("random.uniform")
522
+ def test_coolant_configuration_independence(mock_uniform, mock_sleep):
523
+ """Test coolant configuration doesn't affect other instances"""
524
+ mock_uniform.return_value = 0.5
525
+
526
+ coolant1 = Coolant(interval=1, use_jitter=True, jitter_min=0.1, jitter_max=0.5)
527
+ coolant2 = Coolant(interval=2, use_jitter=False)
528
+
529
+ coolant1.cool()
530
+ coolant2.cool()
531
+
532
+ # coolant1 should have interval + jitter
533
+ # coolant2 should only have interval
534
+ assert mock_sleep.call_count == 3 # 1 interval + 1 jitter + 1 interval