sbom-cyclonedx 0.1.0 → 0.2.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 (368) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.gitlab-ci.yml +49 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +72 -0
  6. data/.vscode/settings.json +6 -0
  7. data/CHANGELOG.md +9 -0
  8. data/CODE_OF_CONDUCT.md +132 -0
  9. data/Gemfile +26 -0
  10. data/Gemfile.lock +179 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +39 -0
  13. data/Rakefile +36 -0
  14. data/Steepfile +14 -0
  15. data/bin/console +11 -0
  16. data/bin/rbs_spec +9 -0
  17. data/bin/setup +8 -0
  18. data/bom-1.6.schema.json +7334 -0
  19. data/lib/email_address_extension.rb +26 -0
  20. data/lib/sbom/cyclone_dx/enum.rb +2178 -0
  21. data/lib/sbom/cyclone_dx/field.rb +404 -0
  22. data/lib/sbom/cyclone_dx/pattern.rb +43 -0
  23. data/lib/sbom/cyclone_dx/record/advisory.rb +17 -0
  24. data/lib/sbom/cyclone_dx/record/annotation.rb +46 -0
  25. data/lib/sbom/cyclone_dx/record/attachment.rb +21 -0
  26. data/lib/sbom/cyclone_dx/record/base.rb +244 -0
  27. data/lib/sbom/cyclone_dx/record/cipher_suite.rb +23 -0
  28. data/lib/sbom/cyclone_dx/record/co2_measure.rb +18 -0
  29. data/lib/sbom/cyclone_dx/record/command.rb +18 -0
  30. data/lib/sbom/cyclone_dx/record/commit.rb +25 -0
  31. data/lib/sbom/cyclone_dx/record/component.rb +126 -0
  32. data/lib/sbom/cyclone_dx/record/component_data.rb +46 -0
  33. data/lib/sbom/cyclone_dx/record/component_evidence.rb +68 -0
  34. data/lib/sbom/cyclone_dx/record/component_identity_evidence.rb +36 -0
  35. data/lib/sbom/cyclone_dx/record/composition.rb +33 -0
  36. data/lib/sbom/cyclone_dx/record/condition.rb +20 -0
  37. data/lib/sbom/cyclone_dx/record/copyright.rb +16 -0
  38. data/lib/sbom/cyclone_dx/record/crypto_properties.rb +137 -0
  39. data/lib/sbom/cyclone_dx/record/data_governance.rb +21 -0
  40. data/lib/sbom/cyclone_dx/record/data_governance_responsible_party.rb +22 -0
  41. data/lib/sbom/cyclone_dx/record/declarations.rb +193 -0
  42. data/lib/sbom/cyclone_dx/record/definitions.rb +17 -0
  43. data/lib/sbom/cyclone_dx/record/dependency.rb +21 -0
  44. data/lib/sbom/cyclone_dx/record/diff.rb +18 -0
  45. data/lib/sbom/cyclone_dx/record/energy_consumption.rb +31 -0
  46. data/lib/sbom/cyclone_dx/record/energy_measure.rb +18 -0
  47. data/lib/sbom/cyclone_dx/record/energy_provider.rb +31 -0
  48. data/lib/sbom/cyclone_dx/record/environmental_consideration.rb +20 -0
  49. data/lib/sbom/cyclone_dx/record/event.rb +31 -0
  50. data/lib/sbom/cyclone_dx/record/external_reference.rb +25 -0
  51. data/lib/sbom/cyclone_dx/record/fairness_assessment.rb +22 -0
  52. data/lib/sbom/cyclone_dx/record/formula.rb +29 -0
  53. data/lib/sbom/cyclone_dx/record/graphic.rb +19 -0
  54. data/lib/sbom/cyclone_dx/record/graphics_collection.rb +19 -0
  55. data/lib/sbom/cyclone_dx/record/hash_data.rb +18 -0
  56. data/lib/sbom/cyclone_dx/record/identifiable_action.rb +21 -0
  57. data/lib/sbom/cyclone_dx/record/input.rb +34 -0
  58. data/lib/sbom/cyclone_dx/record/input_output_ml_parameter.rb +17 -0
  59. data/lib/sbom/cyclone_dx/record/issue.rb +36 -0
  60. data/lib/sbom/cyclone_dx/record/license.rb +90 -0
  61. data/lib/sbom/cyclone_dx/record/license_choice.rb +35 -0
  62. data/lib/sbom/cyclone_dx/record/metadata.rb +55 -0
  63. data/lib/sbom/cyclone_dx/record/model_card.rb +89 -0
  64. data/lib/sbom/cyclone_dx/record/note.rb +20 -0
  65. data/lib/sbom/cyclone_dx/record/organizational_contact.rb +26 -0
  66. data/lib/sbom/cyclone_dx/record/organizational_entity.rb +28 -0
  67. data/lib/sbom/cyclone_dx/record/output.rb +34 -0
  68. data/lib/sbom/cyclone_dx/record/parameter.rb +20 -0
  69. data/lib/sbom/cyclone_dx/record/patch.rb +23 -0
  70. data/lib/sbom/cyclone_dx/record/performance_metric.rb +30 -0
  71. data/lib/sbom/cyclone_dx/record/postal_address.rb +34 -0
  72. data/lib/sbom/cyclone_dx/record/property.rb +18 -0
  73. data/lib/sbom/cyclone_dx/record/rating.rb +27 -0
  74. data/lib/sbom/cyclone_dx/record/release_notes.rb +44 -0
  75. data/lib/sbom/cyclone_dx/record/resource_reference_choice.rb +22 -0
  76. data/lib/sbom/cyclone_dx/record/risk.rb +18 -0
  77. data/lib/sbom/cyclone_dx/record/root.rb +63 -0
  78. data/lib/sbom/cyclone_dx/record/secured_by.rb +20 -0
  79. data/lib/sbom/cyclone_dx/record/service.rb +54 -0
  80. data/lib/sbom/cyclone_dx/record/service_data.rb +32 -0
  81. data/lib/sbom/cyclone_dx/record/signature.rb +85 -0
  82. data/lib/sbom/cyclone_dx/record/standard.rb +72 -0
  83. data/lib/sbom/cyclone_dx/record/step.rb +24 -0
  84. data/lib/sbom/cyclone_dx/record/swid.rb +29 -0
  85. data/lib/sbom/cyclone_dx/record/task.rb +56 -0
  86. data/lib/sbom/cyclone_dx/record/tools.rb +20 -0
  87. data/lib/sbom/cyclone_dx/record/trigger.rb +48 -0
  88. data/lib/sbom/cyclone_dx/record/version.rb +24 -0
  89. data/lib/sbom/cyclone_dx/record/volume.rb +33 -0
  90. data/lib/sbom/cyclone_dx/record/vulnerability.rb +119 -0
  91. data/lib/sbom/cyclone_dx/record/vulnerability_source.rb +20 -0
  92. data/lib/sbom/cyclone_dx/record/workflow.rb +59 -0
  93. data/lib/sbom/cyclone_dx/record/workspace.rb +45 -0
  94. data/lib/sbom/cyclone_dx/record.rb +12 -0
  95. data/lib/sbom/cyclone_dx/validator/array_validator.rb +66 -0
  96. data/lib/sbom/cyclone_dx/validator/base_validator.rb +43 -0
  97. data/lib/sbom/cyclone_dx/validator/boolean_validator.rb +16 -0
  98. data/lib/sbom/cyclone_dx/validator/date_time_validator.rb +29 -0
  99. data/lib/sbom/cyclone_dx/validator/email_address_validator.rb +31 -0
  100. data/lib/sbom/cyclone_dx/validator/float_validator.rb +30 -0
  101. data/lib/sbom/cyclone_dx/validator/integer_validator.rb +30 -0
  102. data/lib/sbom/cyclone_dx/validator/record_validator.rb +26 -0
  103. data/lib/sbom/cyclone_dx/validator/string_validator.rb +33 -0
  104. data/lib/sbom/cyclone_dx/validator/union_validator.rb +39 -0
  105. data/lib/sbom/cyclone_dx/validator/uri_validator.rb +32 -0
  106. data/lib/sbom/cyclone_dx/validator.rb +32 -0
  107. data/lib/sbom/cyclone_dx/version.rb +7 -0
  108. data/lib/sbom/cyclone_dx.rb +39 -0
  109. data/rbs_collection.lock.yaml +288 -0
  110. data/rbs_collection.yaml +31 -0
  111. data/sbom-cyclone_dx.gemspec +32 -0
  112. data/sig/email_address_extension.rbs +14 -0
  113. data/sig/sbom/cyclone_dx/enum.rbs +93 -0
  114. data/sig/sbom/cyclone_dx/field.rbs +434 -0
  115. data/sig/sbom/cyclone_dx/pattern.rbs +24 -0
  116. data/sig/sbom/cyclone_dx/record/advisory.rbs +19 -0
  117. data/sig/sbom/cyclone_dx/record/annotation.rbs +63 -0
  118. data/sig/sbom/cyclone_dx/record/attachment.rbs +24 -0
  119. data/sig/sbom/cyclone_dx/record/base.rbs +62 -0
  120. data/sig/sbom/cyclone_dx/record/cipher_suite.rbs +24 -0
  121. data/sig/sbom/cyclone_dx/record/co2_measure.rbs +14 -0
  122. data/sig/sbom/cyclone_dx/record/command.rbs +19 -0
  123. data/sig/sbom/cyclone_dx/record/commit.rbs +34 -0
  124. data/sig/sbom/cyclone_dx/record/component.rbs +203 -0
  125. data/sig/sbom/cyclone_dx/record/component_data.rbs +73 -0
  126. data/sig/sbom/cyclone_dx/record/component_evidence.rbs +115 -0
  127. data/sig/sbom/cyclone_dx/record/component_identity_evidence.rbs +53 -0
  128. data/sig/sbom/cyclone_dx/record/composition.rbs +39 -0
  129. data/sig/sbom/cyclone_dx/record/condition.rbs +24 -0
  130. data/sig/sbom/cyclone_dx/record/copyright.rbs +14 -0
  131. data/sig/sbom/cyclone_dx/record/crypto_properties.rbs +268 -0
  132. data/sig/sbom/cyclone_dx/record/data_governance.rbs +24 -0
  133. data/sig/sbom/cyclone_dx/record/data_governance_responsible_party.rbs +19 -0
  134. data/sig/sbom/cyclone_dx/record/declarations.rbs +352 -0
  135. data/sig/sbom/cyclone_dx/record/definitions.rbs +14 -0
  136. data/sig/sbom/cyclone_dx/record/dependency.rbs +24 -0
  137. data/sig/sbom/cyclone_dx/record/diff.rbs +19 -0
  138. data/sig/sbom/cyclone_dx/record/energy_consumption.rbs +39 -0
  139. data/sig/sbom/cyclone_dx/record/energy_measure.rbs +14 -0
  140. data/sig/sbom/cyclone_dx/record/energy_provider.rbs +39 -0
  141. data/sig/sbom/cyclone_dx/record/environmental_consideration.rbs +19 -0
  142. data/sig/sbom/cyclone_dx/record/event.rbs +44 -0
  143. data/sig/sbom/cyclone_dx/record/external_reference.rbs +29 -0
  144. data/sig/sbom/cyclone_dx/record/fairness_assessment.rbs +29 -0
  145. data/sig/sbom/cyclone_dx/record/formula.rbs +34 -0
  146. data/sig/sbom/cyclone_dx/record/graphic.rbs +19 -0
  147. data/sig/sbom/cyclone_dx/record/graphics_collection.rbs +19 -0
  148. data/sig/sbom/cyclone_dx/record/hash_data.rbs +19 -0
  149. data/sig/sbom/cyclone_dx/record/identifiable_action.rbs +24 -0
  150. data/sig/sbom/cyclone_dx/record/input.rbs +44 -0
  151. data/sig/sbom/cyclone_dx/record/input_output_ml_parameter.rbs +14 -0
  152. data/sig/sbom/cyclone_dx/record/issue.rbs +53 -0
  153. data/sig/sbom/cyclone_dx/record/license.rbs +134 -0
  154. data/sig/sbom/cyclone_dx/record/license_choice.rbs +39 -0
  155. data/sig/sbom/cyclone_dx/record/metadata.rbs +82 -0
  156. data/sig/sbom/cyclone_dx/record/model_card.rbs +143 -0
  157. data/sig/sbom/cyclone_dx/record/note.rbs +19 -0
  158. data/sig/sbom/cyclone_dx/record/organizational_contact.rbs +29 -0
  159. data/sig/sbom/cyclone_dx/record/organizational_entity.rbs +34 -0
  160. data/sig/sbom/cyclone_dx/record/output.rbs +44 -0
  161. data/sig/sbom/cyclone_dx/record/parameter.rbs +24 -0
  162. data/sig/sbom/cyclone_dx/record/patch.rbs +24 -0
  163. data/sig/sbom/cyclone_dx/record/performance_metric.rbs +43 -0
  164. data/sig/sbom/cyclone_dx/record/postal_address.rbs +44 -0
  165. data/sig/sbom/cyclone_dx/record/property.rbs +19 -0
  166. data/sig/sbom/cyclone_dx/record/rating.rbs +39 -0
  167. data/sig/sbom/cyclone_dx/record/release_notes.rbs +64 -0
  168. data/sig/sbom/cyclone_dx/record/resource_reference_choice.rbs +19 -0
  169. data/sig/sbom/cyclone_dx/record/risk.rbs +19 -0
  170. data/sig/sbom/cyclone_dx/record/root.rbs +84 -0
  171. data/sig/sbom/cyclone_dx/record/secured_by.rbs +19 -0
  172. data/sig/sbom/cyclone_dx/record/service.rbs +99 -0
  173. data/sig/sbom/cyclone_dx/record/service_data.rbs +44 -0
  174. data/sig/sbom/cyclone_dx/record/signature.rbs +130 -0
  175. data/sig/sbom/cyclone_dx/record/standard.rbs +132 -0
  176. data/sig/sbom/cyclone_dx/record/step.rbs +29 -0
  177. data/sig/sbom/cyclone_dx/record/swid.rbs +44 -0
  178. data/sig/sbom/cyclone_dx/record/task.rbs +84 -0
  179. data/sig/sbom/cyclone_dx/record/tools.rbs +19 -0
  180. data/sig/sbom/cyclone_dx/record/trigger.rbs +69 -0
  181. data/sig/sbom/cyclone_dx/record/version.rbs +24 -0
  182. data/sig/sbom/cyclone_dx/record/volume.rbs +49 -0
  183. data/sig/sbom/cyclone_dx/record/vulnerability.rbs +209 -0
  184. data/sig/sbom/cyclone_dx/record/vulnerability_source.rbs +19 -0
  185. data/sig/sbom/cyclone_dx/record/workflow.rbs +94 -0
  186. data/sig/sbom/cyclone_dx/record/workspace.rbs +69 -0
  187. data/sig/sbom/cyclone_dx/record.rbs +161 -0
  188. data/sig/sbom/cyclone_dx/type.rbs +16 -0
  189. data/sig/sbom/cyclone_dx/validator/array_validator.rbs +31 -0
  190. data/sig/sbom/cyclone_dx/validator/base_validator.rbs +21 -0
  191. data/sig/sbom/cyclone_dx/validator/boolean_validator.rbs +9 -0
  192. data/sig/sbom/cyclone_dx/validator/date_time_validator.rbs +10 -0
  193. data/sig/sbom/cyclone_dx/validator/email_address_validator.rbs +10 -0
  194. data/sig/sbom/cyclone_dx/validator/float_validator.rbs +12 -0
  195. data/sig/sbom/cyclone_dx/validator/integer_validator.rbs +12 -0
  196. data/sig/sbom/cyclone_dx/validator/record_validator.rbs +12 -0
  197. data/sig/sbom/cyclone_dx/validator/string_validator.rbs +14 -0
  198. data/sig/sbom/cyclone_dx/validator/union_validator.rbs +24 -0
  199. data/sig/sbom/cyclone_dx/validator/uri_validator.rbs +10 -0
  200. data/sig/sbom/cyclone_dx/validator.rbs +66 -0
  201. data/sig/sbom/cyclone_dx.rbs +13 -0
  202. data/sig/types.rbs +45 -0
  203. data/spec/email_address_extension_spec.rb +27 -0
  204. data/spec/factories/factory_helper.rb +78 -0
  205. data/spec/factories/record/advisory_factory.rb +11 -0
  206. data/spec/factories/record/annotation_factory.rb +63 -0
  207. data/spec/factories/record/attachment_factory.rb +9 -0
  208. data/spec/factories/record/cipher_suite_factory.rb +26 -0
  209. data/spec/factories/record/co2_measure_factory.rb +9 -0
  210. data/spec/factories/record/command_factory.rb +10 -0
  211. data/spec/factories/record/commit_factory.rb +13 -0
  212. data/spec/factories/record/component_data_factory.rb +28 -0
  213. data/spec/factories/record/component_evidence_factory.rb +44 -0
  214. data/spec/factories/record/component_factory.rb +102 -0
  215. data/spec/factories/record/component_identity_evidence_factory.rb +25 -0
  216. data/spec/factories/record/composition_factory.rb +20 -0
  217. data/spec/factories/record/condition_factory.rb +11 -0
  218. data/spec/factories/record/copyright_factory.rb +9 -0
  219. data/spec/factories/record/crypto_properties_factory.rb +191 -0
  220. data/spec/factories/record/data_governance_factory.rb +11 -0
  221. data/spec/factories/record/data_governance_responsible_party_factory.rb +31 -0
  222. data/spec/factories/record/declarations_factory.rb +145 -0
  223. data/spec/factories/record/definitions_factory.rb +9 -0
  224. data/spec/factories/record/dependency_factory.rb +12 -0
  225. data/spec/factories/record/diff_factory.rb +24 -0
  226. data/spec/factories/record/energy_consumption_factory.rb +15 -0
  227. data/spec/factories/record/energy_measure_factory.rb +9 -0
  228. data/spec/factories/record/energy_provider_factory.rb +15 -0
  229. data/spec/factories/record/environmental_consideration_factory.rb +10 -0
  230. data/spec/factories/record/event_factory.rb +15 -0
  231. data/spec/factories/record/external_reference_factory.rb +13 -0
  232. data/spec/factories/record/fairness_assessment_factory.rb +12 -0
  233. data/spec/factories/record/formula_factory.rb +13 -0
  234. data/spec/factories/record/graphic_factory.rb +10 -0
  235. data/spec/factories/record/graphics_collection_factory.rb +10 -0
  236. data/spec/factories/record/hash_data_factory.rb +10 -0
  237. data/spec/factories/record/identifiable_action_factory.rb +11 -0
  238. data/spec/factories/record/input_factory.rb +36 -0
  239. data/spec/factories/record/input_output_ml_parameter_factory.rb +9 -0
  240. data/spec/factories/record/issue_factory.rb +22 -0
  241. data/spec/factories/record/license_choice_factory.rb +23 -0
  242. data/spec/factories/record/license_factory.rb +99 -0
  243. data/spec/factories/record/metadata_factory.rb +38 -0
  244. data/spec/factories/record/model_card_factory.rb +59 -0
  245. data/spec/factories/record/note_factory.rb +11 -0
  246. data/spec/factories/record/organizational_contact_factory.rb +12 -0
  247. data/spec/factories/record/organizational_entity_factory.rb +13 -0
  248. data/spec/factories/record/output_factory.rb +32 -0
  249. data/spec/factories/record/parameter_factory.rb +11 -0
  250. data/spec/factories/record/patch_factory.rb +12 -0
  251. data/spec/factories/record/performance_metric_factory.rb +20 -0
  252. data/spec/factories/record/postal_address_factory.rb +14 -0
  253. data/spec/factories/record/property_factory.rb +11 -0
  254. data/spec/factories/record/rating_factory.rb +14 -0
  255. data/spec/factories/record/release_notes_factory.rb +20 -0
  256. data/spec/factories/record/resource_reference_choice_factory.rb +27 -0
  257. data/spec/factories/record/risk_factory.rb +10 -0
  258. data/spec/factories/record/root_factory.rb +23 -0
  259. data/spec/factories/record/secured_by_factory.rb +10 -0
  260. data/spec/factories/record/service_data_factory.rb +16 -0
  261. data/spec/factories/record/service_factory.rb +27 -0
  262. data/spec/factories/record/signature_factory.rb +50 -0
  263. data/spec/factories/record/standard_factory.rb +37 -0
  264. data/spec/factories/record/step_factory.rb +12 -0
  265. data/spec/factories/record/swid_factory.rb +16 -0
  266. data/spec/factories/record/task_factory.rb +24 -0
  267. data/spec/factories/record/tools_factory.rb +10 -0
  268. data/spec/factories/record/trigger_factory.rb +21 -0
  269. data/spec/factories/record/version_factory.rb +19 -0
  270. data/spec/factories/record/volume_factory.rb +16 -0
  271. data/spec/factories/record/vulnerability_factory.rb +70 -0
  272. data/spec/factories/record/vulnerability_source_factory.rb +10 -0
  273. data/spec/factories/record/workflow_factory.rb +26 -0
  274. data/spec/factories/record/workspace_factory.rb +21 -0
  275. data/spec/factories/record_factory.rb +159 -0
  276. data/spec/fixtures/cipher_info.yml +948 -0
  277. data/spec/fixtures/purl_data.yml +0 -0
  278. data/spec/sbom/cyclone_dx/enum_spec.rb +30 -0
  279. data/spec/sbom/cyclone_dx/field_spec.rb +104 -0
  280. data/spec/sbom/cyclone_dx/pattern_spec.rb +18 -0
  281. data/spec/sbom/cyclone_dx/record/advisory_spec.rb +14 -0
  282. data/spec/sbom/cyclone_dx/record/annotation_spec.rb +31 -0
  283. data/spec/sbom/cyclone_dx/record/attachment_spec.rb +14 -0
  284. data/spec/sbom/cyclone_dx/record/base_spec.rb +363 -0
  285. data/spec/sbom/cyclone_dx/record/cipher_suite_spec.rb +14 -0
  286. data/spec/sbom/cyclone_dx/record/co2_measure_spec.rb +14 -0
  287. data/spec/sbom/cyclone_dx/record/command_spec.rb +14 -0
  288. data/spec/sbom/cyclone_dx/record/commit_spec.rb +14 -0
  289. data/spec/sbom/cyclone_dx/record/component_data_spec.rb +14 -0
  290. data/spec/sbom/cyclone_dx/record/component_evidence_spec.rb +14 -0
  291. data/spec/sbom/cyclone_dx/record/component_identity_evidence_spec.rb +14 -0
  292. data/spec/sbom/cyclone_dx/record/component_spec.rb +14 -0
  293. data/spec/sbom/cyclone_dx/record/composition_spec.rb +14 -0
  294. data/spec/sbom/cyclone_dx/record/condition_spec.rb +14 -0
  295. data/spec/sbom/cyclone_dx/record/copyright_spec.rb +14 -0
  296. data/spec/sbom/cyclone_dx/record/crypto_properties_spec.rb +14 -0
  297. data/spec/sbom/cyclone_dx/record/data_governance_responsible_party_spec.rb +19 -0
  298. data/spec/sbom/cyclone_dx/record/data_governance_spec.rb +14 -0
  299. data/spec/sbom/cyclone_dx/record/declarations_spec.rb +14 -0
  300. data/spec/sbom/cyclone_dx/record/definitions_spec.rb +14 -0
  301. data/spec/sbom/cyclone_dx/record/dependency_spec.rb +14 -0
  302. data/spec/sbom/cyclone_dx/record/diff_spec.rb +14 -0
  303. data/spec/sbom/cyclone_dx/record/energy_consumption_spec.rb +14 -0
  304. data/spec/sbom/cyclone_dx/record/energy_measure_spec.rb +14 -0
  305. data/spec/sbom/cyclone_dx/record/energy_provider_spec.rb +14 -0
  306. data/spec/sbom/cyclone_dx/record/environmental_consideration_spec.rb +14 -0
  307. data/spec/sbom/cyclone_dx/record/event_spec.rb +14 -0
  308. data/spec/sbom/cyclone_dx/record/external_reference_spec.rb +14 -0
  309. data/spec/sbom/cyclone_dx/record/fairness_assessment_spec.rb +14 -0
  310. data/spec/sbom/cyclone_dx/record/formula_spec.rb +14 -0
  311. data/spec/sbom/cyclone_dx/record/graphic_spec.rb +14 -0
  312. data/spec/sbom/cyclone_dx/record/graphics_collection_spec.rb +14 -0
  313. data/spec/sbom/cyclone_dx/record/hash_data_spec.rb +14 -0
  314. data/spec/sbom/cyclone_dx/record/identifiable_action_spec.rb +14 -0
  315. data/spec/sbom/cyclone_dx/record/input_output_ml_parameter_spec.rb +14 -0
  316. data/spec/sbom/cyclone_dx/record/input_spec.rb +14 -0
  317. data/spec/sbom/cyclone_dx/record/issue_spec.rb +14 -0
  318. data/spec/sbom/cyclone_dx/record/license_choice_spec.rb +26 -0
  319. data/spec/sbom/cyclone_dx/record/license_spec.rb +14 -0
  320. data/spec/sbom/cyclone_dx/record/metadata_spec.rb +14 -0
  321. data/spec/sbom/cyclone_dx/record/model_card_spec.rb +14 -0
  322. data/spec/sbom/cyclone_dx/record/note_spec.rb +14 -0
  323. data/spec/sbom/cyclone_dx/record/organizational_contact_spec.rb +14 -0
  324. data/spec/sbom/cyclone_dx/record/organizational_entity_spec.rb +14 -0
  325. data/spec/sbom/cyclone_dx/record/output_spec.rb +14 -0
  326. data/spec/sbom/cyclone_dx/record/parameter_spec.rb +14 -0
  327. data/spec/sbom/cyclone_dx/record/patch_spec.rb +14 -0
  328. data/spec/sbom/cyclone_dx/record/performance_metric_spec.rb +14 -0
  329. data/spec/sbom/cyclone_dx/record/postal_address_spec.rb +14 -0
  330. data/spec/sbom/cyclone_dx/record/property_spec.rb +14 -0
  331. data/spec/sbom/cyclone_dx/record/rating_spec.rb +14 -0
  332. data/spec/sbom/cyclone_dx/record/release_notes_spec.rb +14 -0
  333. data/spec/sbom/cyclone_dx/record/resource_reference_choice_spec.rb +14 -0
  334. data/spec/sbom/cyclone_dx/record/risk_spec.rb +14 -0
  335. data/spec/sbom/cyclone_dx/record/root_spec.rb +14 -0
  336. data/spec/sbom/cyclone_dx/record/secured_by_spec.rb +14 -0
  337. data/spec/sbom/cyclone_dx/record/service_data_spec.rb +14 -0
  338. data/spec/sbom/cyclone_dx/record/service_spec.rb +14 -0
  339. data/spec/sbom/cyclone_dx/record/signature_spec.rb +26 -0
  340. data/spec/sbom/cyclone_dx/record/standard_spec.rb +14 -0
  341. data/spec/sbom/cyclone_dx/record/step_spec.rb +14 -0
  342. data/spec/sbom/cyclone_dx/record/swid_spec.rb +14 -0
  343. data/spec/sbom/cyclone_dx/record/task_spec.rb +14 -0
  344. data/spec/sbom/cyclone_dx/record/tools_spec.rb +14 -0
  345. data/spec/sbom/cyclone_dx/record/trigger_spec.rb +14 -0
  346. data/spec/sbom/cyclone_dx/record/version_spec.rb +14 -0
  347. data/spec/sbom/cyclone_dx/record/volume_spec.rb +14 -0
  348. data/spec/sbom/cyclone_dx/record/vulnerability_source_spec.rb +14 -0
  349. data/spec/sbom/cyclone_dx/record/vulnerability_spec.rb +14 -0
  350. data/spec/sbom/cyclone_dx/record/workflow_spec.rb +14 -0
  351. data/spec/sbom/cyclone_dx/record/workspace_spec.rb +14 -0
  352. data/spec/sbom/cyclone_dx/record_spec.rb +7 -0
  353. data/spec/sbom/cyclone_dx/validator/array_validator_spec.rb +184 -0
  354. data/spec/sbom/cyclone_dx/validator/base_validator_spec.rb +71 -0
  355. data/spec/sbom/cyclone_dx/validator/boolean_validator_spec.rb +26 -0
  356. data/spec/sbom/cyclone_dx/validator/date_time_validator_spec.rb +28 -0
  357. data/spec/sbom/cyclone_dx/validator/email_address_validator_spec.rb +23 -0
  358. data/spec/sbom/cyclone_dx/validator/float_validator_spec.rb +71 -0
  359. data/spec/sbom/cyclone_dx/validator/integer_validator_spec.rb +71 -0
  360. data/spec/sbom/cyclone_dx/validator/record_validator_spec.rb +35 -0
  361. data/spec/sbom/cyclone_dx/validator/string_validator_spec.rb +94 -0
  362. data/spec/sbom/cyclone_dx/validator/union_validator_spec.rb +65 -0
  363. data/spec/sbom/cyclone_dx/validator/uri_validator_spec.rb +21 -0
  364. data/spec/sbom/cyclone_dx/validator_spec.rb +38 -0
  365. data/spec/sbom/cyclone_dx/version_spec.rb +9 -0
  366. data/spec/sbom/cyclone_dx_spec.rb +7 -0
  367. data/spec/spec_helper.rb +39 -0
  368. metadata +377 -6
