intershell 0.3.0

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 (357) hide show
  1. package/README.md +301 -0
  2. package/dist/commands/ci/act.d.ts +13 -0
  3. package/dist/commands/ci/act.d.ts.map +1 -0
  4. package/dist/commands/ci/act.js +89 -0
  5. package/dist/commands/ci/act.js.map +1 -0
  6. package/dist/commands/ci/attach-affected.d.ts +12 -0
  7. package/dist/commands/ci/attach-affected.d.ts.map +1 -0
  8. package/dist/commands/ci/attach-affected.js +83 -0
  9. package/dist/commands/ci/attach-affected.js.map +1 -0
  10. package/dist/commands/ci/attach-service-ports.d.ts +10 -0
  11. package/dist/commands/ci/attach-service-ports.d.ts.map +1 -0
  12. package/dist/commands/ci/attach-service-ports.js +25 -0
  13. package/dist/commands/ci/attach-service-ports.js.map +1 -0
  14. package/dist/commands/commit-check.d.ts +13 -0
  15. package/dist/commands/commit-check.d.ts.map +1 -0
  16. package/dist/commands/commit-check.js +110 -0
  17. package/dist/commands/commit-check.js.map +1 -0
  18. package/dist/commands/commit.d.ts +16 -0
  19. package/dist/commands/commit.d.ts.map +1 -0
  20. package/dist/commands/commit.js +91 -0
  21. package/dist/commands/commit.js.map +1 -0
  22. package/dist/commands/dev/check.d.ts +13 -0
  23. package/dist/commands/dev/check.d.ts.map +1 -0
  24. package/dist/commands/dev/check.js +91 -0
  25. package/dist/commands/dev/check.js.map +1 -0
  26. package/dist/commands/dev/cleanup.d.ts +10 -0
  27. package/dist/commands/dev/cleanup.d.ts.map +1 -0
  28. package/dist/commands/dev/cleanup.js +28 -0
  29. package/dist/commands/dev/cleanup.js.map +1 -0
  30. package/dist/commands/dev/rm.d.ts +12 -0
  31. package/dist/commands/dev/rm.d.ts.map +1 -0
  32. package/dist/commands/dev/rm.js +49 -0
  33. package/dist/commands/dev/rm.js.map +1 -0
  34. package/dist/commands/dev/setup.d.ts +10 -0
  35. package/dist/commands/dev/setup.d.ts.map +1 -0
  36. package/dist/commands/dev/setup.js +40 -0
  37. package/dist/commands/dev/setup.js.map +1 -0
  38. package/dist/commands/local/cleanup.d.ts +12 -0
  39. package/dist/commands/local/cleanup.d.ts.map +1 -0
  40. package/dist/commands/local/cleanup.js +62 -0
  41. package/dist/commands/local/cleanup.js.map +1 -0
  42. package/dist/commands/local/setup.d.ts +11 -0
  43. package/dist/commands/local/setup.d.ts.map +1 -0
  44. package/dist/commands/local/setup.js +55 -0
  45. package/dist/commands/local/setup.js.map +1 -0
  46. package/dist/commands/local/vscode.d.ts +17 -0
  47. package/dist/commands/local/vscode.d.ts.map +1 -0
  48. package/dist/commands/local/vscode.js +94 -0
  49. package/dist/commands/local/vscode.js.map +1 -0
  50. package/dist/commands/update-package-json.d.ts +12 -0
  51. package/dist/commands/update-package-json.d.ts.map +1 -0
  52. package/dist/commands/update-package-json.js +82 -0
  53. package/dist/commands/update-package-json.js.map +1 -0
  54. package/dist/commands/version/apply.d.ts +16 -0
  55. package/dist/commands/version/apply.d.ts.map +1 -0
  56. package/dist/commands/version/apply.js +120 -0
  57. package/dist/commands/version/apply.js.map +1 -0
  58. package/dist/commands/version/ci.d.ts +12 -0
  59. package/dist/commands/version/ci.d.ts.map +1 -0
  60. package/dist/commands/version/ci.js +67 -0
  61. package/dist/commands/version/ci.js.map +1 -0
  62. package/dist/commands/version/prepare.d.ts +19 -0
  63. package/dist/commands/version/prepare.d.ts.map +1 -0
  64. package/dist/commands/version/prepare.js +153 -0
  65. package/dist/commands/version/prepare.js.map +1 -0
  66. package/dist/core/colorify.d.ts +21 -0
  67. package/dist/core/colorify.d.ts.map +1 -0
  68. package/dist/core/colorify.js +56 -0
  69. package/dist/core/colorify.js.map +1 -0
  70. package/dist/core/index.d.ts +4 -0
  71. package/dist/core/index.d.ts.map +1 -0
  72. package/dist/core/index.js +3 -0
  73. package/dist/core/index.js.map +1 -0
  74. package/dist/core/types.d.ts +181 -0
  75. package/dist/core/types.d.ts.map +1 -0
  76. package/dist/core/types.js +5 -0
  77. package/dist/core/types.js.map +1 -0
  78. package/dist/core/wrapshell.d.ts +19 -0
  79. package/dist/core/wrapshell.d.ts.map +1 -0
  80. package/dist/core/wrapshell.js +323 -0
  81. package/dist/core/wrapshell.js.map +1 -0
  82. package/dist/entities/affected/affected.d.ts +4 -0
  83. package/dist/entities/affected/affected.d.ts.map +1 -0
  84. package/dist/entities/affected/affected.js +20 -0
  85. package/dist/entities/affected/affected.js.map +1 -0
  86. package/dist/entities/affected/affected.test.d.ts +2 -0
  87. package/dist/entities/affected/affected.test.d.ts.map +1 -0
  88. package/dist/entities/affected/affected.test.js +305 -0
  89. package/dist/entities/affected/affected.test.js.map +1 -0
  90. package/dist/entities/affected/index.d.ts +2 -0
  91. package/dist/entities/affected/index.d.ts.map +1 -0
  92. package/dist/entities/affected/index.js +2 -0
  93. package/dist/entities/affected/index.js.map +1 -0
  94. package/dist/entities/branch/branch.d.ts +8 -0
  95. package/dist/entities/branch/branch.d.ts.map +1 -0
  96. package/dist/entities/branch/branch.js +74 -0
  97. package/dist/entities/branch/branch.js.map +1 -0
  98. package/dist/entities/branch/branch.test.d.ts +2 -0
  99. package/dist/entities/branch/branch.test.d.ts.map +1 -0
  100. package/dist/entities/branch/branch.test.js +316 -0
  101. package/dist/entities/branch/branch.test.js.map +1 -0
  102. package/dist/entities/branch/branch.types.d.ts +6 -0
  103. package/dist/entities/branch/branch.types.d.ts.map +1 -0
  104. package/dist/entities/branch/branch.types.js +2 -0
  105. package/dist/entities/branch/branch.types.js.map +1 -0
  106. package/dist/entities/branch/index.d.ts +3 -0
  107. package/dist/entities/branch/index.d.ts.map +1 -0
  108. package/dist/entities/branch/index.js +3 -0
  109. package/dist/entities/branch/index.js.map +1 -0
  110. package/dist/entities/commit/commit.d.ts +15 -0
  111. package/dist/entities/commit/commit.d.ts.map +1 -0
  112. package/dist/entities/commit/commit.js +196 -0
  113. package/dist/entities/commit/commit.js.map +1 -0
  114. package/dist/entities/commit/commit.test.d.ts +26 -0
  115. package/dist/entities/commit/commit.test.d.ts.map +1 -0
  116. package/dist/entities/commit/commit.test.js +550 -0
  117. package/dist/entities/commit/commit.test.js.map +1 -0
  118. package/dist/entities/commit/commit.types.d.ts +49 -0
  119. package/dist/entities/commit/commit.types.d.ts.map +1 -0
  120. package/dist/entities/commit/commit.types.js +31 -0
  121. package/dist/entities/commit/commit.types.js.map +1 -0
  122. package/dist/entities/commit/index.d.ts +3 -0
  123. package/dist/entities/commit/index.d.ts.map +1 -0
  124. package/dist/entities/commit/index.js +3 -0
  125. package/dist/entities/commit/index.js.map +1 -0
  126. package/dist/entities/commit/pr.d.ts +11 -0
  127. package/dist/entities/commit/pr.d.ts.map +1 -0
  128. package/dist/entities/commit/pr.js +201 -0
  129. package/dist/entities/commit/pr.js.map +1 -0
  130. package/dist/entities/commit/pr.test.d.ts +2 -0
  131. package/dist/entities/commit/pr.test.d.ts.map +1 -0
  132. package/dist/entities/commit/pr.test.js +782 -0
  133. package/dist/entities/commit/pr.test.js.map +1 -0
  134. package/dist/entities/compose/compose.d.ts +18 -0
  135. package/dist/entities/compose/compose.d.ts.map +1 -0
  136. package/dist/entities/compose/compose.js +197 -0
  137. package/dist/entities/compose/compose.js.map +1 -0
  138. package/dist/entities/compose/compose.test.d.ts +2 -0
  139. package/dist/entities/compose/compose.test.d.ts.map +1 -0
  140. package/dist/entities/compose/compose.test.js +406 -0
  141. package/dist/entities/compose/compose.test.js.map +1 -0
  142. package/dist/entities/compose/compose.types.d.ts +77 -0
  143. package/dist/entities/compose/compose.types.d.ts.map +1 -0
  144. package/dist/entities/compose/compose.types.js +2 -0
  145. package/dist/entities/compose/compose.types.js.map +1 -0
  146. package/dist/entities/compose/index.d.ts +3 -0
  147. package/dist/entities/compose/index.d.ts.map +1 -0
  148. package/dist/entities/compose/index.js +3 -0
  149. package/dist/entities/compose/index.js.map +1 -0
  150. package/dist/entities/entities.shell.d.ts +29 -0
  151. package/dist/entities/entities.shell.d.ts.map +1 -0
  152. package/dist/entities/entities.shell.js +27 -0
  153. package/dist/entities/entities.shell.js.map +1 -0
  154. package/dist/entities/entities.shell.test.d.ts +2 -0
  155. package/dist/entities/entities.shell.test.d.ts.map +1 -0
  156. package/dist/entities/entities.shell.test.js +23 -0
  157. package/dist/entities/entities.shell.test.js.map +1 -0
  158. package/dist/entities/index.d.ts +12 -0
  159. package/dist/entities/index.d.ts.map +1 -0
  160. package/dist/entities/index.js +12 -0
  161. package/dist/entities/index.js.map +1 -0
  162. package/dist/entities/intershell-config/intershell-config.d.ts +11 -0
  163. package/dist/entities/intershell-config/intershell-config.d.ts.map +1 -0
  164. package/dist/entities/intershell-config/intershell-config.default.d.ts +188 -0
  165. package/dist/entities/intershell-config/intershell-config.default.d.ts.map +1 -0
  166. package/dist/entities/intershell-config/intershell-config.default.js +225 -0
  167. package/dist/entities/intershell-config/intershell-config.default.js.map +1 -0
  168. package/dist/entities/intershell-config/intershell-config.js +132 -0
  169. package/dist/entities/intershell-config/intershell-config.js.map +1 -0
  170. package/dist/entities/intershell-config/intershell-config.test.d.ts +2 -0
  171. package/dist/entities/intershell-config/intershell-config.test.d.ts.map +1 -0
  172. package/dist/entities/intershell-config/intershell-config.test.js +102 -0
  173. package/dist/entities/intershell-config/intershell-config.test.js.map +1 -0
  174. package/dist/entities/intershell-config/intershell-config.types.d.ts +103 -0
  175. package/dist/entities/intershell-config/intershell-config.types.d.ts.map +1 -0
  176. package/dist/entities/intershell-config/intershell-config.types.js +2 -0
  177. package/dist/entities/intershell-config/intershell-config.types.js.map +1 -0
  178. package/dist/entities/package/index.d.ts +4 -0
  179. package/dist/entities/package/index.d.ts.map +1 -0
  180. package/dist/entities/package/index.js +4 -0
  181. package/dist/entities/package/index.js.map +1 -0
  182. package/dist/entities/package/package.d.ts +49 -0
  183. package/dist/entities/package/package.d.ts.map +1 -0
  184. package/dist/entities/package/package.js +234 -0
  185. package/dist/entities/package/package.js.map +1 -0
  186. package/dist/entities/package/package.shell.d.ts +48 -0
  187. package/dist/entities/package/package.shell.d.ts.map +1 -0
  188. package/dist/entities/package/package.shell.js +118 -0
  189. package/dist/entities/package/package.shell.js.map +1 -0
  190. package/dist/entities/package/package.test.d.ts +23 -0
  191. package/dist/entities/package/package.test.d.ts.map +1 -0
  192. package/dist/entities/package/package.test.js +637 -0
  193. package/dist/entities/package/package.test.js.map +1 -0
  194. package/dist/entities/package/package.types.d.ts +48 -0
  195. package/dist/entities/package/package.types.d.ts.map +1 -0
  196. package/dist/entities/package/package.types.js +2 -0
  197. package/dist/entities/package/package.types.js.map +1 -0
  198. package/dist/entities/package-changelog/index.d.ts +4 -0
  199. package/dist/entities/package-changelog/index.d.ts.map +1 -0
  200. package/dist/entities/package-changelog/index.js +4 -0
  201. package/dist/entities/package-changelog/index.js.map +1 -0
  202. package/dist/entities/package-changelog/package-changelog.d.ts +20 -0
  203. package/dist/entities/package-changelog/package-changelog.d.ts.map +1 -0
  204. package/dist/entities/package-changelog/package-changelog.js +59 -0
  205. package/dist/entities/package-changelog/package-changelog.js.map +1 -0
  206. package/dist/entities/package-changelog/package-changelog.types.d.ts +25 -0
  207. package/dist/entities/package-changelog/package-changelog.types.d.ts.map +1 -0
  208. package/dist/entities/package-changelog/package-changelog.types.js +2 -0
  209. package/dist/entities/package-changelog/package-changelog.types.js.map +1 -0
  210. package/dist/entities/package-changelog/template.d.ts +20 -0
  211. package/dist/entities/package-changelog/template.d.ts.map +1 -0
  212. package/dist/entities/package-changelog/template.default.d.ts +10 -0
  213. package/dist/entities/package-changelog/template.default.d.ts.map +1 -0
  214. package/dist/entities/package-changelog/template.default.js +85 -0
  215. package/dist/entities/package-changelog/template.default.js.map +1 -0
  216. package/dist/entities/package-changelog/template.js +90 -0
  217. package/dist/entities/package-changelog/template.js.map +1 -0
  218. package/dist/entities/package-commits/dependency-analyzer.d.ts +35 -0
  219. package/dist/entities/package-commits/dependency-analyzer.d.ts.map +1 -0
  220. package/dist/entities/package-commits/dependency-analyzer.js +169 -0
  221. package/dist/entities/package-commits/dependency-analyzer.js.map +1 -0
  222. package/dist/entities/package-commits/dependency-analyzer.test.d.ts +2 -0
  223. package/dist/entities/package-commits/dependency-analyzer.test.d.ts.map +1 -0
  224. package/dist/entities/package-commits/dependency-analyzer.test.js +25 -0
  225. package/dist/entities/package-commits/dependency-analyzer.test.js.map +1 -0
  226. package/dist/entities/package-commits/index.d.ts +3 -0
  227. package/dist/entities/package-commits/index.d.ts.map +1 -0
  228. package/dist/entities/package-commits/index.js +3 -0
  229. package/dist/entities/package-commits/index.js.map +1 -0
  230. package/dist/entities/package-commits/package-commits.d.ts +33 -0
  231. package/dist/entities/package-commits/package-commits.d.ts.map +1 -0
  232. package/dist/entities/package-commits/package-commits.js +149 -0
  233. package/dist/entities/package-commits/package-commits.js.map +1 -0
  234. package/dist/entities/package-commits/package-commits.test.d.ts +2 -0
  235. package/dist/entities/package-commits/package-commits.test.d.ts.map +1 -0
  236. package/dist/entities/package-commits/package-commits.test.js +40 -0
  237. package/dist/entities/package-commits/package-commits.test.js.map +1 -0
  238. package/dist/entities/package-tags/index.d.ts +2 -0
  239. package/dist/entities/package-tags/index.d.ts.map +1 -0
  240. package/dist/entities/package-tags/index.js +2 -0
  241. package/dist/entities/package-tags/index.js.map +1 -0
  242. package/dist/entities/package-tags/package-tags.d.ts +24 -0
  243. package/dist/entities/package-tags/package-tags.d.ts.map +1 -0
  244. package/dist/entities/package-tags/package-tags.js +197 -0
  245. package/dist/entities/package-tags/package-tags.js.map +1 -0
  246. package/dist/entities/package-tags/package-tags.test.d.ts +2 -0
  247. package/dist/entities/package-tags/package-tags.test.d.ts.map +1 -0
  248. package/dist/entities/package-tags/package-tags.test.js +60 -0
  249. package/dist/entities/package-tags/package-tags.test.js.map +1 -0
  250. package/dist/entities/package-version/index.d.ts +3 -0
  251. package/dist/entities/package-version/index.d.ts.map +1 -0
  252. package/dist/entities/package-version/index.js +3 -0
  253. package/dist/entities/package-version/index.js.map +1 -0
  254. package/dist/entities/package-version/package-version.d.ts +16 -0
  255. package/dist/entities/package-version/package-version.d.ts.map +1 -0
  256. package/dist/entities/package-version/package-version.js +166 -0
  257. package/dist/entities/package-version/package-version.js.map +1 -0
  258. package/dist/entities/package-version/package-version.test.d.ts +2 -0
  259. package/dist/entities/package-version/package-version.test.d.ts.map +1 -0
  260. package/dist/entities/package-version/package-version.test.js +113 -0
  261. package/dist/entities/package-version/package-version.test.js.map +1 -0
  262. package/dist/entities/package-version/package-version.types.d.ts +31 -0
  263. package/dist/entities/package-version/package-version.types.d.ts.map +1 -0
  264. package/dist/entities/package-version/package-version.types.js +2 -0
  265. package/dist/entities/package-version/package-version.types.js.map +1 -0
  266. package/dist/entities/tag/index.d.ts +3 -0
  267. package/dist/entities/tag/index.d.ts.map +1 -0
  268. package/dist/entities/tag/index.js +3 -0
  269. package/dist/entities/tag/index.js.map +1 -0
  270. package/dist/entities/tag/tag.d.ts +24 -0
  271. package/dist/entities/tag/tag.d.ts.map +1 -0
  272. package/dist/entities/tag/tag.js +168 -0
  273. package/dist/entities/tag/tag.js.map +1 -0
  274. package/dist/entities/tag/tag.test.d.ts +2 -0
  275. package/dist/entities/tag/tag.test.d.ts.map +1 -0
  276. package/dist/entities/tag/tag.test.js +638 -0
  277. package/dist/entities/tag/tag.test.js.map +1 -0
  278. package/dist/entities/tag/tag.types.d.ts +35 -0
  279. package/dist/entities/tag/tag.types.d.ts.map +1 -0
  280. package/dist/entities/tag/tag.types.js +2 -0
  281. package/dist/entities/tag/tag.types.js.map +1 -0
  282. package/dist/index.d.ts +3 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +6 -0
  285. package/dist/index.js.map +1 -0
  286. package/package.json +73 -0
  287. package/src/commands/ci/act.ts +95 -0
  288. package/src/commands/ci/attach-affected.ts +93 -0
  289. package/src/commands/ci/attach-service-ports.ts +31 -0
  290. package/src/commands/commit-check.ts +124 -0
  291. package/src/commands/commit.ts +103 -0
  292. package/src/commands/dev/check.ts +117 -0
  293. package/src/commands/dev/cleanup.ts +34 -0
  294. package/src/commands/dev/rm.ts +66 -0
  295. package/src/commands/dev/setup.ts +48 -0
  296. package/src/commands/local/cleanup.ts +74 -0
  297. package/src/commands/local/setup.ts +68 -0
  298. package/src/commands/local/vscode.ts +118 -0
  299. package/src/commands/update-package-json.ts +104 -0
  300. package/src/commands/version/apply.ts +156 -0
  301. package/src/commands/version/ci.ts +85 -0
  302. package/src/commands/version/prepare.ts +217 -0
  303. package/src/core/colorify.ts +61 -0
  304. package/src/core/index.ts +3 -0
  305. package/src/core/types.ts +262 -0
  306. package/src/core/wrapshell.ts +388 -0
  307. package/src/entities/affected/affected.test.ts +427 -0
  308. package/src/entities/affected/affected.ts +22 -0
  309. package/src/entities/affected/index.ts +1 -0
  310. package/src/entities/branch/branch.test.ts +348 -0
  311. package/src/entities/branch/branch.ts +89 -0
  312. package/src/entities/branch/branch.types.ts +5 -0
  313. package/src/entities/branch/index.ts +2 -0
  314. package/src/entities/commit/commit.test.ts +769 -0
  315. package/src/entities/commit/commit.ts +245 -0
  316. package/src/entities/commit/commit.types.ts +81 -0
  317. package/src/entities/commit/index.ts +2 -0
  318. package/src/entities/commit/pr.test.ts +860 -0
  319. package/src/entities/commit/pr.ts +241 -0
  320. package/src/entities/compose/compose.test.ts +496 -0
  321. package/src/entities/compose/compose.ts +251 -0
  322. package/src/entities/compose/compose.types.ts +88 -0
  323. package/src/entities/compose/index.ts +2 -0
  324. package/src/entities/entities.shell.test.ts +35 -0
  325. package/src/entities/entities.shell.ts +81 -0
  326. package/src/entities/index.ts +11 -0
  327. package/src/entities/intershell-config/intershell-config.default.ts +229 -0
  328. package/src/entities/intershell-config/intershell-config.test.ts +117 -0
  329. package/src/entities/intershell-config/intershell-config.ts +143 -0
  330. package/src/entities/intershell-config/intershell-config.types.ts +118 -0
  331. package/src/entities/package/index.ts +3 -0
  332. package/src/entities/package/package.shell.ts +124 -0
  333. package/src/entities/package/package.test.ts +830 -0
  334. package/src/entities/package/package.ts +267 -0
  335. package/src/entities/package/package.types.ts +49 -0
  336. package/src/entities/package-changelog/index.ts +3 -0
  337. package/src/entities/package-changelog/package-changelog.ts +81 -0
  338. package/src/entities/package-changelog/package-changelog.types.ts +30 -0
  339. package/src/entities/package-changelog/template.default.ts +109 -0
  340. package/src/entities/package-changelog/template.ts +118 -0
  341. package/src/entities/package-commits/dependency-analyzer.test.ts +29 -0
  342. package/src/entities/package-commits/dependency-analyzer.ts +194 -0
  343. package/src/entities/package-commits/index.ts +2 -0
  344. package/src/entities/package-commits/package-commits.test.ts +44 -0
  345. package/src/entities/package-commits/package-commits.ts +191 -0
  346. package/src/entities/package-tags/index.ts +1 -0
  347. package/src/entities/package-tags/package-tags.test.ts +73 -0
  348. package/src/entities/package-tags/package-tags.ts +234 -0
  349. package/src/entities/package-version/index.ts +2 -0
  350. package/src/entities/package-version/package-version.test.ts +141 -0
  351. package/src/entities/package-version/package-version.ts +234 -0
  352. package/src/entities/package-version/package-version.types.ts +35 -0
  353. package/src/entities/tag/index.ts +2 -0
  354. package/src/entities/tag/tag.test.ts +844 -0
  355. package/src/entities/tag/tag.ts +208 -0
  356. package/src/entities/tag/tag.types.ts +37 -0
  357. package/src/index.ts +7 -0
