bupkis 0.18.3 → 1.0.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 (388) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/dist/assertion/assertion-async.cjs +268 -0
  4. package/dist/assertion/assertion-async.cjs.map +1 -0
  5. package/dist/assertion/assertion-async.d.cts +40 -0
  6. package/dist/assertion/assertion-async.d.cts.map +1 -0
  7. package/dist/assertion/assertion-async.d.ts +40 -0
  8. package/dist/assertion/assertion-async.d.ts.map +1 -0
  9. package/dist/assertion/assertion-async.js +259 -0
  10. package/dist/assertion/assertion-async.js.map +1 -0
  11. package/dist/assertion/assertion-standard-schema-async.cjs +132 -0
  12. package/dist/assertion/assertion-standard-schema-async.cjs.map +1 -0
  13. package/dist/assertion/assertion-standard-schema-async.d.cts +52 -0
  14. package/dist/assertion/assertion-standard-schema-async.d.cts.map +1 -0
  15. package/dist/assertion/assertion-standard-schema-async.d.ts +52 -0
  16. package/dist/assertion/assertion-standard-schema-async.d.ts.map +1 -0
  17. package/dist/assertion/assertion-standard-schema-async.js +128 -0
  18. package/dist/assertion/assertion-standard-schema-async.js.map +1 -0
  19. package/dist/assertion/assertion-standard-schema-sync.cjs +141 -0
  20. package/dist/assertion/assertion-standard-schema-sync.cjs.map +1 -0
  21. package/dist/assertion/assertion-standard-schema-sync.d.cts +52 -0
  22. package/dist/assertion/assertion-standard-schema-sync.d.cts.map +1 -0
  23. package/dist/assertion/assertion-standard-schema-sync.d.ts +52 -0
  24. package/dist/assertion/assertion-standard-schema-sync.d.ts.map +1 -0
  25. package/dist/assertion/assertion-standard-schema-sync.js +137 -0
  26. package/dist/assertion/assertion-standard-schema-sync.js.map +1 -0
  27. package/dist/assertion/assertion-sync.cjs +281 -0
  28. package/dist/assertion/assertion-sync.cjs.map +1 -0
  29. package/dist/assertion/assertion-sync.d.cts +60 -0
  30. package/dist/assertion/assertion-sync.d.cts.map +1 -0
  31. package/dist/assertion/assertion-sync.d.ts +60 -0
  32. package/dist/assertion/assertion-sync.d.ts.map +1 -0
  33. package/dist/assertion/assertion-sync.js +275 -0
  34. package/dist/assertion/assertion-sync.js.map +1 -0
  35. package/dist/assertion/assertion-types.cjs +20 -0
  36. package/dist/assertion/assertion-types.cjs.map +1 -0
  37. package/dist/assertion/assertion-types.d.cts +1086 -0
  38. package/dist/assertion/assertion-types.d.cts.map +1 -0
  39. package/dist/assertion/assertion-types.d.ts +1086 -0
  40. package/dist/assertion/assertion-types.d.ts.map +1 -0
  41. package/dist/assertion/assertion-types.js +19 -0
  42. package/dist/assertion/assertion-types.js.map +1 -0
  43. package/dist/assertion/assertion.cjs +382 -0
  44. package/dist/assertion/assertion.cjs.map +1 -0
  45. package/dist/assertion/assertion.d.cts +109 -0
  46. package/dist/assertion/assertion.d.cts.map +1 -0
  47. package/dist/assertion/assertion.d.ts +109 -0
  48. package/dist/assertion/assertion.d.ts.map +1 -0
  49. package/dist/assertion/assertion.js +375 -0
  50. package/dist/assertion/assertion.js.map +1 -0
  51. package/dist/assertion/create.cjs +148 -0
  52. package/dist/assertion/create.cjs.map +1 -0
  53. package/dist/assertion/create.d.cts +85 -0
  54. package/dist/assertion/create.d.cts.map +1 -0
  55. package/dist/assertion/create.d.ts +85 -0
  56. package/dist/assertion/create.d.ts.map +1 -0
  57. package/dist/assertion/create.js +143 -0
  58. package/dist/assertion/create.js.map +1 -0
  59. package/dist/assertion/format-assertion-failure.cjs +63 -0
  60. package/dist/assertion/format-assertion-failure.cjs.map +1 -0
  61. package/dist/assertion/format-assertion-failure.d.cts +21 -0
  62. package/dist/assertion/format-assertion-failure.d.cts.map +1 -0
  63. package/dist/assertion/format-assertion-failure.d.ts +21 -0
  64. package/dist/assertion/format-assertion-failure.d.ts.map +1 -0
  65. package/dist/assertion/format-assertion-failure.js +59 -0
  66. package/dist/assertion/format-assertion-failure.js.map +1 -0
  67. package/dist/assertion/impl/assertion-util.cjs +68 -0
  68. package/dist/assertion/impl/assertion-util.cjs.map +1 -0
  69. package/dist/assertion/impl/assertion-util.d.cts +36 -0
  70. package/dist/assertion/impl/assertion-util.d.cts.map +1 -0
  71. package/dist/assertion/impl/assertion-util.d.ts +36 -0
  72. package/dist/assertion/impl/assertion-util.d.ts.map +1 -0
  73. package/dist/assertion/impl/assertion-util.js +62 -0
  74. package/dist/assertion/impl/assertion-util.js.map +1 -0
  75. package/dist/assertion/impl/async-iterable.cjs +627 -0
  76. package/dist/assertion/impl/async-iterable.cjs.map +1 -0
  77. package/dist/assertion/impl/async-iterable.d.cts +406 -0
  78. package/dist/assertion/impl/async-iterable.d.cts.map +1 -0
  79. package/dist/assertion/impl/async-iterable.d.ts +406 -0
  80. package/dist/assertion/impl/async-iterable.d.ts.map +1 -0
  81. package/dist/assertion/impl/async-iterable.js +624 -0
  82. package/dist/assertion/impl/async-iterable.js.map +1 -0
  83. package/dist/assertion/impl/async-parametric.cjs +412 -0
  84. package/dist/assertion/impl/async-parametric.cjs.map +1 -0
  85. package/dist/assertion/impl/async-parametric.d.cts +278 -0
  86. package/dist/assertion/impl/async-parametric.d.cts.map +1 -0
  87. package/dist/assertion/impl/async-parametric.d.ts +278 -0
  88. package/dist/assertion/impl/async-parametric.d.ts.map +1 -0
  89. package/dist/assertion/impl/async-parametric.js +409 -0
  90. package/dist/assertion/impl/async-parametric.js.map +1 -0
  91. package/dist/assertion/impl/async.cjs +56 -0
  92. package/dist/assertion/impl/async.cjs.map +1 -0
  93. package/dist/assertion/impl/async.d.cts +179 -0
  94. package/dist/assertion/impl/async.d.cts.map +1 -0
  95. package/dist/assertion/impl/async.d.ts +179 -0
  96. package/dist/assertion/impl/async.d.ts.map +1 -0
  97. package/dist/assertion/impl/async.js +39 -0
  98. package/dist/assertion/impl/async.js.map +1 -0
  99. package/dist/assertion/impl/index.cjs +37 -0
  100. package/dist/assertion/impl/index.cjs.map +1 -0
  101. package/dist/assertion/impl/index.d.cts +21 -0
  102. package/dist/assertion/impl/index.d.cts.map +1 -0
  103. package/dist/assertion/impl/index.d.ts +21 -0
  104. package/dist/assertion/impl/index.d.ts.map +1 -0
  105. package/dist/assertion/impl/index.js +21 -0
  106. package/dist/assertion/impl/index.js.map +1 -0
  107. package/dist/assertion/impl/iteration-util.cjs +297 -0
  108. package/dist/assertion/impl/iteration-util.cjs.map +1 -0
  109. package/dist/assertion/impl/iteration-util.d.cts +12 -0
  110. package/dist/assertion/impl/iteration-util.d.cts.map +1 -0
  111. package/dist/assertion/impl/iteration-util.d.ts +12 -0
  112. package/dist/assertion/impl/iteration-util.d.ts.map +1 -0
  113. package/dist/assertion/impl/iteration-util.js +282 -0
  114. package/dist/assertion/impl/iteration-util.js.map +1 -0
  115. package/dist/assertion/impl/snapshot.cjs +276 -0
  116. package/dist/assertion/impl/snapshot.cjs.map +1 -0
  117. package/dist/assertion/impl/snapshot.d.cts +278 -0
  118. package/dist/assertion/impl/snapshot.d.cts.map +1 -0
  119. package/dist/assertion/impl/snapshot.d.ts +278 -0
  120. package/dist/assertion/impl/snapshot.d.ts.map +1 -0
  121. package/dist/assertion/impl/snapshot.js +273 -0
  122. package/dist/assertion/impl/snapshot.js.map +1 -0
  123. package/dist/assertion/impl/sync-basic.cjs +553 -0
  124. package/dist/assertion/impl/sync-basic.cjs.map +1 -0
  125. package/dist/assertion/impl/sync-basic.d.cts +528 -0
  126. package/dist/assertion/impl/sync-basic.d.cts.map +1 -0
  127. package/dist/assertion/impl/sync-basic.d.ts +528 -0
  128. package/dist/assertion/impl/sync-basic.d.ts.map +1 -0
  129. package/dist/assertion/impl/sync-basic.js +550 -0
  130. package/dist/assertion/impl/sync-basic.js.map +1 -0
  131. package/dist/assertion/impl/sync-collection.cjs +1424 -0
  132. package/dist/assertion/impl/sync-collection.cjs.map +1 -0
  133. package/dist/assertion/impl/sync-collection.d.cts +922 -0
  134. package/dist/assertion/impl/sync-collection.d.cts.map +1 -0
  135. package/dist/assertion/impl/sync-collection.d.ts +922 -0
  136. package/dist/assertion/impl/sync-collection.d.ts.map +1 -0
  137. package/dist/assertion/impl/sync-collection.js +1418 -0
  138. package/dist/assertion/impl/sync-collection.js.map +1 -0
  139. package/dist/assertion/impl/sync-date.cjs +341 -0
  140. package/dist/assertion/impl/sync-date.cjs.map +1 -0
  141. package/dist/assertion/impl/sync-date.d.cts +209 -0
  142. package/dist/assertion/impl/sync-date.d.cts.map +1 -0
  143. package/dist/assertion/impl/sync-date.d.ts +209 -0
  144. package/dist/assertion/impl/sync-date.d.ts.map +1 -0
  145. package/dist/assertion/impl/sync-date.js +338 -0
  146. package/dist/assertion/impl/sync-date.js.map +1 -0
  147. package/dist/assertion/impl/sync-esoteric.cjs +214 -0
  148. package/dist/assertion/impl/sync-esoteric.cjs.map +1 -0
  149. package/dist/assertion/impl/sync-esoteric.d.cts +191 -0
  150. package/dist/assertion/impl/sync-esoteric.d.cts.map +1 -0
  151. package/dist/assertion/impl/sync-esoteric.d.ts +191 -0
  152. package/dist/assertion/impl/sync-esoteric.d.ts.map +1 -0
  153. package/dist/assertion/impl/sync-esoteric.js +211 -0
  154. package/dist/assertion/impl/sync-esoteric.js.map +1 -0
  155. package/dist/assertion/impl/sync-iterable.cjs +512 -0
  156. package/dist/assertion/impl/sync-iterable.cjs.map +1 -0
  157. package/dist/assertion/impl/sync-iterable.d.cts +334 -0
  158. package/dist/assertion/impl/sync-iterable.d.cts.map +1 -0
  159. package/dist/assertion/impl/sync-iterable.d.ts +334 -0
  160. package/dist/assertion/impl/sync-iterable.d.ts.map +1 -0
  161. package/dist/assertion/impl/sync-iterable.js +509 -0
  162. package/dist/assertion/impl/sync-iterable.js.map +1 -0
  163. package/dist/assertion/impl/sync-parametric.cjs +805 -0
  164. package/dist/assertion/impl/sync-parametric.cjs.map +1 -0
  165. package/dist/assertion/impl/sync-parametric.d.cts +560 -0
  166. package/dist/assertion/impl/sync-parametric.d.cts.map +1 -0
  167. package/dist/assertion/impl/sync-parametric.d.ts +560 -0
  168. package/dist/assertion/impl/sync-parametric.d.ts.map +1 -0
  169. package/dist/assertion/impl/sync-parametric.js +802 -0
  170. package/dist/assertion/impl/sync-parametric.js.map +1 -0
  171. package/dist/assertion/impl/sync.cjs +229 -0
  172. package/dist/assertion/impl/sync.cjs.map +1 -0
  173. package/dist/assertion/impl/sync.d.cts +536 -0
  174. package/dist/assertion/impl/sync.d.cts.map +1 -0
  175. package/dist/assertion/impl/sync.d.ts +536 -0
  176. package/dist/assertion/impl/sync.d.ts.map +1 -0
  177. package/dist/assertion/impl/sync.js +212 -0
  178. package/dist/assertion/impl/sync.js.map +1 -0
  179. package/dist/assertion/index.cjs +38 -0
  180. package/dist/assertion/index.cjs.map +1 -0
  181. package/dist/assertion/index.d.cts +18 -0
  182. package/dist/assertion/index.d.cts.map +1 -0
  183. package/dist/assertion/index.d.ts +18 -0
  184. package/dist/assertion/index.d.ts.map +1 -0
  185. package/dist/assertion/index.js +17 -0
  186. package/dist/assertion/index.js.map +1 -0
  187. package/dist/assertion/slotify.cjs +165 -0
  188. package/dist/assertion/slotify.cjs.map +1 -0
  189. package/dist/assertion/slotify.d.cts +11 -0
  190. package/dist/assertion/slotify.d.cts.map +1 -0
  191. package/dist/assertion/slotify.d.ts +11 -0
  192. package/dist/assertion/slotify.d.ts.map +1 -0
  193. package/dist/assertion/slotify.js +161 -0
  194. package/dist/assertion/slotify.js.map +1 -0
  195. package/dist/bootstrap.cjs +43 -0
  196. package/dist/bootstrap.cjs.map +1 -0
  197. package/dist/bootstrap.d.cts +27 -0
  198. package/dist/bootstrap.d.cts.map +1 -0
  199. package/dist/bootstrap.d.ts +27 -0
  200. package/dist/bootstrap.d.ts.map +1 -0
  201. package/dist/bootstrap.js +40 -0
  202. package/dist/bootstrap.js.map +1 -0
  203. package/dist/constant.cjs +82 -0
  204. package/dist/constant.cjs.map +1 -0
  205. package/dist/constant.d.cts +69 -0
  206. package/dist/constant.d.cts.map +1 -0
  207. package/dist/constant.d.ts +69 -0
  208. package/dist/constant.d.ts.map +1 -0
  209. package/dist/constant.js +79 -0
  210. package/dist/constant.js.map +1 -0
  211. package/dist/diff.cjs +340 -0
  212. package/dist/diff.cjs.map +1 -0
  213. package/dist/diff.d.cts +51 -0
  214. package/dist/diff.d.cts.map +1 -0
  215. package/dist/diff.d.ts +51 -0
  216. package/dist/diff.d.ts.map +1 -0
  217. package/dist/diff.js +334 -0
  218. package/dist/diff.js.map +1 -0
  219. package/dist/error.cjs +194 -0
  220. package/dist/error.cjs.map +1 -0
  221. package/dist/error.d.cts +212 -0
  222. package/dist/error.d.cts.map +1 -0
  223. package/dist/error.d.ts +212 -0
  224. package/dist/error.d.ts.map +1 -0
  225. package/dist/error.js +181 -0
  226. package/dist/error.js.map +1 -0
  227. package/dist/expect.cjs +587 -0
  228. package/dist/expect.cjs.map +1 -0
  229. package/dist/expect.d.cts +138 -0
  230. package/dist/expect.d.cts.map +1 -0
  231. package/dist/expect.d.ts +138 -0
  232. package/dist/expect.d.ts.map +1 -0
  233. package/dist/expect.js +582 -0
  234. package/dist/expect.js.map +1 -0
  235. package/dist/guards.cjs +291 -0
  236. package/dist/guards.cjs.map +1 -0
  237. package/dist/guards.d.cts +225 -0
  238. package/dist/guards.d.cts.map +1 -0
  239. package/dist/guards.d.ts +225 -0
  240. package/dist/guards.d.ts.map +1 -0
  241. package/dist/guards.js +273 -0
  242. package/dist/guards.js.map +1 -0
  243. package/dist/index.cjs +111 -0
  244. package/dist/index.cjs.map +1 -0
  245. package/dist/index.d.cts +460 -0
  246. package/dist/index.d.cts.map +1 -0
  247. package/dist/index.d.ts +460 -0
  248. package/dist/index.d.ts.map +1 -0
  249. package/dist/index.js +71 -0
  250. package/dist/index.js.map +1 -0
  251. package/dist/internal-schema.cjs +234 -0
  252. package/dist/internal-schema.cjs.map +1 -0
  253. package/dist/internal-schema.d.cts +8 -0
  254. package/dist/internal-schema.d.cts.map +1 -0
  255. package/dist/internal-schema.d.ts +8 -0
  256. package/dist/internal-schema.d.ts.map +1 -0
  257. package/dist/internal-schema.js +229 -0
  258. package/dist/internal-schema.js.map +1 -0
  259. package/dist/metadata.cjs +57 -0
  260. package/dist/metadata.cjs.map +1 -0
  261. package/dist/metadata.d.cts +27 -0
  262. package/dist/metadata.d.cts.map +1 -0
  263. package/dist/metadata.d.ts +27 -0
  264. package/dist/metadata.d.ts.map +1 -0
  265. package/dist/metadata.js +54 -0
  266. package/dist/metadata.js.map +1 -0
  267. package/dist/schema.cjs +1522 -0
  268. package/dist/schema.cjs.map +1 -0
  269. package/dist/schema.d.cts +1196 -0
  270. package/dist/schema.d.cts.map +1 -0
  271. package/dist/schema.d.ts +1196 -0
  272. package/dist/schema.d.ts.map +1 -0
  273. package/dist/schema.js +1516 -0
  274. package/dist/schema.js.map +1 -0
  275. package/dist/snapshot/adapter.cjs +29 -0
  276. package/dist/snapshot/adapter.cjs.map +1 -0
  277. package/dist/snapshot/adapter.d.cts +258 -0
  278. package/dist/snapshot/adapter.d.cts.map +1 -0
  279. package/dist/snapshot/adapter.d.ts +258 -0
  280. package/dist/snapshot/adapter.d.ts.map +1 -0
  281. package/dist/snapshot/adapter.js +25 -0
  282. package/dist/snapshot/adapter.js.map +1 -0
  283. package/dist/snapshot/adapters/fallback.cjs +452 -0
  284. package/dist/snapshot/adapters/fallback.cjs.map +1 -0
  285. package/dist/snapshot/adapters/fallback.d.cts +185 -0
  286. package/dist/snapshot/adapters/fallback.d.cts.map +1 -0
  287. package/dist/snapshot/adapters/fallback.d.ts +185 -0
  288. package/dist/snapshot/adapters/fallback.d.ts.map +1 -0
  289. package/dist/snapshot/adapters/fallback.js +445 -0
  290. package/dist/snapshot/adapters/fallback.js.map +1 -0
  291. package/dist/snapshot/adapters/node-test.cjs +297 -0
  292. package/dist/snapshot/adapters/node-test.cjs.map +1 -0
  293. package/dist/snapshot/adapters/node-test.d.cts +131 -0
  294. package/dist/snapshot/adapters/node-test.d.cts.map +1 -0
  295. package/dist/snapshot/adapters/node-test.d.ts +131 -0
  296. package/dist/snapshot/adapters/node-test.d.ts.map +1 -0
  297. package/dist/snapshot/adapters/node-test.js +293 -0
  298. package/dist/snapshot/adapters/node-test.js.map +1 -0
  299. package/dist/snapshot/index.cjs +61 -0
  300. package/dist/snapshot/index.cjs.map +1 -0
  301. package/dist/snapshot/index.d.cts +40 -0
  302. package/dist/snapshot/index.d.cts.map +1 -0
  303. package/dist/snapshot/index.d.ts +40 -0
  304. package/dist/snapshot/index.d.ts.map +1 -0
  305. package/dist/snapshot/index.js +44 -0
  306. package/dist/snapshot/index.js.map +1 -0
  307. package/dist/snapshot/node-version.cjs +49 -0
  308. package/dist/snapshot/node-version.cjs.map +1 -0
  309. package/dist/snapshot/node-version.d.cts +34 -0
  310. package/dist/snapshot/node-version.d.cts.map +1 -0
  311. package/dist/snapshot/node-version.d.ts +34 -0
  312. package/dist/snapshot/node-version.d.ts.map +1 -0
  313. package/dist/snapshot/node-version.js +44 -0
  314. package/dist/snapshot/node-version.js.map +1 -0
  315. package/dist/snapshot/select-adapter.cjs +170 -0
  316. package/dist/snapshot/select-adapter.cjs.map +1 -0
  317. package/dist/snapshot/select-adapter.d.cts +128 -0
  318. package/dist/snapshot/select-adapter.d.cts.map +1 -0
  319. package/dist/snapshot/select-adapter.d.ts +128 -0
  320. package/dist/snapshot/select-adapter.d.ts.map +1 -0
  321. package/dist/snapshot/select-adapter.js +164 -0
  322. package/dist/snapshot/select-adapter.js.map +1 -0
  323. package/dist/snapshot/serializer.cjs +245 -0
  324. package/dist/snapshot/serializer.cjs.map +1 -0
  325. package/dist/snapshot/serializer.d.cts +126 -0
  326. package/dist/snapshot/serializer.d.cts.map +1 -0
  327. package/dist/snapshot/serializer.d.ts +126 -0
  328. package/dist/snapshot/serializer.d.ts.map +1 -0
  329. package/dist/snapshot/serializer.js +237 -0
  330. package/dist/snapshot/serializer.js.map +1 -0
  331. package/dist/standard-schema.cjs +13 -0
  332. package/dist/standard-schema.cjs.map +1 -0
  333. package/dist/standard-schema.d.cts +192 -0
  334. package/dist/standard-schema.d.cts.map +1 -0
  335. package/dist/standard-schema.d.ts +192 -0
  336. package/dist/standard-schema.d.ts.map +1 -0
  337. package/dist/standard-schema.js +12 -0
  338. package/dist/standard-schema.js.map +1 -0
  339. package/dist/types.cjs +22 -0
  340. package/dist/types.cjs.map +1 -0
  341. package/dist/types.d.cts +756 -0
  342. package/dist/types.d.cts.map +1 -0
  343. package/dist/types.d.ts +756 -0
  344. package/dist/types.d.ts.map +1 -0
  345. package/dist/types.js +21 -0
  346. package/dist/types.js.map +1 -0
  347. package/dist/use.cjs +240 -0
  348. package/dist/use.cjs.map +1 -0
  349. package/dist/use.d.cts +8 -0
  350. package/dist/use.d.cts.map +1 -0
  351. package/dist/use.d.ts +8 -0
  352. package/dist/use.d.ts.map +1 -0
  353. package/dist/use.js +236 -0
  354. package/dist/use.js.map +1 -0
  355. package/dist/util.cjs +255 -0
  356. package/dist/util.cjs.map +1 -0
  357. package/dist/util.d.cts +141 -0
  358. package/dist/util.d.cts.map +1 -0
  359. package/dist/util.d.ts +141 -0
  360. package/dist/util.d.ts.map +1 -0
  361. package/dist/util.js +234 -0
  362. package/dist/util.js.map +1 -0
  363. package/dist/value-to-schema.cjs +537 -0
  364. package/dist/value-to-schema.cjs.map +1 -0
  365. package/dist/value-to-schema.d.cts +144 -0
  366. package/dist/value-to-schema.d.cts.map +1 -0
  367. package/dist/value-to-schema.d.ts +144 -0
  368. package/dist/value-to-schema.d.ts.map +1 -0
  369. package/dist/value-to-schema.js +533 -0
  370. package/dist/value-to-schema.js.map +1 -0
  371. package/package.json +22 -19
  372. package/src/assertion/assertion-types.ts +4 -8
  373. package/src/assertion/assertion.ts +1 -1
  374. package/src/assertion/format-assertion-failure.ts +2 -0
  375. package/src/assertion/impl/assertion-util.ts +1 -2
  376. package/src/assertion/impl/iteration-util.ts +1 -3
  377. package/src/assertion/impl/sync-collection.ts +633 -7
  378. package/src/assertion/impl/sync.ts +27 -0
  379. package/src/error.ts +13 -22
  380. package/src/guards.ts +8 -14
  381. package/src/internal-schema.ts +4 -8
  382. package/src/metadata.ts +1 -2
  383. package/src/snapshot/adapter.ts +2 -3
  384. package/src/snapshot/adapters/fallback.ts +2 -3
  385. package/src/snapshot/adapters/node-test.ts +14 -20
  386. package/src/snapshot/select-adapter.ts +3 -3
  387. package/src/snapshot/serializer.ts +2 -3
  388. package/src/types.ts +2 -162