File without changes
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/enum"
5
+
6
+ describe SBOM::CycloneDX::Enum do
7
+ let(:all_enums) do
8
+ described_class.constants.filter_map do |constant|
9
+ next unless constant.match?(/\A[A-Z_]+\Z/)
10
+
11
+ described_class.const_get(constant)
12
+ end
13
+ end
14
+
15
+ it "only has Array enums" do
16
+ expect(all_enums.all?(Array)).to be true
17
+ end
18
+
19
+ it "has unique values per enum" do
20
+ all_enums.each do |enum|
21
+ expect(enum.uniq).to eq(enum)
22
+ end
23
+ end
24
+
25
+ it "has the same type for all values in a given enum" do
26
+ all_enums.each do |enum|
27
+ expect(enum.all?(enum.first.class)).to be true
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe SBOM::CycloneDX::Field do
6
+ describe SBOM::CycloneDX::Field::Base do
7
+ describe "#initialize" do
8
+ it "raises an error if instantiated directly"
9
+ end
10
+
11
+ describe "#value"
12
+ describe "#valid?"
13
+ describe "convenience methods"
14
+
15
+ context "with the singleton class" do
16
+ describe "#field_name" do
17
+ it "returns the defined field name"
18
+ end
19
+
20
+ describe "#validator"
21
+ describe "#json_name"
22
+ describe "#required?"
23
+ describe "#const"
24
+ describe "#const?"
25
+ describe "#default"
26
+ describe "#default?"
27
+ end
28
+ end
29
+
30
+ describe SBOM::CycloneDX::Field::ConstBase do
31
+ describe "#initialize" do
32
+ it "raises an error if instantiated directly"
33
+ it "sets the value to the class' #const value"
34
+ end
35
+ end
36
+
37
+ describe SBOM::CycloneDX::Field::PropBase do
38
+ describe "#initialize" do
39
+ it "raises an error if instantiated directly"
40
+ it "requires exactly zero or one argument"
41
+
42
+ context "with no argument" do
43
+ it "calls unset_value"
44
+ end
45
+
46
+ context "with one argument" do
47
+ it "calls value= with the argument"
48
+ end
49
+ end
50
+
51
+ describe "#value=" do
52
+ context "when the argument is nil" do
53
+ context "when required and default exists" do
54
+ it "sets the value to default"
55
+ it "sets the value presence to true"
56
+ end
57
+
58
+ context "when required an no default exists" do
59
+ it "sets the value to nil"
60
+ it "sets the value presence to false"
61
+ end
62
+
63
+ context "when not required" do
64
+ it "sets the value to nil"
65
+ it "sets the value presence to true"
66
+ end
67
+ end
68
+
69
+ context "when the argument is not nil" do
70
+ it "sets the value to the argument"
71
+ it "sets the value presence to true"
72
+ end
73
+ end
74
+
75
+ describe "#unset_value" do
76
+ context "when a default value exists" do
77
+ it "sets the value to the default"
78
+ it "sets the value presence to true"
79
+ end
80
+
81
+ context "when no default value exists" do
82
+ it "sets the value to nil"
83
+ it "sets the value presence to false"
84
+ end
85
+ end
86
+
87
+ describe "#coerce" do
88
+ it "raises a NotImplementedError if not overridden"
89
+ end
90
+ end
91
+
92
+ describe "#array"
93
+ describe "#boolean"
94
+ describe "#date_time"
95
+ describe "#email_address"
96
+ describe "#float"
97
+ describe "#integer"
98
+ describe "#record"
99
+ describe "#string"
100
+ describe "#union"
101
+ describe "#uri"
102
+
103
+ # TODO: Add some shared test logic for the considerable #Field and #validate_types methods
104
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/pattern"
5
+
6
+ describe SBOM::CycloneDX::Pattern do
7
+ let(:all_patterns) do
8
+ described_class.constants.filter_map do |constant|
9
+ next unless constant.match?(/\A[A-Z_]+\Z/)
10
+
11
+ described_class.const_get(constant)
12
+ end
13
+ end
14
+
15
+ it "only has Regexp patterns" do
16
+ expect(all_patterns.all?(Regexp)).to be true
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/advisory"
5
+
6
+ describe SBOM::CycloneDX::Record::Advisory do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:advisory) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:advisory, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/annotation"
5
+
6
+ describe SBOM::CycloneDX::Record::Annotation do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:annotation) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:annotation, :all_fields) }.not_to raise_error
13
+ end
14
+
15
+ describe SBOM::CycloneDX::Record::Annotation::Annotator do
16
+ it "can be initialized with minimum required attributes" do
17
+ expect { build(:annotator) }.not_to raise_error
18
+ end
19
+
20
+ it "can be initialized with all attributes" do
21
+ expect { build(:annotator, :all_fields) }.not_to raise_error
22
+ end
23
+
24
+ it "is valid with organization, contact, component, or service" do
25
+ expect { build(:annotator, :organization) }.not_to raise_error
26
+ expect { build(:annotator, :contact) }.not_to raise_error
27
+ expect { build(:annotator, :component) }.not_to raise_error
28
+ expect { build(:annotator, :service) }.not_to raise_error
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/attachment"
5
+
6
+ describe SBOM::CycloneDX::Record::Attachment do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:attachment) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:attachment, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,363 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ class ConcreteRecord < SBOM::CycloneDX::Record::Base
6
+ class InnerRecord < SBOM::CycloneDX::Record::Base
7
+ json_name "someInnerRecord"
8
+ prop :integer_prop, :integer, json_name: "integer-prop"
9
+ end
10
+
11
+ prop :string_prop, :string
12
+ prop :record_prop, InnerRecord
13
+ end
14
+
15
+ describe SBOM::CycloneDX::Record::Base do
16
+ before(:each, :skip_body_check) do
17
+ allow(described_class).to receive(:in_subclass_body?).and_return(true)
18
+ end
19
+
20
+ context "with singleton class" do
21
+ describe "#fields" do
22
+ it "returns a Hash of Fields" do
23
+ fields = ConcreteRecord.fields
24
+
25
+ expect(fields).to be_a(Hash)
26
+ expect(fields.keys).to contain_exactly(:string_prop, :record_prop)
27
+ expect(fields.values.all? { |f| f < SBOM::CycloneDX::Field::Base }).to be(true)
28
+ end
29
+ end
30
+
31
+ describe "#json_create" do
32
+ it "creates a new instance of the class from a symbol-keyed JSON representation" do
33
+ json_hash = { string_prop: "value", record_prop: { "integer-prop": 1 } }
34
+ result = ConcreteRecord.json_create(json_hash)
35
+ expect(result).to be_a(ConcreteRecord)
36
+ expect(result.string_prop).to eq("value")
37
+ expect(result.record_prop).to be_a(ConcreteRecord::InnerRecord)
38
+ expect(result.record_prop.integer_prop).to eq(1)
39
+ end
40
+
41
+ it "creates a new instance of the class from a string-keyed JSON representation" do
42
+ json_hash = { "string_prop" => "value", "record_prop" => { "integer-prop" => 1 } }
43
+ result = ConcreteRecord.json_create(json_hash)
44
+ expect(result).to be_a(ConcreteRecord)
45
+ expect(result.string_prop).to eq("value")
46
+ expect(result.record_prop).to be_a(ConcreteRecord::InnerRecord)
47
+ expect(result.record_prop.integer_prop).to eq(1)
48
+ end
49
+ end
50
+
51
+ describe "#json_name" do
52
+ context "when called with an argument" do
53
+ it "sets the JSON name for the class if called within the class body" do
54
+ expect(ConcreteRecord::InnerRecord.json_name).to eq("someInnerRecord")
55
+ end
56
+
57
+ it "raises an error if called outside the class body" do
58
+ expect do
59
+ ConcreteRecord.json_name("concrete-record")
60
+ end.to raise_error("json_name can only be set within the class body")
61
+ end
62
+ end
63
+
64
+ context "when called without an argument" do
65
+ it "returns the JSON name for the class if one was set" do
66
+ expect(ConcreteRecord::InnerRecord.json_name).to eq("someInnerRecord")
67
+ end
68
+
69
+ it "returns the bare class name if no JSON name was set" do
70
+ expect(ConcreteRecord.json_name).to eq("ConcreteRecord")
71
+ end
72
+
73
+ it "returns 'Record' if no JSON name was set and the class name is nil" do
74
+ expect(Class.new(described_class).json_name).to eq("Record")
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "#prop" do
80
+ subject(:prop_test) { Class.new(described_class) }
81
+
82
+ it "raises an error if called outside the class body" do
83
+ expect do
84
+ prop_test.prop(:bad_prop, :string)
85
+ end.to raise_error("properties must be defined in the class body of a subclass of Record")
86
+ end
87
+
88
+ it "raises an error if called on the abstract class" do
89
+ expect do
90
+ described_class.prop(:bad_prop, :string)
91
+ end.to raise_error("properties cannot be defined for abstract Record")
92
+ end
93
+
94
+ it "raises an error if a property is defined more than once", :skip_body_check do
95
+ expect do
96
+ prop_test.prop(:a_prop, :integer)
97
+ prop_test.prop(:a_prop, :string)
98
+ end.to raise_error("property a_prop already defined")
99
+ end
100
+
101
+ it "creates a new field with the specified name and type", :skip_body_check do
102
+ prop_test.prop(:string_prop, :string)
103
+ expect(prop_test.fields[:string_prop].validator).to be_a(SBOM::CycloneDX::Validator::StringValidator)
104
+ end
105
+
106
+ it "accepts the :required flag", :skip_body_check do
107
+ prop_test.prop(:string_prop, :string, required: true)
108
+ expect(prop_test.fields[:string_prop].required?).to be(true)
109
+ end
110
+
111
+ it "accepts additional type-specific options", :skip_body_check do
112
+ test_pattern = /test/
113
+ prop_test.prop(:string_prop, :string, pattern: test_pattern)
114
+ expect(prop_test.fields[:string_prop].validator.instance_variable_get(:@pattern)).to eq(test_pattern)
115
+ end
116
+
117
+ it "defines a getter method for the property", :skip_body_check do
118
+ prop_test.prop(:string_prop, :string)
119
+ expect(prop_test.new).to respond_to(:string_prop)
120
+ end
121
+
122
+ it "defines a setter method for non-const properties", :skip_body_check do
123
+ prop_test.prop(:string_prop, :string)
124
+ expect(prop_test.new).to respond_to(:string_prop=)
125
+ end
126
+
127
+ it "does not define a setter method for const properties", :skip_body_check do
128
+ prop_test.prop(:string_prop, :string, const: "test")
129
+ expect(prop_test.new).not_to respond_to(:string_prop=)
130
+ end
131
+
132
+ it "defines a predicate method for the property with a '?' suffix", :skip_body_check do
133
+ prop_test.prop(:string_prop, :string)
134
+ expect(prop_test.new).to respond_to(:string_prop?)
135
+ end
136
+
137
+ it "defines a _valid? method for the property", :skip_body_check do
138
+ prop_test.prop(:string_prop, :string)
139
+ expect(prop_test.new).to respond_to(:string_prop_valid?)
140
+ end
141
+ end
142
+
143
+ describe "#const" do
144
+ subject(:const_test) { Class.new(described_class) }
145
+
146
+ it "is syntactic sugar for prop with :const value", :skip_body_check do
147
+ # rubocop:disable RSpec/SubjectStub
148
+ allow(const_test).to receive(:prop).and_call_original
149
+
150
+ const_test.const(:const_prop, :string, "test")
151
+
152
+ expect(const_test).to have_received(:prop)
153
+ .with(:const_prop, :string, const: "test", json_name: nil, required: false)
154
+ # rubocop:enable RSpec/SubjectStub
155
+ end
156
+ end
157
+
158
+ describe "#validate" do
159
+ subject(:validate_test) { Class.new(described_class) }
160
+
161
+ it "raises an error if called outside the class body" do
162
+ expect do
163
+ validate_test.validate(:bad_prop, presence: :one)
164
+ end.to raise_error("custom validators must be defined in the class body of a subclass of Record")
165
+ end
166
+
167
+ it "raises an error if called on the abstract class" do
168
+ expect do
169
+ described_class.validate(:bad_prop, presence: :one)
170
+ end.to raise_error("custom validators cannot be defined for abstract Record")
171
+ end
172
+
173
+ it "raises an error if provided with both :presence option and a block", :skip_body_check do
174
+ expect do
175
+ validate_test.validate(:bad_prop, presence: :one) { |value| value == "test" }
176
+ end.to raise_error("cannot provide both :presence and a block")
177
+ end
178
+
179
+ # TODO: Test that we correctly create the validators here
180
+ it "accepts presence validtaion with :all, :any, or :one", :skip_body_check do
181
+ expect do
182
+ validate_test.validate(:prop1, :prop2, presence: :all)
183
+ validate_test.validate(:prop1, :prop2, presence: :any)
184
+ validate_test.validate(:prop1, :prop2, presence: :one)
185
+ end.not_to raise_error
186
+ end
187
+
188
+ it "accepts a block for running custom validations", :skip_body_check do
189
+ expect do
190
+ validate_test.validate(:prop1, :prop2) { |value1, value2| value1 == value2 }
191
+ end.not_to raise_error
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "#initialize" do
197
+ context "when called on the abstract class" do
198
+ it "raises an error when instantiated" do
199
+ expect { described_class.new }.to raise_error("Cannot instantiate abstract Record")
200
+ end
201
+ end
202
+
203
+ context "when called on a subclass" do
204
+ subject(:record_class) do
205
+ allow(described_class).to receive(:in_subclass_body?).and_return(true)
206
+
207
+ Class.new(described_class) do
208
+ prop :string_prop, :string
209
+ prop :integer_prop, :integer, default: 1
210
+ prop :required_prop, :string, required: true
211
+ const :const_prop, :string, "test"
212
+ end
213
+ end
214
+
215
+ it "does not raise an error when instantiated" do
216
+ expect { record_class.new(required_prop: "a") }.not_to raise_error
217
+ end
218
+
219
+ it "populates fields with provided values" do
220
+ result = record_class.new(string_prop: "a string", required_prop: "a required string", integer_prop: 2)
221
+
222
+ expect(result.string_prop).to eq("a string")
223
+ expect(result.required_prop).to eq("a required string")
224
+ expect(result.integer_prop).to eq(2)
225
+ end
226
+
227
+ it "populates defaults when values are not provided" do
228
+ expect(record_class.new(required_prop: "a").integer_prop).to eq(1)
229
+ end
230
+
231
+ it "raises an error when a value is provided for a const field" do
232
+ expect do
233
+ record_class.new(const_prop: "new value")
234
+ end.to raise_error("Sbom value does not match const field ('test' != 'new value')")
235
+ end
236
+
237
+ it "raises an error when an unknown field is provided" do
238
+ expect do
239
+ record_class.new(required_prop: "a", unknown_field: "value")
240
+ end.to raise_error("Unknown field(s): unknown_field")
241
+ end
242
+
243
+ it "checks validity of the record" do
244
+ result = record_class.new(required_prop: "a")
245
+ expect(result.errors).not_to be_empty
246
+ expect(result.errors.values.all?(&:empty?)).to be(true)
247
+ end
248
+ end
249
+ end
250
+
251
+ describe "#<=>" do
252
+ subject(:comparable_record) do
253
+ allow(described_class).to receive(:in_subclass_body?).and_return(true)
254
+
255
+ Class.new(described_class) do
256
+ prop :string_prop, :string
257
+ prop :integer_prop, :integer
258
+ prop :boolean_prop, :boolean
259
+ prop :property_prop, SBOM::CycloneDX::Record::Property
260
+ end
261
+ end
262
+
263
+ it "returns nil if records are not of the same type", :skip_body_check do
264
+ record = comparable_record.new(string_prop: "a", integer_prop: 1, boolean_prop: true)
265
+ other_record = Class.new(described_class) do
266
+ prop :string_prop, :string
267
+ prop :integer_prop, :integer
268
+ prop :boolean_prop, :boolean
269
+ end.new(string_prop: "a", integer_prop: 1, boolean_prop: true)
270
+
271
+ expect(record <=> other_record).to be_nil
272
+ end
273
+
274
+ it "returns 0 if all record fields match", :skip_body_check do
275
+ record = comparable_record.new(string_prop: "a", integer_prop: 1, boolean_prop: true)
276
+ other_record = comparable_record.new(string_prop: "a", integer_prop: 1, boolean_prop: true)
277
+
278
+ expect(record <=> other_record).to eq(0)
279
+ end
280
+
281
+ it "returns non-zero if records differ", :skip_body_check do
282
+ record = comparable_record.new(string_prop: "a", integer_prop: 1, boolean_prop: true)
283
+ other_record = comparable_record.new(string_prop: "a", integer_prop: 1, boolean_prop: false)
284
+
285
+ expect(record <=> other_record).not_to eq(0)
286
+ end
287
+
288
+ it "recursively compares nested records", :skip_body_check do
289
+ record = comparable_record.new(property_prop: SBOM::CycloneDX::Record::Property.new(name: "a"))
290
+ matching_record = comparable_record.new(property_prop: SBOM::CycloneDX::Record::Property.new(name: "a"))
291
+ mismatching_record = comparable_record.new(property_prop: SBOM::CycloneDX::Record::Property.new(name: "b"))
292
+
293
+ expect(record <=> matching_record).to eq(0)
294
+ expect(record <=> mismatching_record).not_to eq(0)
295
+ end
296
+ end
297
+
298
+ describe "#valid?" do
299
+ subject(:record_class) do
300
+ allow(described_class).to receive(:in_subclass_body?).and_return(true)
301
+
302
+ Class.new(described_class) do
303
+ prop :string_prop, :string
304
+ prop :other_string_prop, :string
305
+ prop :integer_prop, :integer, maximum: 10
306
+ prop :other_integer_prop, :integer
307
+ prop :float_prop, :float
308
+ prop :boolean_prop, :boolean
309
+ validate :string_prop, :other_string_prop, presence: :one
310
+ validate :integer_prop, :other_integer_prop, presence: :any
311
+ validate :float_prop, :boolean_prop, presence: :all
312
+ end
313
+ end
314
+
315
+ it "returns true if all fields are valid" do
316
+ record = record_class.new(string_prop: "a", integer_prop: 1, float_prop: 2.0, boolean_prop: false)
317
+ expect(record).to be_valid
318
+ end
319
+
320
+ it "returns false if any field is invalid" do
321
+ record = record_class.new(string_prop: "a", integer_prop: 11, float_prop: 2.0, boolean_prop: false)
322
+ expect(record).not_to be_valid
323
+ end
324
+
325
+ it "runs presence validations" do
326
+ expect(
327
+ record_class
328
+ .new(string_prop: "a", other_string_prop: "b", integer_prop: 1, float_prop: 2.0, boolean_prop: false)
329
+ ).not_to be_valid
330
+
331
+ expect(record_class.new(string_prop: "a", float_prop: 2.0, boolean_prop: false)).not_to be_valid
332
+ expect(record_class.new(string_prop: "a", integer_prop: 1, float_prop: 2.0)).not_to be_valid
333
+ end
334
+
335
+ it "populates the errors hash" do
336
+ record = record_class.new(string_prop: "a", integer_prop: 1, float_prop: 2.0, boolean_prop: false)
337
+ expect(record).to be_valid
338
+ expect(record.errors.values.all?(&:empty?)).to be(true)
339
+
340
+ record.integer_prop = 11
341
+ expect(record).not_to be_valid
342
+ expect(record.errors[:integer_prop]).to eq(["Value is not within range"])
343
+ end
344
+
345
+ context "when custom validations are present" do
346
+ it "runs the custom validations"
347
+ it "does not add any errors when custom validations return \"\", true, or nil"
348
+ it "adds an error when custom validations return a string"
349
+ it "adds multiple errors when custom validations return an array of strings"
350
+ it "adds a basic error when custom validations return false"
351
+ it "adds the stringified return value when custom validations return an unexpected value"
352
+ end
353
+ end
354
+
355
+ describe "#valid!" do
356
+ it "raises an error if the record is invalid"
357
+ it "does not raise an error if the record is valid"
358
+ end
359
+
360
+ describe "#formatted_errors" do
361
+ it "returns a formatted string of errors"
362
+ end
363
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/cipher_suite"
5
+
6
+ describe SBOM::CycloneDX::Record::CipherSuite do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:cipher_suite) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:cipher_suite, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/co2_measure"
5
+
6
+ describe SBOM::CycloneDX::Record::CO2Measure do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:co2_measure) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:co2_measure, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/command"
5
+
6
+ describe SBOM::CycloneDX::Record::Command do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:command) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:command, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/commit"
5
+
6
+ describe SBOM::CycloneDX::Record::Commit do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:commit) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:commit, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/component_data"
5
+
6
+ describe SBOM::CycloneDX::Record::ComponentData do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:component_data) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:component_data, :all_fields) }.not_to raise_error
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "sbom/cyclone_dx/record/component_evidence"
5
+
6
+ describe SBOM::CycloneDX::Record::ComponentEvidence do
7
+ it "can be initialized with minimum required attributes" do
8
+ expect { build(:component_evidence) }.not_to raise_error
9
+ end
10
+
11
+ it "can be initialized with all attributes" do
12
+ expect { build(:component_evidence, :all_fields) }.not_to raise_error
13
+ end
14
+ end