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,693 @@
1
+ from unittest.mock import MagicMock, patch
2
+
3
+ import pandas as pd
4
+ import pytest
5
+
6
+ from xfintech.data.common.cache import Cache
7
+ from xfintech.data.common.coolant import Coolant
8
+ from xfintech.data.common.paginate import Paginate
9
+ from xfintech.data.common.params import Params
10
+ from xfintech.data.common.retry import Retry
11
+ from xfintech.data.source.tushare.session.session import Session
12
+ from xfintech.data.source.tushare.stock.stockst.constant import (
13
+ KEY,
14
+ NAME,
15
+ PAGINATE,
16
+ SOURCE,
17
+ TARGET,
18
+ )
19
+ from xfintech.data.source.tushare.stock.stockst.stockst import StockSt
20
+
21
+ # ============================================================================
22
+ # Fixtures
23
+ # ============================================================================
24
+
25
+
26
+ @pytest.fixture
27
+ def mock_session():
28
+ """Create a mock Tushare session"""
29
+ session = MagicMock(spec=Session)
30
+ session._credential = "test_token"
31
+ session.id = "test1234"
32
+ session.mode = "direct"
33
+ session.relay_url = None
34
+ session.relay_secret = None
35
+ session.connected = True
36
+
37
+ # Mock the connection object
38
+ mock_connection = MagicMock()
39
+ mock_connection.stock_st = MagicMock()
40
+ session.connection = mock_connection
41
+
42
+ return session
43
+
44
+
45
+ @pytest.fixture
46
+ def sample_source_data():
47
+ """Create sample source data in Tushare format"""
48
+ return pd.DataFrame(
49
+ {
50
+ "ts_code": ["000001.SZ", "000002.SZ", "600000.SH"],
51
+ "name": ["*ST平安", "*ST万科", "ST浦发"],
52
+ "trade_date": ["20230101", "20230101", "20230102"],
53
+ "type": ["S", "S", "S"],
54
+ "type_name": ["*ST", "*ST", "ST"],
55
+ }
56
+ )
57
+
58
+
59
+ @pytest.fixture
60
+ def expected_transformed_data():
61
+ """Create expected transformed data"""
62
+ return pd.DataFrame(
63
+ {
64
+ "code": ["000001.SZ", "000002.SZ", "600000.SH"],
65
+ "name": ["*ST平安", "*ST万科", "ST浦发"],
66
+ "date": ["2023-01-01", "2023-01-01", "2023-01-02"],
67
+ "datecode": ["20230101", "20230101", "20230102"],
68
+ "type": ["S", "S", "S"],
69
+ "type_name": ["*ST", "*ST", "ST"],
70
+ }
71
+ )
72
+
73
+
74
+ # ============================================================================
75
+ # Initialization Tests
76
+ # ============================================================================
77
+
78
+
79
+ def test_st_init_basic(mock_session):
80
+ """Test StockSt initialization with minimal parameters"""
81
+ st = StockSt(session=mock_session)
82
+
83
+ assert st.name == NAME
84
+ assert st.key == KEY
85
+ assert st.source == SOURCE
86
+ assert st.target == TARGET
87
+ assert isinstance(st.params, Params)
88
+ assert isinstance(st.coolant, Coolant)
89
+ assert isinstance(st.paginate, Paginate)
90
+ assert isinstance(st.retry, Retry)
91
+ assert st.paginate.pagesize == PAGINATE.pagesize
92
+ assert st.paginate.pagelimit == PAGINATE.pagelimit
93
+
94
+
95
+ def test_st_init_with_params_dict(mock_session):
96
+ """Test StockSt initialization with params as dict"""
97
+ params = {"start_date": "20230101", "end_date": "20231231"}
98
+ st = StockSt(session=mock_session, params=params)
99
+ assert st.params.get("start_date") == "20230101"
100
+ assert st.params.get("end_date") == "20231231"
101
+
102
+
103
+ def test_st_init_with_params_object(mock_session):
104
+ """Test StockSt initialization with Params object"""
105
+ params = Params(year="2023")
106
+ st = StockSt(session=mock_session, params=params)
107
+ assert st.params.get("year") == "2023"
108
+
109
+
110
+ def test_st_init_with_year_param(mock_session):
111
+ """Test StockSt initialization with year parameter"""
112
+ st = StockSt(session=mock_session, params={"year": "2023"})
113
+ assert st.params.get("year") == "2023"
114
+
115
+
116
+ def test_st_init_with_trade_date_param(mock_session):
117
+ """Test StockSt initialization with trade_date parameter"""
118
+ st = StockSt(session=mock_session, params={"trade_date": "20230315"})
119
+
120
+ assert st.params.trade_date == "20230315"
121
+
122
+
123
+ def test_st_init_with_ts_code_param(mock_session):
124
+ """Test StockSt initialization with ts_code parameter"""
125
+ st = StockSt(session=mock_session, params={"ts_code": "600000.SH"})
126
+
127
+ assert st.params.ts_code == "600000.SH"
128
+
129
+
130
+ def test_st_init_with_cache_bool_true(mock_session):
131
+ """Test StockSt initialization with cache=True"""
132
+ st = StockSt(session=mock_session, cache=True)
133
+
134
+ assert st.cache is not None
135
+ assert isinstance(st.cache, Cache)
136
+
137
+
138
+ def test_st_init_with_cache_bool_false(mock_session):
139
+ """Test StockSt initialization with cache=False"""
140
+ st = StockSt(session=mock_session, cache=False)
141
+
142
+ assert st.cache is None
143
+
144
+
145
+ def test_st_init_with_cache_dict(mock_session):
146
+ """Test StockSt initialization with cache as dict"""
147
+ cache_config = {"directory": "/tmp/cache"}
148
+ st = StockSt(session=mock_session, cache=cache_config)
149
+
150
+ assert st.cache is not None
151
+ assert isinstance(st.cache, Cache)
152
+
153
+
154
+ def test_st_init_with_all_params(mock_session):
155
+ """Test StockSt initialization with all parameters"""
156
+ st = StockSt(
157
+ session=mock_session,
158
+ params={"year": "2023"},
159
+ coolant={"interval": 1.0},
160
+ retry={"max_retries": 3},
161
+ cache=True,
162
+ )
163
+
164
+ assert st.name == NAME
165
+ assert st.params.year == "2023"
166
+ assert st.cache is not None
167
+ assert st.paginate.pagesize == PAGINATE.pagesize
168
+ assert st.paginate.pagelimit == PAGINATE.pagelimit
169
+
170
+
171
+ def test_st_constants():
172
+ """Test that constants are properly defined"""
173
+ assert NAME == "stockst"
174
+ assert KEY == "/tushare/stockst"
175
+ assert SOURCE is not None
176
+ assert TARGET is not None
177
+
178
+
179
+ # ============================================================================
180
+ # Transform Method Tests
181
+ # ============================================================================
182
+
183
+
184
+ def test_st_transform_basic(mock_session, sample_source_data):
185
+ """Test basic data transformation"""
186
+ st = StockSt(session=mock_session)
187
+ result = st.transform(sample_source_data)
188
+
189
+ assert not result.empty
190
+ assert len(result) == 3
191
+ assert "code" in result.columns
192
+ assert "name" in result.columns
193
+ assert "date" in result.columns
194
+
195
+
196
+ def test_st_transform_code_mapping(mock_session, sample_source_data):
197
+ """Test that ts_code is mapped to code"""
198
+ st = StockSt(session=mock_session)
199
+ result = st.transform(sample_source_data)
200
+
201
+ assert result["code"].tolist() == ["000001.SZ", "000002.SZ", "600000.SH"]
202
+
203
+
204
+ def test_st_transform_name_mapping(mock_session, sample_source_data):
205
+ """Test that name is preserved"""
206
+ st = StockSt(session=mock_session)
207
+ result = st.transform(sample_source_data)
208
+
209
+ assert "*ST平安" in result["name"].values
210
+
211
+
212
+ def test_st_transform_date_format(mock_session, sample_source_data):
213
+ """Test that trade_date is converted from YYYYMMDD to YYYY-MM-DD"""
214
+ st = StockSt(session=mock_session)
215
+ result = st.transform(sample_source_data)
216
+
217
+ assert "2023-01-01" in result["date"].values
218
+ assert "2023-01-02" in result["date"].values
219
+
220
+
221
+ def test_st_transform_datecode_preserved(mock_session, sample_source_data):
222
+ """Test that datecode preserves original format"""
223
+ st = StockSt(session=mock_session)
224
+ result = st.transform(sample_source_data)
225
+
226
+ assert "20230101" in result["datecode"].values
227
+ assert "20230102" in result["datecode"].values
228
+
229
+
230
+ def test_st_transform_type_fields(mock_session, sample_source_data):
231
+ """Test that type and type_name are preserved"""
232
+ st = StockSt(session=mock_session)
233
+ result = st.transform(sample_source_data)
234
+
235
+ assert all(result["type"] == "S")
236
+ assert "*ST" in result["type_name"].values
237
+ assert "ST" in result["type_name"].values
238
+
239
+
240
+ def test_st_transform_empty_dataframe(mock_session):
241
+ """Test transform with empty DataFrame"""
242
+ st = StockSt(session=mock_session)
243
+ empty_df = pd.DataFrame()
244
+ result = st.transform(empty_df)
245
+
246
+ assert result.empty
247
+ assert list(result.columns) == TARGET.list_column_names()
248
+
249
+
250
+ def test_st_transform_none_input(mock_session):
251
+ """Test transform with None input"""
252
+ st = StockSt(session=mock_session)
253
+ result = st.transform(None)
254
+
255
+ assert result.empty
256
+ assert list(result.columns) == TARGET.list_column_names()
257
+
258
+
259
+ def test_st_transform_handles_invalid_dates(mock_session):
260
+ """Test transform handles invalid date formats"""
261
+ st = StockSt(session=mock_session)
262
+ data = pd.DataFrame(
263
+ {
264
+ "ts_code": ["000001.SZ"],
265
+ "name": ["Test ST"],
266
+ "trade_date": ["invalid"],
267
+ "type": ["S"],
268
+ "type_name": ["*ST"],
269
+ }
270
+ )
271
+
272
+ result = st.transform(data)
273
+ assert pd.isna(result["date"].iloc[0]) or result["date"].iloc[0] == "NaT"
274
+
275
+
276
+ def test_st_transform_removes_duplicates(mock_session):
277
+ """Test that transform removes duplicate rows"""
278
+ st = StockSt(session=mock_session)
279
+ data = pd.DataFrame(
280
+ {
281
+ "ts_code": ["000001.SZ", "000001.SZ"], # Duplicate
282
+ "name": ["*ST平安", "*ST平安"],
283
+ "trade_date": ["20230101", "20230101"],
284
+ "type": ["S", "S"],
285
+ "type_name": ["*ST", "*ST"],
286
+ }
287
+ )
288
+
289
+ result = st.transform(data)
290
+ assert len(result) == 1
291
+
292
+
293
+ def test_st_transform_sorts_by_code(mock_session, sample_source_data):
294
+ """Test that result is sorted by code"""
295
+ st = StockSt(session=mock_session)
296
+ shuffled = sample_source_data.sample(frac=1).reset_index(drop=True)
297
+ result = st.transform(shuffled)
298
+
299
+ assert result["code"].tolist() == sorted(result["code"].tolist())
300
+
301
+
302
+ def test_st_transform_resets_index(mock_session, sample_source_data):
303
+ """Test that result has reset index"""
304
+ st = StockSt(session=mock_session)
305
+ result = st.transform(sample_source_data)
306
+
307
+ assert result.index.tolist() == list(range(len(result)))
308
+
309
+
310
+ def test_st_transform_only_target_columns(mock_session, sample_source_data):
311
+ """Test that only target columns are in result"""
312
+ st = StockSt(session=mock_session)
313
+ result = st.transform(sample_source_data)
314
+
315
+ expected_cols = set(TARGET.list_column_names())
316
+ actual_cols = set(result.columns)
317
+ assert actual_cols == expected_cols
318
+
319
+
320
+ # ============================================================================
321
+ # _run Method Tests
322
+ # ============================================================================
323
+
324
+
325
+ def test_st_run_with_cache_hit(mock_session):
326
+ """Test _run returns cached data when available"""
327
+ st = StockSt(session=mock_session, cache=True)
328
+
329
+ cached_df = pd.DataFrame({"code": ["000001.SZ"]})
330
+ st.cache.set(st.params.identifier, cached_df)
331
+
332
+ result = st._run()
333
+
334
+ assert result.equals(cached_df)
335
+
336
+
337
+ def test_st_run_basic_date_range(mock_session, sample_source_data):
338
+ """Test _run with start_date and end_date"""
339
+ st = StockSt(session=mock_session, params={"start_date": "20230101", "end_date": "20231231"})
340
+
341
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
342
+ result = st._run()
343
+
344
+ assert not result.empty
345
+ st._fetchall.assert_called_once()
346
+ call_kwargs = st._fetchall.call_args[1]
347
+ assert call_kwargs["start_date"] == "20230101"
348
+ assert call_kwargs["end_date"] == "20231231"
349
+
350
+
351
+ def test_st_run_with_year_param(mock_session, sample_source_data):
352
+ """Test _run converts year to start/end date"""
353
+ st = StockSt(session=mock_session, params={"year": "2023"})
354
+
355
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
356
+ st._run()
357
+
358
+ call_kwargs = st._fetchall.call_args[1]
359
+ assert call_kwargs["start_date"] == "20230101"
360
+ assert call_kwargs["end_date"] == "20231231"
361
+ assert "year" not in call_kwargs
362
+
363
+
364
+ def test_st_run_with_year_param_int(mock_session, sample_source_data):
365
+ """Test _run handles year as integer"""
366
+ st = StockSt(session=mock_session, params={"year": 2023})
367
+
368
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
369
+ st._run()
370
+
371
+ call_kwargs = st._fetchall.call_args[1]
372
+ assert call_kwargs["start_date"] == "20230101"
373
+ assert call_kwargs["end_date"] == "20231231"
374
+
375
+
376
+ def test_st_run_with_ts_code_param(mock_session, sample_source_data):
377
+ """Test _run with ts_code parameter"""
378
+ st = StockSt(session=mock_session, params={"ts_code": "600000.SH"})
379
+
380
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
381
+ st._run()
382
+
383
+ call_kwargs = st._fetchall.call_args[1]
384
+ assert call_kwargs["ts_code"] == "600000.SH"
385
+
386
+
387
+ def test_st_run_adds_fields_param(mock_session, sample_source_data):
388
+ """Test _run adds fields parameter if not provided"""
389
+ st = StockSt(session=mock_session)
390
+
391
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
392
+ st._run()
393
+
394
+ call_kwargs = st._fetchall.call_args[1]
395
+ assert "fields" in call_kwargs
396
+
397
+
398
+ def test_st_run_preserves_fields_param(mock_session, sample_source_data):
399
+ """Test _run preserves existing fields parameter"""
400
+ custom_fields = "ts_code,name,trade_date"
401
+ st = StockSt(session=mock_session, params={"fields": custom_fields})
402
+
403
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
404
+ st._run()
405
+
406
+ call_kwargs = st._fetchall.call_args[1]
407
+ assert "fields" in call_kwargs
408
+
409
+
410
+ def test_st_run_sets_cache(mock_session, sample_source_data):
411
+ """Test _run saves result to cache"""
412
+ st = StockSt(session=mock_session, cache=True)
413
+
414
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
415
+ st._run()
416
+
417
+ cached = st.cache.get(st.params.identifier)
418
+ assert cached is not None
419
+
420
+
421
+ def test_st_run_calls_transform(mock_session, sample_source_data):
422
+ """Test _run calls transform method"""
423
+ st = StockSt(session=mock_session)
424
+
425
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
426
+ with patch.object(st, "transform", return_value=sample_source_data) as mock_transform:
427
+ st._run()
428
+
429
+ mock_transform.assert_called_once()
430
+
431
+
432
+ # ============================================================================
433
+ # list_codes Method Tests
434
+ # ============================================================================
435
+
436
+
437
+ def test_st_list_codes_basic(mock_session, sample_source_data):
438
+ """Test list_codes returns list of ST stock codes"""
439
+ st = StockSt(session=mock_session, cache=True)
440
+
441
+ transformed = st.transform(sample_source_data)
442
+ st.cache.set(st.params.identifier, transformed)
443
+
444
+ codes = st.list_codes()
445
+
446
+ assert isinstance(codes, list)
447
+ assert len(codes) == 3
448
+ assert "000001.SZ" in codes
449
+
450
+
451
+ def test_st_list_codes_unique(mock_session):
452
+ """Test list_codes returns unique codes"""
453
+ st = StockSt(session=mock_session, cache=True)
454
+
455
+ df = pd.DataFrame(
456
+ {
457
+ "code": ["000001.SZ", "000001.SZ", "000002.SZ"],
458
+ }
459
+ )
460
+ st.cache.set(st.params.identifier, df)
461
+
462
+ codes = st.list_codes()
463
+
464
+ assert len(codes) == 2
465
+
466
+
467
+ def test_st_list_codes_sorted(mock_session, sample_source_data):
468
+ """Test list_codes returns sorted list"""
469
+ st = StockSt(session=mock_session, cache=True)
470
+
471
+ transformed = st.transform(sample_source_data)
472
+ st.cache.set(st.params.identifier, transformed)
473
+
474
+ codes = st.list_codes()
475
+
476
+ assert codes == sorted(codes)
477
+
478
+
479
+ def test_st_list_codes_calls_run_when_not_cached(mock_session, sample_source_data):
480
+ """Test list_codes calls run() when data not in cache"""
481
+ st = StockSt(session=mock_session)
482
+
483
+ with patch.object(st, "run", return_value=st.transform(sample_source_data)):
484
+ codes = st.list_codes()
485
+
486
+ st.run.assert_called_once()
487
+ assert len(codes) == 3
488
+
489
+
490
+ # ============================================================================
491
+ # list_names Method Tests
492
+ # ============================================================================
493
+
494
+
495
+ def test_st_list_names_basic(mock_session, sample_source_data):
496
+ """Test list_names returns list of ST stock names"""
497
+ st = StockSt(session=mock_session, cache=True)
498
+
499
+ transformed = st.transform(sample_source_data)
500
+ st.cache.set(st.params.identifier, transformed)
501
+
502
+ names = st.list_names()
503
+
504
+ assert isinstance(names, list)
505
+ assert len(names) == 3
506
+ assert "*ST平安" in names
507
+
508
+
509
+ def test_st_list_names_sorted(mock_session, sample_source_data):
510
+ """Test list_names returns sorted list"""
511
+ st = StockSt(session=mock_session, cache=True)
512
+
513
+ transformed = st.transform(sample_source_data)
514
+ st.cache.set(st.params.identifier, transformed)
515
+
516
+ names = st.list_names()
517
+
518
+ assert names == sorted(names)
519
+
520
+
521
+ def test_st_list_names_unique(mock_session):
522
+ """Test list_names returns unique names"""
523
+ st = StockSt(session=mock_session, cache=True)
524
+
525
+ df = pd.DataFrame(
526
+ {
527
+ "name": ["*ST平安", "*ST平安", "*ST万科"],
528
+ }
529
+ )
530
+ st.cache.set(st.params.identifier, df)
531
+
532
+ names = st.list_names()
533
+
534
+ assert len(names) == 2
535
+
536
+
537
+ def test_st_list_names_calls_run_when_not_cached(mock_session, sample_source_data):
538
+ """Test list_names calls run() when data not in cache"""
539
+ st = StockSt(session=mock_session)
540
+
541
+ with patch.object(st, "run", return_value=st.transform(sample_source_data)):
542
+ names = st.list_names()
543
+
544
+ st.run.assert_called_once()
545
+ assert len(names) == 3
546
+
547
+
548
+ # ============================================================================
549
+ # Integration Tests
550
+ # ============================================================================
551
+
552
+
553
+ def test_st_full_workflow(mock_session, sample_source_data):
554
+ """Test complete workflow from initialization to data retrieval"""
555
+ st = StockSt(
556
+ session=mock_session,
557
+ params={"year": "2023"},
558
+ cache=True,
559
+ )
560
+
561
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
562
+ result = st.run()
563
+
564
+ assert not result.empty
565
+ assert "code" in result.columns
566
+
567
+ codes = st.list_codes()
568
+ names = st.list_names()
569
+
570
+ assert len(codes) > 0
571
+ assert len(names) > 0
572
+
573
+
574
+ def test_st_cache_persistence(mock_session, sample_source_data):
575
+ """Test that cache persists across method calls"""
576
+ st = StockSt(session=mock_session, cache=True)
577
+
578
+ with patch.object(st, "_load_cache", return_value=None) as mock_load:
579
+ with patch.object(st, "_fetchall", return_value=sample_source_data) as mock_fetch:
580
+ # First run - fetches data and caches it
581
+ result1 = st.run()
582
+ assert mock_fetch.call_count == 1
583
+ assert mock_load.call_count == 1
584
+
585
+ # Second run - _load_cache still returns None, so _fetchall called again
586
+ result2 = st.run()
587
+ assert mock_fetch.call_count == 2 # Called again
588
+ assert mock_load.call_count == 2
589
+
590
+ pd.testing.assert_frame_equal(result1, result2)
591
+
592
+
593
+ def test_st_params_identifier_uniqueness(mock_session):
594
+ """Test that different params produce different cache keys"""
595
+ st1 = StockSt(session=mock_session, params={"year": "2022"}, cache=True)
596
+ st2 = StockSt(session=mock_session, params={"year": "2023"}, cache=True)
597
+
598
+ assert st1.params.identifier != st2.params.identifier
599
+
600
+
601
+ # ============================================================================
602
+ # Edge Case Tests
603
+ # ============================================================================
604
+
605
+
606
+ def test_st_empty_result_handling(mock_session):
607
+ """Test handling of empty API results"""
608
+ st = StockSt(session=mock_session)
609
+
610
+ empty_df = pd.DataFrame()
611
+ with patch.object(st, "_fetchall", return_value=empty_df):
612
+ result = st._run()
613
+
614
+ assert result.empty
615
+ assert list(result.columns) == TARGET.list_column_names()
616
+
617
+
618
+ def test_st_large_dataset_handling(mock_session):
619
+ """Test handling of large datasets"""
620
+ st = StockSt(session=mock_session)
621
+
622
+ large_data = pd.DataFrame(
623
+ {
624
+ "ts_code": [f"{i:06d}.SZ" for i in range(1000)],
625
+ "name": [f"*ST股票{i}" for i in range(1000)],
626
+ "trade_date": ["20230101"] * 1000,
627
+ "type": ["S"] * 1000,
628
+ "type_name": ["*ST"] * 1000,
629
+ }
630
+ )
631
+
632
+ result = st.transform(large_data)
633
+
634
+ assert len(result) == 1000
635
+ assert not result.empty
636
+
637
+
638
+ def test_st_special_characters_in_data(mock_session):
639
+ """Test handling of special characters in ST data"""
640
+ st = StockSt(session=mock_session)
641
+
642
+ data = pd.DataFrame(
643
+ {
644
+ "ts_code": ["000001.SZ"],
645
+ "name": ["*ST股票(特殊)& Special <Chars>"],
646
+ "trade_date": ["20230101"],
647
+ "type": ["S"],
648
+ "type_name": ["*ST"],
649
+ }
650
+ )
651
+
652
+ result = st.transform(data)
653
+
654
+ assert len(result) == 1
655
+ assert "ST" in result["name"].values[0] or "特殊" in result["name"].values[0]
656
+
657
+
658
+ def test_st_without_cache(mock_session, sample_source_data):
659
+ """Test StockSt works correctly without cache"""
660
+ st = StockSt(session=mock_session, cache=False)
661
+
662
+ assert st.cache is None
663
+
664
+ with patch.object(st, "_fetchall", return_value=sample_source_data):
665
+ result = st.run()
666
+
667
+ assert not result.empty
668
+
669
+ codes = st.list_codes()
670
+ names = st.list_names()
671
+
672
+ assert len(codes) > 0
673
+ assert len(names) > 0
674
+
675
+
676
+ def test_st_multiple_st_types(mock_session):
677
+ """Test handling of multiple ST types"""
678
+ st = StockSt(session=mock_session)
679
+
680
+ data = pd.DataFrame(
681
+ {
682
+ "ts_code": ["000001.SZ", "000002.SZ", "000003.SZ"],
683
+ "name": ["*ST股票1", "ST股票2", "SST股票3"],
684
+ "trade_date": ["20230101", "20230101", "20230101"],
685
+ "type": ["S", "S", "S"],
686
+ "type_name": ["*ST", "ST", "SST"],
687
+ }
688
+ )
689
+
690
+ result = st.transform(data)
691
+
692
+ assert len(result) == 3
693
+ assert set(result["type_name"].values) == {"*ST", "ST", "SST"}