@@ -14,6 +14,7 @@
14
14
  *
15
15
  * @showGroup
16
16
  */
17
+ import { inspect } from 'node:util';
17
18
  import setDifference from 'set.prototype.difference';
18
19
  import setIntersection from 'set.prototype.intersection';
19
20
  import isDisjointFrom from 'set.prototype.isdisjointfrom';
@@ -40,6 +41,7 @@ import {
40
41
  import { has } from '../../util.js';
41
42
  import {
42
43
  valueToSchema,
44
+ valueToSchemaOptionsForDeepEqual,
43
45
  valueToSchemaOptionsForSatisfies,
44
46
  } from '../../value-to-schema.js';
45
47
  import { createAssertion } from '../create.js';
@@ -83,8 +85,6 @@ export const mapContainsAssertion = createAssertion(
83
85
  }
84
86
  if (!hasKey) {
85
87
  return {
86
- actual: key,
87
- expected: `key to exist in ${subject.constructor.name}`,
88
88
  message: `Expected ${subject.constructor.name} to contain key`,
89
89
  };
90
90
  }
@@ -174,8 +174,6 @@ export const setContainsAssertion = createAssertion(
174
174
  : subject.has(value);
175
175
  if (!hasValue) {
176
176
  return {
177
- actual: value,
178
- expected: `value to exist in ${subject.constructor.name}`,
179
177
  message: `Expected ${subject.constructor.name} to contain value`,
180
178
  };
181
179
  }
@@ -542,9 +540,8 @@ export const objectSizeAssertion = createAssertion(
542
540
  */
543
541
  export const setEqualityAssertion = createAssertion(
544
542
  [SetSchema, 'to equal', SetSchema],
545
- (actual, expected) => {
546
- return actual.size === expected.size && isSubsetOf(actual, expected);
547
- },
543
+ (actual, expected) =>
544
+ actual.size === expected.size && isSubsetOf(actual, expected),
548
545
  );
549
546
 
550
547
  /**
@@ -1004,3 +1001,632 @@ export const collectionSizeBetweenAssertion = createAssertion(
1004
1001
  }
1005
1002
  },
1006
1003
  );
1004
+
1005
+ // =============================================================================
1006
+ // Collection value assertions (Map/Set/Array)
1007
+ // =============================================================================
1008
+
1009
+ const CollectionSchema = z.union([MapSchema, SetSchema, UnknownArraySchema]);
1010
+
1011
+ /**
1012
+ * Returns the iterable of values for a Map, Set, or Array.
1013
+ *
1014
+ * Map iterates its values (not entries), while Set and Array are directly
1015
+ * iterable.
1016
+ *
1017
+ * @function
1018
+ * @internal
1019
+ */
1020
+ const getCollectionValues = (
1021
+ collection: Map<unknown, unknown> | Set<unknown> | unknown[],
1022
+ ): Iterable<unknown> => {
1023
+ if (collection instanceof Map) {
1024
+ return collection.values();
1025
+ }
1026
+ return collection;
1027
+ };
1028
+
1029
+ /**
1030
+ * Asserts that ALL values in a Map, Set, or Array individually satisfy the
1031
+ * expected shape.
1032
+ *
1033
+ * Uses partial/satisfy semantics — every value must match. Empty collections
1034
+ * pass vacuously.
1035
+ *
1036
+ * @remarks
1037
+ * For `Map`, values (not keys) are checked. Use `mapKeysSatisfyAssertion` to
1038
+ * assert on Map keys instead.
1039
+ * @example
1040
+ *
1041
+ * ```ts
1042
+ * expect([{ a: 1 }, { a: 2, b: 3 }], 'to have values satisfying', {
1043
+ * a: z.number(),
1044
+ * }); // passes
1045
+ * expect(new Set([1, 2, 3]), 'to have values satisfying', z.number()); // passes
1046
+ * expect(new Map([['k', { x: 1 }]]), 'to have values satisfying', {
1047
+ * x: z.number(),
1048
+ * }); // passes
1049
+ * ```
1050
+ *
1051
+ * @function
1052
+ * @group Collection Assertions
1053
+ * @bupkisAnchor collection-to-have-values-satisfying-any
1054
+ * @bupkisAssertionCategory collections
1055
+ */
1056
+ export const collectionValuesSatisfyAssertion = createAssertion(
1057
+ [
1058
+ CollectionSchema,
1059
+ ['to have values satisfying', 'to contain values satisfying'],
1060
+ UnknownSchema,
1061
+ ],
1062
+ (subject, expected) => {
1063
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1064
+ let index = 0;
1065
+ for (const value of getCollectionValues(subject)) {
1066
+ const result = schema.safeParse(value);
1067
+ if (!result.success) {
1068
+ return {
1069
+ message: `Expected all values to satisfy ${inspect(expected)}, but value at index ${index} did not match: ${inspect(value)}`,
1070
+ };
1071
+ }
1072
+ index++;
1073
+ }
1074
+ // Empty collections trivially satisfy (vacuous truth)
1075
+ },
1076
+ );
1077
+
1078
+ /**
1079
+ * Asserts that ALL values in a Map, Set, or Array individually match with deep
1080
+ * equality.
1081
+ *
1082
+ * Uses strict deep-equality semantics — every value must exactly match. Empty
1083
+ * collections pass vacuously.
1084
+ *
1085
+ * @example
1086
+ *
1087
+ * ```ts
1088
+ * expect([{ a: 1 }, { a: 1 }], 'to have values exhaustively satisfying', {
1089
+ * a: 1,
1090
+ * }); // passes
1091
+ * expect([{ a: 1, b: 2 }], 'to have values exhaustively satisfying', {
1092
+ * a: 1,
1093
+ * }); // fails — extra property b
1094
+ * ```
1095
+ *
1096
+ * @function
1097
+ * @group Collection Assertions
1098
+ * @bupkisAnchor collection-to-have-values-exhaustively-satisfying-any
1099
+ * @bupkisAssertionCategory collections
1100
+ */
1101
+ export const collectionValuesExhaustivelySatisfyAssertion = createAssertion(
1102
+ [CollectionSchema, 'to have values exhaustively satisfying', UnknownSchema],
1103
+ (subject, expected) => {
1104
+ const schema = valueToSchema(expected, valueToSchemaOptionsForDeepEqual);
1105
+ let index = 0;
1106
+ for (const value of getCollectionValues(subject)) {
1107
+ const result = schema.safeParse(value);
1108
+ if (!result.success) {
1109
+ return {
1110
+ message: `Expected all values to exhaustively satisfy ${inspect(expected)}, but value at index ${index} did not match: ${inspect(value)}`,
1111
+ };
1112
+ }
1113
+ index++;
1114
+ }
1115
+ },
1116
+ );
1117
+
1118
+ /**
1119
+ * Asserts that at least one value in a Map, Set, or Array satisfies the
1120
+ * expected shape.
1121
+ *
1122
+ * Uses partial/satisfy semantics — any single matching value is sufficient.
1123
+ * Fails on empty collections.
1124
+ *
1125
+ * @remarks
1126
+ * For `Map`, values (not keys) are checked.
1127
+ * @example
1128
+ *
1129
+ * ```ts
1130
+ * expect([{ a: 1, b: 2 }, { c: 3 }], 'to have a value satisfying', {
1131
+ * a: 1,
1132
+ * }); // passes
1133
+ * expect(new Set([1, 'two', 3]), 'to have a value satisfying', z.string()); // passes
1134
+ * expect([1, 2, 3], 'to have value satisfying', 2); // passes
1135
+ * ```
1136
+ *
1137
+ * @function
1138
+ * @group Collection Assertions
1139
+ * @bupkisAnchor collection-to-have-a-value-satisfying-any
1140
+ * @bupkisAssertionCategory collections
1141
+ */
1142
+ export const collectionHasValueSatisfyingAssertion = createAssertion(
1143
+ [
1144
+ CollectionSchema,
1145
+ [
1146
+ 'to have a value satisfying',
1147
+ 'to have value satisfying',
1148
+ 'to contain a value satisfying',
1149
+ ],
1150
+ UnknownSchema,
1151
+ ],
1152
+ (subject, expected) => {
1153
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1154
+ for (const value of getCollectionValues(subject)) {
1155
+ if (schema.safeParse(value).success) {
1156
+ return;
1157
+ }
1158
+ }
1159
+ return {
1160
+ message: `Expected collection to have a value satisfying ${inspect(expected)}, but none matched`,
1161
+ };
1162
+ },
1163
+ );
1164
+
1165
+ /**
1166
+ * Asserts that at least one value in a Map, Set, or Array exhaustively matches
1167
+ * the expected value.
1168
+ *
1169
+ * Uses strict deep-equality semantics. Fails on empty collections.
1170
+ *
1171
+ * @example
1172
+ *
1173
+ * ```ts
1174
+ * expect(
1175
+ * [{ a: 1 }, { a: 1, b: 2 }],
1176
+ * 'to have a value exhaustively satisfying',
1177
+ * {
1178
+ * a: 1,
1179
+ * },
1180
+ * ); // passes — first element matches exactly
1181
+ * expect([{ a: 1, b: 2 }], 'to have a value exhaustively satisfying', {
1182
+ * a: 1,
1183
+ * }); // fails — extra property b
1184
+ * ```
1185
+ *
1186
+ * @function
1187
+ * @group Collection Assertions
1188
+ * @bupkisAnchor collection-to-have-a-value-exhaustively-satisfying-any
1189
+ * @bupkisAssertionCategory collections
1190
+ */
1191
+ export const collectionHasValueExhaustivelySatisfyingAssertion =
1192
+ createAssertion(
1193
+ [
1194
+ CollectionSchema,
1195
+ [
1196
+ 'to have a value exhaustively satisfying',
1197
+ 'to have value exhaustively satisfying',
1198
+ ],
1199
+ UnknownSchema,
1200
+ ],
1201
+ (subject, expected) => {
1202
+ const schema = valueToSchema(expected, valueToSchemaOptionsForDeepEqual);
1203
+ for (const value of getCollectionValues(subject)) {
1204
+ if (schema.safeParse(value).success) {
1205
+ return;
1206
+ }
1207
+ }
1208
+ return {
1209
+ message: `Expected collection to have a value exhaustively satisfying ${inspect(expected)}, but none matched`,
1210
+ };
1211
+ },
1212
+ );
1213
+
1214
+ // =============================================================================
1215
+ // Map key assertions
1216
+ // =============================================================================
1217
+
1218
+ /**
1219
+ * Asserts that ALL keys in a Map individually satisfy the expected shape.
1220
+ *
1221
+ * Uses partial/satisfy semantics — every key must match. Empty Maps pass
1222
+ * vacuously.
1223
+ *
1224
+ * @example
1225
+ *
1226
+ * ```ts
1227
+ * const map = new Map([
1228
+ * ['foo', 1],
1229
+ * ['bar', 2],
1230
+ * ]);
1231
+ * expect(map, 'to have keys satisfying', z.string()); // passes
1232
+ * expect(map, 'to have props satisfying', z.string()); // alias — same assertion
1233
+ * expect(map, 'to have fields satisfying', z.string()); // alias
1234
+ * expect(map, 'to contain keys satisfying', /^[a-z]+$/); // alias
1235
+ * ```
1236
+ *
1237
+ * @function
1238
+ * @group Collection Assertions
1239
+ * @bupkisAnchor map-to-have-keys-satisfying-any
1240
+ * @bupkisAssertionCategory collections
1241
+ */
1242
+ export const mapKeysSatisfyAssertion = createAssertion(
1243
+ [
1244
+ MapSchema,
1245
+ [
1246
+ 'to have keys satisfying',
1247
+ 'to have props satisfying',
1248
+ 'to have properties satisfying',
1249
+ 'to have fields satisfying',
1250
+ 'to contain keys satisfying',
1251
+ 'to contain props satisfying',
1252
+ 'to contain properties satisfying',
1253
+ 'to contain fields satisfying',
1254
+ ],
1255
+ UnknownSchema,
1256
+ ],
1257
+ (subject, expected) => {
1258
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1259
+ let index = 0;
1260
+ for (const key of subject.keys()) {
1261
+ const result = schema.safeParse(key);
1262
+ if (!result.success) {
1263
+ return {
1264
+ message: `Expected all Map keys to satisfy ${inspect(expected)}, but key at index ${index} did not match: ${inspect(key)}`,
1265
+ };
1266
+ }
1267
+ index++;
1268
+ }
1269
+ // Empty Maps trivially satisfy (vacuous truth)
1270
+ },
1271
+ );
1272
+
1273
+ /**
1274
+ * Asserts that ALL keys in a Map individually match with deep equality.
1275
+ *
1276
+ * Uses strict deep-equality semantics — every key must exactly match. Empty
1277
+ * Maps pass vacuously.
1278
+ *
1279
+ * @example
1280
+ *
1281
+ * ```ts
1282
+ * const map = new Map([
1283
+ * [{ id: 1 }, 'a'],
1284
+ * [{ id: 2 }, 'b'],
1285
+ * ]);
1286
+ * expect(map, 'to have keys exhaustively satisfying', { id: z.number() }); // fails — extra strict
1287
+ * expect(map, 'to have props exhaustively satisfying', { id: z.number() }); // alias
1288
+ * expect(map, 'to have fields exhaustively satisfying', {
1289
+ * id: z.number(),
1290
+ * }); // alias
1291
+ * ```
1292
+ *
1293
+ * @function
1294
+ * @group Collection Assertions
1295
+ * @bupkisAnchor map-to-have-keys-exhaustively-satisfying-any
1296
+ * @bupkisAssertionCategory collections
1297
+ */
1298
+ export const mapKeysExhaustivelySatisfyAssertion = createAssertion(
1299
+ [
1300
+ MapSchema,
1301
+ [
1302
+ 'to have keys exhaustively satisfying',
1303
+ 'to have props exhaustively satisfying',
1304
+ 'to have properties exhaustively satisfying',
1305
+ 'to have fields exhaustively satisfying',
1306
+ ],
1307
+ UnknownSchema,
1308
+ ],
1309
+ (subject, expected) => {
1310
+ const schema = valueToSchema(expected, valueToSchemaOptionsForDeepEqual);
1311
+ let index = 0;
1312
+ for (const key of subject.keys()) {
1313
+ const result = schema.safeParse(key);
1314
+ if (!result.success) {
1315
+ return {
1316
+ message: `Expected all Map keys to exhaustively satisfy ${inspect(expected)}, but key at index ${index} did not match: ${inspect(key)}`,
1317
+ };
1318
+ }
1319
+ index++;
1320
+ }
1321
+ },
1322
+ );
1323
+
1324
+ /**
1325
+ * Asserts that at least one key in a Map satisfies the expected shape.
1326
+ *
1327
+ * Uses partial/satisfy semantics. Fails on empty Maps.
1328
+ *
1329
+ * @example
1330
+ *
1331
+ * ```ts
1332
+ * const map = new Map([
1333
+ * ['foo', 1],
1334
+ * [42, 2],
1335
+ * ]);
1336
+ * expect(map, 'to have a key satisfying', z.string()); // passes
1337
+ * expect(map, 'to have key satisfying', z.number()); // passes
1338
+ * expect(map, 'to have a prop satisfying', z.string()); // alias
1339
+ * expect(map, 'to have a field satisfying', z.number()); // alias
1340
+ * ```
1341
+ *
1342
+ * @function
1343
+ * @group Collection Assertions
1344
+ * @bupkisAnchor map-to-have-a-key-satisfying-any
1345
+ * @bupkisAssertionCategory collections
1346
+ */
1347
+ export const mapHasKeySatisfyingAssertion = createAssertion(
1348
+ [
1349
+ MapSchema,
1350
+ [
1351
+ 'to have a key satisfying',
1352
+ 'to have key satisfying',
1353
+ 'to have a prop satisfying',
1354
+ 'to have prop satisfying',
1355
+ 'to have a property satisfying',
1356
+ 'to have property satisfying',
1357
+ 'to have a field satisfying',
1358
+ 'to have field satisfying',
1359
+ ],
1360
+ UnknownSchema,
1361
+ ],
1362
+ (subject, expected) => {
1363
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1364
+ for (const key of subject.keys()) {
1365
+ if (schema.safeParse(key).success) {
1366
+ return;
1367
+ }
1368
+ }
1369
+ return {
1370
+ message: `Expected Map to have a key satisfying ${inspect(expected)}, but none matched`,
1371
+ };
1372
+ },
1373
+ );
1374
+
1375
+ /**
1376
+ * Asserts that at least one key in a Map exhaustively matches the expected
1377
+ * value.
1378
+ *
1379
+ * Uses strict deep-equality semantics. Fails on empty Maps.
1380
+ *
1381
+ * @example
1382
+ *
1383
+ * ```ts
1384
+ * const map = new Map([
1385
+ * [{ id: 1 }, 'a'],
1386
+ * [{ id: 2 }, 'b'],
1387
+ * ]);
1388
+ * expect(map, 'to have a key exhaustively satisfying', { id: 1 }); // passes
1389
+ * expect(map, 'to have a prop exhaustively satisfying', { id: 1 }); // alias
1390
+ * expect(map, 'to have a field exhaustively satisfying', { id: 2 }); // alias
1391
+ * ```
1392
+ *
1393
+ * @function
1394
+ * @group Collection Assertions
1395
+ * @bupkisAnchor map-to-have-a-key-exhaustively-satisfying-any
1396
+ * @bupkisAssertionCategory collections
1397
+ */
1398
+ export const mapHasKeyExhaustivelySatisfyingAssertion = createAssertion(
1399
+ [
1400
+ MapSchema,
1401
+ [
1402
+ 'to have a key exhaustively satisfying',
1403
+ 'to have key exhaustively satisfying',
1404
+ 'to have a prop exhaustively satisfying',
1405
+ 'to have prop exhaustively satisfying',
1406
+ 'to have a property exhaustively satisfying',
1407
+ 'to have property exhaustively satisfying',
1408
+ 'to have a field exhaustively satisfying',
1409
+ 'to have field exhaustively satisfying',
1410
+ ],
1411
+ UnknownSchema,
1412
+ ],
1413
+ (subject, expected) => {
1414
+ const schema = valueToSchema(expected, valueToSchemaOptionsForDeepEqual);
1415
+ for (const key of subject.keys()) {
1416
+ if (schema.safeParse(key).success) {
1417
+ return;
1418
+ }
1419
+ }
1420
+ return {
1421
+ message: `Expected Map to have a key exhaustively satisfying ${inspect(expected)}, but none matched`,
1422
+ };
1423
+ },
1424
+ );
1425
+
1426
+ // =============================================================================
1427
+ // Object key assertions
1428
+ // =============================================================================
1429
+
1430
+ /**
1431
+ * Asserts that ALL own enumerable string keys of a non-collection object
1432
+ * individually satisfy the expected shape.
1433
+ *
1434
+ * Uses partial/satisfy semantics — every key must match. Empty objects pass
1435
+ * vacuously.
1436
+ *
1437
+ * @remarks
1438
+ * Only considers own enumerable string keys (equivalent to `Object.keys()`).
1439
+ * Symbol keys and non-enumerable keys are not checked.
1440
+ * @example
1441
+ *
1442
+ * ```ts
1443
+ * expect({ foo: 1, bar: 2 }, 'to have keys satisfying', z.string()); // passes
1444
+ * expect({ foo: 1, bar: 2 }, 'to have props satisfying', /^[a-z]+$/); // alias
1445
+ * expect({ foo: 1, bar: 2 }, 'to have fields satisfying', /^[a-z]+$/); // alias
1446
+ * expect({ FOO: 1 }, 'to have keys satisfying', /^[a-z]+$/); // fails
1447
+ * ```
1448
+ *
1449
+ * @function
1450
+ * @group Collection Assertions
1451
+ * @bupkisAnchor object-to-have-keys-satisfying-any
1452
+ * @bupkisAssertionCategory object
1453
+ */
1454
+ export const objectKeysSatisfyAssertion = createAssertion(
1455
+ [
1456
+ NonCollectionObjectSchema,
1457
+ [
1458
+ 'to have keys satisfying',
1459
+ 'to have props satisfying',
1460
+ 'to have properties satisfying',
1461
+ 'to have fields satisfying',
1462
+ ],
1463
+ UnknownSchema,
1464
+ ],
1465
+ (subject, expected) => {
1466
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1467
+ for (const key of keys(subject)) {
1468
+ const result = schema.safeParse(key);
1469
+ if (!result.success) {
1470
+ return {
1471
+ message: `Expected all object keys to satisfy ${inspect(expected)}, but key ${inspect(key)} did not match`,
1472
+ };
1473
+ }
1474
+ }
1475
+ // Empty objects trivially satisfy (vacuous truth)
1476
+ },
1477
+ );
1478
+
1479
+ /**
1480
+ * Asserts that at least one own enumerable string key of a non-collection
1481
+ * object satisfies the expected shape.
1482
+ *
1483
+ * Uses partial/satisfy semantics. Fails on objects with no own enumerable
1484
+ * string keys.
1485
+ *
1486
+ * @remarks
1487
+ * Only considers own enumerable string keys (equivalent to `Object.keys()`).
1488
+ * Symbol keys and non-enumerable keys are not checked.
1489
+ * @example
1490
+ *
1491
+ * ```ts
1492
+ * expect({ foo: 1, BAR: 2 }, 'to have a key satisfying', /^[a-z]+$/); // passes
1493
+ * expect({ foo: 1 }, 'to have key satisfying', z.string()); // passes
1494
+ * expect({ foo: 1 }, 'to have a prop satisfying', z.string()); // alias
1495
+ * expect({ foo: 1 }, 'to have a field satisfying', z.string()); // alias
1496
+ * ```
1497
+ *
1498
+ * @function
1499
+ * @group Collection Assertions
1500
+ * @bupkisAnchor object-to-have-a-key-satisfying-any
1501
+ * @bupkisAssertionCategory object
1502
+ */
1503
+ export const objectHasKeySatisfyingAssertion = createAssertion(
1504
+ [
1505
+ NonCollectionObjectSchema,
1506
+ [
1507
+ 'to have a key satisfying',
1508
+ 'to have key satisfying',
1509
+ 'to have a prop satisfying',
1510
+ 'to have prop satisfying',
1511
+ 'to have a property satisfying',
1512
+ 'to have property satisfying',
1513
+ 'to have a field satisfying',
1514
+ 'to have field satisfying',
1515
+ ],
1516
+ UnknownSchema,
1517
+ ],
1518
+ (subject, expected) => {
1519
+ const schema = valueToSchema(expected, valueToSchemaOptionsForSatisfies);
1520
+ for (const key of keys(subject)) {
1521
+ if (schema.safeParse(key).success) {
1522
+ return;
1523
+ }
1524
+ }
1525
+ return {
1526
+ message: `Expected object to have a key satisfying ${inspect(expected)}, but none matched`,
1527
+ };
1528
+ },
1529
+ );
1530
+
1531
+ /**
1532
+ * Asserts that ALL own enumerable string keys of a non-collection object match
1533
+ * a regular expression.
1534
+ *
1535
+ * Empty objects pass vacuously.
1536
+ *
1537
+ * @remarks
1538
+ * Only considers own enumerable string keys (equivalent to `Object.keys()`).
1539
+ * Symbol keys and non-enumerable keys are not checked.
1540
+ * @example
1541
+ *
1542
+ * ```ts
1543
+ * expect({ foo: 1, bar: 2 }, 'to have keys matching', /^[a-z]+$/); // passes
1544
+ * expect({ foo: 1, bar: 2 }, 'to have props matching', /^[a-z]+$/); // alias
1545
+ * expect({ foo: 1, bar: 2 }, 'to have fields matching', /^[a-z]+$/); // alias
1546
+ * expect({ foo: 1, Bar: 2 }, 'to have keys matching', /^[a-z]+$/); // fails
1547
+ * expect({}, 'to have keys matching', /anything/); // passes (vacuous)
1548
+ * ```
1549
+ *
1550
+ * @function
1551
+ * @group Collection Assertions
1552
+ * @bupkisAnchor object-to-have-keys-matching-regexp
1553
+ * @bupkisAssertionCategory object
1554
+ */
1555
+ export const objectKeysMatchAssertion = createAssertion(
1556
+ [
1557
+ NonCollectionObjectSchema,
1558
+ [
1559
+ 'to have keys matching',
1560
+ 'to have props matching',
1561
+ 'to have properties matching',
1562
+ 'to have fields matching',
1563
+ ],
1564
+ z.instanceof(RegExp),
1565
+ ],
1566
+ (subject, pattern) => {
1567
+ for (const key of keys(subject)) {
1568
+ if (pattern.global || pattern.sticky) {
1569
+ pattern.lastIndex = 0;
1570
+ }
1571
+ if (!pattern.test(key)) {
1572
+ return {
1573
+ message: `Expected all object keys to match ${inspect(pattern)}, but key ${inspect(key)} did not match`,
1574
+ };
1575
+ }
1576
+ }
1577
+ },
1578
+ );
1579
+
1580
+ /**
1581
+ * Asserts that at least one own enumerable string key of a non-collection
1582
+ * object matches a regular expression.
1583
+ *
1584
+ * Fails on objects with no own enumerable string keys.
1585
+ *
1586
+ * @remarks
1587
+ * Only considers own enumerable string keys (equivalent to `Object.keys()`).
1588
+ * Symbol keys and non-enumerable keys are not checked.
1589
+ * @example
1590
+ *
1591
+ * ```ts
1592
+ * expect({ foo: 1, BAR: 2 }, 'to have a key matching', /^[a-z]+$/); // passes
1593
+ * expect({ foo: 1, BAR: 2 }, 'to have a prop matching', /^[a-z]+$/); // alias
1594
+ * expect({ foo: 1, BAR: 2 }, 'to have a field matching', /^[a-z]+$/); // alias
1595
+ * expect({ FOO: 1, BAR: 2 }, 'to have a key matching', /^[a-z]+$/); // fails
1596
+ * expect({ foo: 1 }, 'to have key matching', /foo/); // passes
1597
+ * ```
1598
+ *
1599
+ * @function
1600
+ * @group Collection Assertions
1601
+ * @bupkisAnchor object-to-have-a-key-matching-regexp
1602
+ * @bupkisAssertionCategory object
1603
+ */
1604
+ export const objectHasKeyMatchingAssertion = createAssertion(
1605
+ [
1606
+ NonCollectionObjectSchema,
1607
+ [
1608
+ 'to have a key matching',
1609
+ 'to have key matching',
1610
+ 'to have a prop matching',
1611
+ 'to have prop matching',
1612
+ 'to have a property matching',
1613
+ 'to have property matching',
1614
+ 'to have a field matching',
1615
+ 'to have field matching',
1616
+ ],
1617
+ z.instanceof(RegExp),
1618
+ ],
1619
+ (subject, pattern) => {
1620
+ for (const key of keys(subject)) {
1621
+ if (pattern.global || pattern.sticky) {
1622
+ pattern.lastIndex = 0;
1623
+ }
1624
+ if (pattern.test(key)) {
1625
+ return;
1626
+ }
1627
+ }
1628
+ return {
1629
+ message: `Expected object to have a key matching ${inspect(pattern)}, but none matched`,
1630
+ };
1631
+ },
1632
+ );