@@ -0,0 +1,844 @@
1
+ import { afterAll, afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
+ import type { $ } from "bun";
3
+
4
+ // Import EntityTag directly
5
+ const { EntityTag } = await import("./tag");
6
+
7
+ describe("EntityTag", () => {
8
+ // Store original methods to restore after tests
9
+ let originalGitTagList: (prefix: string) => $.ShellPromise;
10
+ let originalGitTagLatest: (prefix: string) => $.ShellPromise;
11
+ let originalGitRevParse: (ref: string) => $.ShellPromise;
12
+ let originalGitTagExists: (tagName: string) => $.ShellPromise;
13
+
14
+ // Restore module mocks after all tests
15
+ afterAll(() => {
16
+ mock.restore();
17
+ });
18
+ let originalGitTag: (
19
+ tagName: string,
20
+ message: string,
21
+ options: { force?: string },
22
+ ) => $.ShellPromise;
23
+ let originalGitPushTag: (tagName: string) => $.ShellPromise;
24
+ let originalGitDeleteTag: (tagName: string) => $.ShellPromise;
25
+ let originalGitTagInfo: (tagName: string) => $.ShellPromise;
26
+ let originalGitFirstCommit: () => $.ShellPromise;
27
+
28
+ beforeEach(async () => {
29
+ // Import and mock entitiesShell methods directly
30
+ const { entitiesShell } = await import("../entities.shell");
31
+
32
+ // Store original methods if not already stored
33
+ if (!originalGitTagList) {
34
+ originalGitTagList = entitiesShell.gitTagList;
35
+ }
36
+ if (!originalGitTagLatest) {
37
+ originalGitTagLatest = entitiesShell.gitTagLatest;
38
+ }
39
+ if (!originalGitRevParse) {
40
+ originalGitRevParse = entitiesShell.gitRevParse;
41
+ }
42
+ if (!originalGitTagExists) {
43
+ originalGitTagExists = entitiesShell.gitTagExists;
44
+ }
45
+ if (!originalGitTag) {
46
+ originalGitTag = entitiesShell.gitTag;
47
+ }
48
+ if (!originalGitPushTag) {
49
+ originalGitPushTag = entitiesShell.gitPushTag;
50
+ }
51
+ if (!originalGitDeleteTag) {
52
+ originalGitDeleteTag = entitiesShell.gitDeleteTag;
53
+ }
54
+ if (!originalGitTagInfo) {
55
+ originalGitTagInfo = entitiesShell.gitTagInfo;
56
+ }
57
+ if (!originalGitFirstCommit) {
58
+ originalGitFirstCommit = entitiesShell.gitFirstCommit;
59
+ }
60
+
61
+ // Mock individual methods directly
62
+ entitiesShell.gitTagList = mock(
63
+ () =>
64
+ ({
65
+ exitCode: 0,
66
+ text: () => ["v1.0.0", "v1.1.0", "intershell-v1.0.0"].join("\n"),
67
+ }) as unknown as $.ShellPromise,
68
+ );
69
+
70
+ entitiesShell.gitTagLatest = mock(
71
+ () =>
72
+ ({
73
+ exitCode: 0,
74
+ text: () => "v1.1.0",
75
+ }) as unknown as $.ShellPromise,
76
+ );
77
+
78
+ entitiesShell.gitRevParse = mock(
79
+ () =>
80
+ ({
81
+ exitCode: 0,
82
+ text: () => "abc123",
83
+ }) as unknown as $.ShellPromise,
84
+ );
85
+
86
+ entitiesShell.gitTagExists = mock(
87
+ () =>
88
+ ({
89
+ exitCode: 0,
90
+ text: () => "v1.0.0",
91
+ }) as unknown as $.ShellPromise,
92
+ );
93
+
94
+ entitiesShell.gitTag = mock(() => Promise.resolve() as unknown as $.ShellPromise);
95
+ entitiesShell.gitPushTag = mock(() => Promise.resolve() as unknown as $.ShellPromise);
96
+ entitiesShell.gitDeleteTag = mock(() => Promise.resolve() as unknown as $.ShellPromise);
97
+
98
+ entitiesShell.gitTagInfo = mock(
99
+ () =>
100
+ ({
101
+ exitCode: 0,
102
+ text: () => ["2024-01-01T00:00:00Z", "test message"].join("\n"),
103
+ }) as unknown as $.ShellPromise,
104
+ );
105
+
106
+ entitiesShell.gitFirstCommit = mock(
107
+ () =>
108
+ ({
109
+ exitCode: 0,
110
+ text: () => "first123",
111
+ }) as unknown as $.ShellPromise,
112
+ );
113
+ });
114
+
115
+ afterEach(async () => {
116
+ // Restore original methods
117
+ const { entitiesShell } = await import("../entities.shell");
118
+
119
+ if (originalGitTagList) {
120
+ entitiesShell.gitTagList = originalGitTagList;
121
+ }
122
+ if (originalGitTagLatest) {
123
+ entitiesShell.gitTagLatest = originalGitTagLatest;
124
+ }
125
+ if (originalGitRevParse) {
126
+ entitiesShell.gitRevParse = originalGitRevParse;
127
+ }
128
+ if (originalGitTagExists) {
129
+ entitiesShell.gitTagExists = originalGitTagExists;
130
+ }
131
+ if (originalGitTag) {
132
+ entitiesShell.gitTag = originalGitTag;
133
+ }
134
+ if (originalGitPushTag) {
135
+ entitiesShell.gitPushTag = originalGitPushTag;
136
+ }
137
+ if (originalGitDeleteTag) {
138
+ entitiesShell.gitDeleteTag = originalGitDeleteTag;
139
+ }
140
+ if (originalGitTagInfo) {
141
+ entitiesShell.gitTagInfo = originalGitTagInfo;
142
+ }
143
+ if (originalGitFirstCommit) {
144
+ entitiesShell.gitFirstCommit = originalGitFirstCommit;
145
+ }
146
+ });
147
+
148
+ describe("parseByName", () => {
149
+ test("should parse tag name correctly", () => {
150
+ const result = EntityTag.parseByName("v1.0.0");
151
+ expect(result).toEqual({
152
+ name: "v1.0.0",
153
+ prefix: "v",
154
+ format: "semver",
155
+ });
156
+ });
157
+
158
+ test("should parse tag with package prefix", () => {
159
+ const result = EntityTag.parseByName("intershell-v1.0.0");
160
+ expect(result).toEqual({
161
+ name: "intershell-v1.0.0",
162
+ prefix: "intershell-v",
163
+ format: "custom",
164
+ });
165
+ });
166
+
167
+ test("should parse calver tag", () => {
168
+ const result = EntityTag.parseByName("2024.01.01");
169
+ expect(result).toEqual({
170
+ name: "2024.01.01",
171
+ prefix: undefined,
172
+ format: "semver",
173
+ });
174
+ });
175
+
176
+ test("should parse custom tag", () => {
177
+ const result = EntityTag.parseByName("release-2024");
178
+ expect(result).toEqual({
179
+ name: "release-2024",
180
+ prefix: "release-",
181
+ format: "custom",
182
+ });
183
+ });
184
+
185
+ test("should handle empty tag name", () => {
186
+ const result = EntityTag.parseByName("");
187
+ expect(result).toEqual({
188
+ name: "",
189
+ prefix: undefined,
190
+ format: undefined,
191
+ });
192
+ });
193
+ });
194
+
195
+ describe("utility methods", () => {
196
+ describe("detectFormat", () => {
197
+ test("should detect semver format", () => {
198
+ expect(EntityTag.detectFormat("v1.0.0")).toBe("semver");
199
+ expect(EntityTag.detectFormat("1.0.0")).toBe("semver");
200
+ });
201
+
202
+ test("should detect calver format", () => {
203
+ expect(EntityTag.detectFormat("2024.01.01")).toBe("semver");
204
+ expect(EntityTag.detectFormat("2024.12.25")).toBe("semver");
205
+ });
206
+
207
+ test("should detect custom format", () => {
208
+ expect(EntityTag.detectFormat("release-2024")).toBe("custom");
209
+ expect(EntityTag.detectFormat("beta-v1")).toBe("custom");
210
+ });
211
+
212
+ test("should return undefined for empty tag", () => {
213
+ expect(EntityTag.detectFormat("")).toBeFalsy();
214
+ });
215
+ });
216
+
217
+ describe("detectPrefix", () => {
218
+ test("should detect v prefix", () => {
219
+ expect(EntityTag.detectPrefix("v1.0.0")).toBe("v");
220
+ });
221
+
222
+ test("should detect package prefix", () => {
223
+ expect(EntityTag.detectPrefix("intershell-v1.0.0")).toBe("intershell-v");
224
+ });
225
+
226
+ test("should detect custom prefix", () => {
227
+ expect(EntityTag.detectPrefix("release-v1.0.0")).toBe("release-v");
228
+ });
229
+
230
+ test("should return undefined for numeric prefix", () => {
231
+ expect(EntityTag.detectPrefix("1.0.0")).toBeFalsy();
232
+ });
233
+
234
+ test("should return undefined for empty tag", () => {
235
+ expect(EntityTag.detectPrefix("")).toBeFalsy();
236
+ });
237
+ });
238
+
239
+ describe("getVersionFromTag", () => {
240
+ test("should extract version from v prefixed tag", () => {
241
+ expect(EntityTag.getVersionFromTag("v1.0.0")).toBe("1.0.0");
242
+ });
243
+
244
+ test("should extract version from package prefixed tag", () => {
245
+ expect(EntityTag.getVersionFromTag("intershell-v1.0.0")).toBe("1.0.0");
246
+ });
247
+
248
+ test("should return original tag when no prefix", () => {
249
+ expect(EntityTag.getVersionFromTag("1.0.0")).toBe("1.0.0");
250
+ });
251
+
252
+ test("should handle empty prefix", () => {
253
+ expect(EntityTag.getVersionFromTag("v1.0.0")).toBe("1.0.0");
254
+ });
255
+ });
256
+ });
257
+
258
+ describe.skip("validate", () => {
259
+ test("should validate valid tag name", () => {
260
+ // Mock config for this test
261
+ mock.module("../config/config", () => ({
262
+ entitiesConfig: {
263
+ getConfig: () => ({
264
+ tag: {
265
+ name: {
266
+ enabled: true,
267
+ minLength: 1,
268
+ maxLength: 100,
269
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
270
+ noSpaces: true,
271
+ noSpecialChars: false,
272
+ },
273
+ },
274
+ }),
275
+ },
276
+ }));
277
+
278
+ const result = EntityTag.validate("v1.0.0");
279
+ expect(result.isValid).toBe(true);
280
+ expect(result.errors).toEqual([]);
281
+
282
+ // Restore the mock after the test
283
+ mock.restore();
284
+ });
285
+
286
+ test("should validate parsed tag object", () => {
287
+ // Mock config for this test
288
+ mock.module("../config/config", () => ({
289
+ entitiesConfig: {
290
+ getConfig: () => ({
291
+ tag: {
292
+ name: {
293
+ enabled: true,
294
+ minLength: 1,
295
+ maxLength: 100,
296
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
297
+ noSpaces: true,
298
+ noSpecialChars: false,
299
+ },
300
+ },
301
+ }),
302
+ },
303
+ }));
304
+
305
+ const parsedTag = EntityTag.parseByName("v1.0.0");
306
+ const result = EntityTag.validate(parsedTag);
307
+ expect(result.isValid).toBe(true);
308
+ expect(result.errors).toEqual([]);
309
+
310
+ // Restore the mock after the test
311
+ mock.restore();
312
+ });
313
+
314
+ test("should fail validation for tag name too short", async () => {
315
+ // Mock config with higher minLength
316
+ mock.module("../config/config", () => ({
317
+ entitiesConfig: {
318
+ getConfig: () => ({
319
+ tag: {
320
+ name: {
321
+ enabled: true,
322
+ minLength: 5,
323
+ maxLength: 100,
324
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
325
+ noSpaces: true,
326
+ noSpecialChars: true,
327
+ },
328
+ },
329
+ }),
330
+ },
331
+ }));
332
+
333
+ const result = EntityTag.validate("v1.0");
334
+ expect(result.isValid).toBe(false);
335
+ expect(result.errors).toContain("tag name should be at least 5 characters long");
336
+
337
+ // Restore the mock after the test
338
+ mock.restore();
339
+ });
340
+
341
+ test("should fail validation for tag name too long", async () => {
342
+ // Mock config with lower maxLength
343
+ mock.module("../config/config", () => ({
344
+ entitiesConfig: {
345
+ getConfig: () => ({
346
+ tag: {
347
+ name: {
348
+ enabled: true,
349
+ minLength: 1,
350
+ maxLength: 5,
351
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
352
+ noSpaces: true,
353
+ noSpecialChars: true,
354
+ },
355
+ },
356
+ }),
357
+ },
358
+ }));
359
+
360
+ const result = EntityTag.validate("very-long-tag-name");
361
+ expect(result.isValid).toBe(false);
362
+ expect(result.errors).toContain("tag name should be max 5 characters, received: 18");
363
+
364
+ // Restore the mock after the test
365
+ mock.restore();
366
+ });
367
+
368
+ test("should fail validation for invalid characters", async () => {
369
+ // Mock config with strict allowed characters
370
+ mock.module("../config/config", () => ({
371
+ entitiesConfig: {
372
+ getConfig: () => ({
373
+ tag: {
374
+ name: {
375
+ enabled: true,
376
+ minLength: 1,
377
+ maxLength: 100,
378
+ allowedCharacters: /^[a-zA-Z0-9]+$/,
379
+ noSpaces: true,
380
+ noSpecialChars: true,
381
+ },
382
+ },
383
+ }),
384
+ },
385
+ }));
386
+
387
+ const result = EntityTag.validate("v1.0.0");
388
+ expect(result.isValid).toBe(false);
389
+ expect(result.errors).toContain(
390
+ "tag name contains invalid characters. allowed: ^[a-zA-Z0-9]+$",
391
+ );
392
+
393
+ // Restore the mock after the test
394
+ mock.restore();
395
+ });
396
+
397
+ test("should fail validation for spaces when noSpaces is true", async () => {
398
+ // Mock config with noSpaces enabled
399
+ mock.module("../config/config", () => ({
400
+ entitiesConfig: {
401
+ getConfig: () => ({
402
+ tag: {
403
+ name: {
404
+ enabled: true,
405
+ minLength: 1,
406
+ maxLength: 100,
407
+ allowedCharacters: /^[a-zA-Z0-9\-_.\s]+$/,
408
+ noSpaces: true,
409
+ noSpecialChars: true,
410
+ },
411
+ },
412
+ }),
413
+ },
414
+ }));
415
+
416
+ const result = EntityTag.validate("v 1.0.0");
417
+ expect(result.isValid).toBe(false);
418
+ expect(result.errors).toContain("tag name should not contain spaces");
419
+
420
+ // Restore the mock after the test
421
+ mock.restore();
422
+ });
423
+
424
+ test("should fail validation for special characters when noSpecialChars is true", async () => {
425
+ // Mock config with noSpecialChars enabled
426
+ mock.module("../config/config", () => ({
427
+ entitiesConfig: {
428
+ getConfig: () => ({
429
+ tag: {
430
+ name: {
431
+ enabled: true,
432
+ minLength: 1,
433
+ maxLength: 100,
434
+ allowedCharacters: /^[a-zA-Z0-9\-_.!@#$%^&*()]+$/,
435
+ noSpaces: true,
436
+ noSpecialChars: true,
437
+ },
438
+ },
439
+ }),
440
+ },
441
+ }));
442
+
443
+ const result = EntityTag.validate("v1.0.0!");
444
+ expect(result.isValid).toBe(false);
445
+ expect(result.errors).toContain("tag name should not contain special characters");
446
+
447
+ // Restore the mock after the test
448
+ mock.restore();
449
+ });
450
+
451
+ test("should pass validation when name validation is disabled", async () => {
452
+ // Mock config with name validation disabled
453
+ mock.module("../config/config", () => ({
454
+ entitiesConfig: {
455
+ getConfig: () => ({
456
+ tag: {
457
+ name: {
458
+ enabled: false,
459
+ minLength: 1,
460
+ maxLength: 100,
461
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
462
+ noSpaces: true,
463
+ noSpecialChars: true,
464
+ },
465
+ },
466
+ }),
467
+ },
468
+ }));
469
+
470
+ const result = EntityTag.validate("invalid@tag#name");
471
+ expect(result.isValid).toBe(true);
472
+ expect(result.errors).toEqual([]);
473
+
474
+ // Restore the mock after the test
475
+ mock.restore();
476
+ });
477
+ });
478
+
479
+ describe.skip("Git operations", () => {
480
+ describe("listTags", () => {
481
+ test("should return list of tags with prefix", async () => {
482
+ const result = await EntityTag.listTags("v");
483
+ expect(result).toEqual(["v1.0.0", "v1.1.0", "intershell-v1.0.0"]);
484
+ });
485
+
486
+ test("should handle empty tag list", async () => {
487
+ const { entitiesShell } = await import("../entities.shell");
488
+ entitiesShell.gitTagList = mock(
489
+ () =>
490
+ ({
491
+ exitCode: 0,
492
+ text: () => "",
493
+ }) as unknown as $.ShellPromise,
494
+ );
495
+
496
+ const result = await EntityTag.listTags("nonexistent");
497
+ expect(result).toEqual([]);
498
+ });
499
+
500
+ test("should filter out empty lines", async () => {
501
+ const { entitiesShell } = await import("../entities.shell");
502
+ entitiesShell.gitTagList = mock(
503
+ () =>
504
+ ({
505
+ exitCode: 0,
506
+ text: () => ["v1.0.0", "", "v1.1.0", " ", "v1.2.0"].join("\n"),
507
+ }) as unknown as $.ShellPromise,
508
+ );
509
+
510
+ const result = await EntityTag.listTags("v");
511
+ expect(result).toEqual(["v1.0.0", "v1.1.0", " ", "v1.2.0"]);
512
+ });
513
+ });
514
+
515
+ describe("getLatestTag", () => {
516
+ test("should return latest tag for prefix", async () => {
517
+ const result = await EntityTag.getLatestTag("v");
518
+ expect(result).toBe("v1.1.0");
519
+ });
520
+
521
+ test("should return null for empty tag", async () => {
522
+ const { entitiesShell } = await import("../entities.shell");
523
+ entitiesShell.gitTagLatest = mock(
524
+ () =>
525
+ ({
526
+ exitCode: 0,
527
+ text: () => "",
528
+ }) as unknown as $.ShellPromise,
529
+ );
530
+
531
+ const result = await EntityTag.getLatestTag("nonexistent");
532
+ expect(result).toBe(null);
533
+ });
534
+
535
+ test("should throw error when git command fails", async () => {
536
+ const { entitiesShell } = await import("../entities.shell");
537
+ entitiesShell.gitTagLatest = mock(
538
+ () =>
539
+ ({
540
+ exitCode: 1,
541
+ text: () => "error",
542
+ }) as unknown as $.ShellPromise,
543
+ );
544
+
545
+ await expect(EntityTag.getLatestTag("invalid")).rejects.toThrow(
546
+ "Could not get latest tag for pattern invalid",
547
+ );
548
+ });
549
+ });
550
+
551
+ describe("getTagSha", () => {
552
+ test("should return tag SHA", async () => {
553
+ const result = await EntityTag.getTagSha("v1.0.0");
554
+ expect(result).toBe("abc123");
555
+ });
556
+
557
+ test("should throw error when tag not found", async () => {
558
+ const { entitiesShell } = await import("../entities.shell");
559
+ entitiesShell.gitRevParse = mock(
560
+ () =>
561
+ ({
562
+ exitCode: 1,
563
+ text: () => "error",
564
+ }) as unknown as $.ShellPromise,
565
+ );
566
+
567
+ await expect(EntityTag.getTagSha("nonexistent")).rejects.toThrow(
568
+ "Tag nonexistent not found",
569
+ );
570
+ });
571
+ });
572
+
573
+ describe("tagExists", () => {
574
+ test("should return true when tag exists", async () => {
575
+ const result = await EntityTag.tagExists("v1.0.0");
576
+ expect(result).toBe(true);
577
+ });
578
+
579
+ test("should return false when tag does not exist", async () => {
580
+ const { entitiesShell } = await import("../entities.shell");
581
+ entitiesShell.gitTagExists = mock(
582
+ () =>
583
+ ({
584
+ exitCode: 1,
585
+ text: () => "",
586
+ }) as unknown as $.ShellPromise,
587
+ );
588
+
589
+ const result = await EntityTag.tagExists("nonexistent");
590
+ expect(result).toBe(false);
591
+ });
592
+
593
+ test("should return false when tag name doesn't match", async () => {
594
+ const { entitiesShell } = await import("../entities.shell");
595
+ entitiesShell.gitTagExists = mock(
596
+ () =>
597
+ ({
598
+ exitCode: 0,
599
+ text: () => "different-tag",
600
+ }) as unknown as $.ShellPromise,
601
+ );
602
+
603
+ const result = await EntityTag.tagExists("v1.0.0");
604
+ expect(result).toBe(false);
605
+ });
606
+ });
607
+ });
608
+
609
+ describe.skip("createTag", () => {
610
+ test("should create tag successfully", async () => {
611
+ // This test verifies the createTag method exists and can be called
612
+ // The actual implementation will be tested in integration tests
613
+ expect(typeof EntityTag.createTag).toBe("function");
614
+ expect(EntityTag.createTag.length).toBe(2); // tagName, message (options has default value)
615
+ });
616
+
617
+ test("should create tag with force option", () => {
618
+ // This test verifies the createTag method accepts force option
619
+ expect(typeof EntityTag.createTag).toBe("function");
620
+ });
621
+
622
+ test("should create tag and push when push option is true", () => {
623
+ // This test verifies the createTag method accepts push option
624
+ expect(typeof EntityTag.createTag).toBe("function");
625
+ });
626
+
627
+ test("should throw error when tag already exists without force", async () => {
628
+ const { entitiesShell } = await import("../entities.shell");
629
+ entitiesShell.gitTagExists = mock(
630
+ () =>
631
+ ({
632
+ exitCode: 0,
633
+ text: () => "v1.0.0",
634
+ }) as unknown as $.ShellPromise,
635
+ );
636
+
637
+ await expect(EntityTag.createTag("v1.0.0", "Test tag")).rejects.toThrow(
638
+ "Tag v1.0.0 already exists, use --force to override",
639
+ );
640
+ });
641
+
642
+ test("should throw error when tag validation fails", async () => {
643
+ const { entitiesShell } = await import("../entities.shell");
644
+ entitiesShell.gitTagExists = mock(
645
+ () =>
646
+ ({
647
+ exitCode: 1,
648
+ text: () => "",
649
+ }) as unknown as $.ShellPromise,
650
+ );
651
+
652
+ // Mock config with strict validation
653
+ mock.module("../config/config", () => ({
654
+ entitiesConfig: {
655
+ getConfig: () => ({
656
+ tag: {
657
+ name: {
658
+ enabled: true,
659
+ minLength: 10,
660
+ maxLength: 100,
661
+ allowedCharacters: /^[a-zA-Z0-9\-_.]+$/,
662
+ noSpaces: true,
663
+ noSpecialChars: true,
664
+ },
665
+ },
666
+ }),
667
+ },
668
+ }));
669
+
670
+ await expect(EntityTag.createTag("v1.0.0", "Test tag")).rejects.toThrow(
671
+ "Tag v1.0.0 is invalid: tag name should be at least 10 characters long",
672
+ );
673
+ });
674
+
675
+ test("should throw error when git tag command fails", () => {
676
+ // This test verifies error handling exists
677
+ expect(typeof EntityTag.createTag).toBe("function");
678
+ });
679
+
680
+ test("should throw error when push fails", () => {
681
+ // This test verifies error handling exists
682
+ expect(typeof EntityTag.createTag).toBe("function");
683
+ });
684
+ });
685
+
686
+ describe.skip("deleteTag", () => {
687
+ test("should delete tag successfully", () => {
688
+ // This test verifies the deleteTag method exists
689
+ expect(typeof EntityTag.deleteTag).toBe("function");
690
+ expect(EntityTag.deleteTag.length).toBe(1); // tagName (deleteRemote has default value)
691
+ });
692
+
693
+ test("should delete tag and remote when deleteRemote is true", () => {
694
+ // This test verifies the deleteTag method accepts deleteRemote parameter
695
+ expect(typeof EntityTag.deleteTag).toBe("function");
696
+ });
697
+
698
+ test("should throw error when tag does not exist", async () => {
699
+ const { entitiesShell } = await import("../entities.shell");
700
+ entitiesShell.gitTagExists = mock(
701
+ () =>
702
+ ({
703
+ exitCode: 1,
704
+ text: () => "",
705
+ }) as unknown as $.ShellPromise,
706
+ );
707
+
708
+ await expect(EntityTag.deleteTag("nonexistent")).rejects.toThrow(
709
+ "Tag nonexistent does not exist",
710
+ );
711
+ });
712
+
713
+ test("should throw error when git delete command fails", async () => {
714
+ const { entitiesShell } = await import("../entities.shell");
715
+ entitiesShell.gitTagExists = mock(
716
+ () =>
717
+ ({
718
+ exitCode: 0,
719
+ text: () => "v1.0.0",
720
+ }) as unknown as $.ShellPromise,
721
+ );
722
+ entitiesShell.gitDeleteTag = mock(
723
+ () => Promise.reject(new Error("Delete error")) as unknown as $.ShellPromise,
724
+ );
725
+
726
+ await expect(EntityTag.deleteTag("v1.0.0")).rejects.toThrow(
727
+ "Failed to delete tag v1.0.0: Delete error",
728
+ );
729
+ });
730
+
731
+ test("should throw error when remote delete fails", async () => {
732
+ const { entitiesShell } = await import("../entities.shell");
733
+ entitiesShell.gitTagExists = mock(
734
+ () =>
735
+ ({
736
+ exitCode: 0,
737
+ text: () => "v1.0.0",
738
+ }) as unknown as $.ShellPromise,
739
+ );
740
+ entitiesShell.gitPushTag = mock(
741
+ () => Promise.reject(new Error("Remote delete error")) as unknown as $.ShellPromise,
742
+ );
743
+
744
+ await expect(EntityTag.deleteTag("v1.0.0", true)).rejects.toThrow(
745
+ "Failed to delete remote tag v1.0.0: Remote delete error",
746
+ );
747
+ });
748
+ });
749
+
750
+ describe.skip("getTagInfo", () => {
751
+ test("should return tag info successfully", async () => {
752
+ const result = await EntityTag.getTagInfo("v1.0.0");
753
+ expect(result).toEqual({
754
+ date: "2024-01-01T00:00:00Z",
755
+ message: "test message",
756
+ });
757
+ });
758
+
759
+ test("should throw error when tag info cannot be retrieved", async () => {
760
+ const { entitiesShell } = await import("../entities.shell");
761
+ entitiesShell.gitTagInfo = mock(
762
+ () =>
763
+ ({
764
+ exitCode: 1,
765
+ text: () => "error",
766
+ }) as unknown as $.ShellPromise,
767
+ );
768
+
769
+ await expect(EntityTag.getTagInfo("nonexistent")).rejects.toThrow(
770
+ "Could not get info for tag nonexistent",
771
+ );
772
+ });
773
+
774
+ test("should throw error when tag info has insufficient data", async () => {
775
+ const { entitiesShell } = await import("../entities.shell");
776
+ entitiesShell.gitTagInfo = mock(
777
+ () =>
778
+ ({
779
+ exitCode: 0,
780
+ text: () => "2024-01-01T00:00:00Z", // Only one line
781
+ }) as unknown as $.ShellPromise,
782
+ );
783
+
784
+ await expect(EntityTag.getTagInfo("v1.0.0")).rejects.toThrow(
785
+ "Could not get info for tag v1.0.0",
786
+ );
787
+ });
788
+
789
+ test("should handle undefined text function", async () => {
790
+ const { entitiesShell } = await import("../entities.shell");
791
+ entitiesShell.gitTagInfo = mock(
792
+ () =>
793
+ ({
794
+ exitCode: 0,
795
+ text: undefined,
796
+ }) as unknown as $.ShellPromise,
797
+ );
798
+
799
+ await expect(EntityTag.getTagInfo("v1.0.0")).rejects.toThrow(
800
+ "Could not get info for tag v1.0.0",
801
+ );
802
+ });
803
+ });
804
+
805
+ describe.skip("getBaseCommitSha", () => {
806
+ test("should return SHA for provided reference", async () => {
807
+ const result = await EntityTag.getBaseCommitSha("v1.0.0");
808
+ expect(result).toBe("abc123");
809
+ });
810
+
811
+ test("should return first commit SHA when no reference provided", async () => {
812
+ const result = await EntityTag.getBaseCommitSha();
813
+ expect(result).toBe("first123");
814
+ });
815
+
816
+ test("should throw error when reference is invalid", async () => {
817
+ const { entitiesShell } = await import("../entities.shell");
818
+ entitiesShell.gitRevParse = mock(
819
+ () =>
820
+ ({
821
+ exitCode: 1,
822
+ text: () => "error",
823
+ }) as unknown as $.ShellPromise,
824
+ );
825
+
826
+ await expect(EntityTag.getBaseCommitSha("invalid-ref")).rejects.toThrow(
827
+ "Invalid reference: invalid-ref. Not found as tag, branch, or commit.",
828
+ );
829
+ });
830
+
831
+ test("should throw error when first commit cannot be found", async () => {
832
+ const { entitiesShell } = await import("../entities.shell");
833
+ entitiesShell.gitFirstCommit = mock(
834
+ () =>
835
+ ({
836
+ exitCode: 1,
837
+ text: () => "error",
838
+ }) as unknown as $.ShellPromise,
839
+ );
840
+
841
+ await expect(EntityTag.getBaseCommitSha()).rejects.toThrow("Could not find first commit");
842
+ });
843
+ });
844
+ });