shoulda-matchers 3.1.0 → 5.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 (288) hide show
  1. checksums.yaml +5 -5
  2. data/{MIT-LICENSE → LICENSE} +1 -1
  3. data/README.md +407 -232
  4. data/docs/errors/NonCaseSwappableValueError.md +2 -2
  5. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +7 -80
  6. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +4 -3
  7. data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
  8. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +36 -30
  9. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +8 -10
  10. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +7 -9
  11. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +18 -15
  12. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +3 -2
  13. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +3 -3
  14. data/lib/shoulda/matchers/action_controller/route_matcher.rb +88 -29
  15. data/lib/shoulda/matchers/action_controller/route_params.rb +2 -2
  16. data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +4 -4
  17. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -3
  18. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
  19. data/lib/shoulda/matchers/action_controller.rb +2 -0
  20. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
  21. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -9
  22. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
  23. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
  24. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
  25. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +42 -39
  26. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
  27. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +52 -26
  28. data/lib/shoulda/matchers/active_model/helpers.rb +2 -2
  29. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -30
  30. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +2 -1
  31. data/lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb +26 -0
  32. data/lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb +26 -0
  33. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
  34. data/lib/shoulda/matchers/active_model/qualifiers.rb +2 -0
  35. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -6
  36. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +8 -3
  37. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +31 -16
  38. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +52 -16
  39. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +137 -84
  40. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +159 -46
  41. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +130 -66
  42. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +251 -24
  43. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +12 -9
  44. data/lib/shoulda/matchers/active_model/validation_matcher.rb +38 -6
  45. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
  46. data/lib/shoulda/matchers/active_model/validator.rb +4 -9
  47. data/lib/shoulda/matchers/active_model.rb +3 -5
  48. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +10 -7
  49. data/lib/shoulda/matchers/active_record/association_matcher.rb +386 -111
  50. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
  51. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
  52. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
  53. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
  54. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +14 -15
  55. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +30 -8
  56. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +34 -11
  57. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +69 -0
  58. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
  59. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +74 -0
  60. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
  61. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
  62. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +458 -42
  63. data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +185 -0
  64. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +63 -23
  65. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +164 -48
  66. data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
  67. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +13 -11
  68. data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
  69. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +132 -0
  70. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +18 -18
  71. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
  72. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
  73. data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
  74. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +430 -200
  75. data/lib/shoulda/matchers/active_record.rb +28 -20
  76. data/lib/shoulda/matchers/configuration.rb +12 -1
  77. data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
  78. data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
  79. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
  80. data/lib/shoulda/matchers/doublespeak/object_double.rb +6 -2
  81. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
  82. data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
  83. data/lib/shoulda/matchers/doublespeak.rb +2 -1
  84. data/lib/shoulda/matchers/error.rb +1 -1
  85. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +109 -29
  86. data/lib/shoulda/matchers/independent.rb +2 -2
  87. data/lib/shoulda/matchers/integrations/configuration.rb +8 -4
  88. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
  89. data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
  90. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
  91. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
  92. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
  93. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
  94. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
  95. data/lib/shoulda/matchers/rails_shim.rb +172 -51
  96. data/lib/shoulda/matchers/routing.rb +2 -2
  97. data/lib/shoulda/matchers/util/word_wrap.rb +17 -12
  98. data/lib/shoulda/matchers/util.rb +39 -5
  99. data/lib/shoulda/matchers/version.rb +1 -1
  100. data/lib/shoulda/matchers/warn.rb +4 -3
  101. data/shoulda-matchers.gemspec +33 -15
  102. metadata +31 -338
  103. data/.gitignore +0 -12
  104. data/.hound.yml +0 -3
  105. data/.hound_config/ruby.yml +0 -12
  106. data/.travis.yml +0 -19
  107. data/.yardopts +0 -10
  108. data/Appraisals +0 -73
  109. data/CONTRIBUTING.md +0 -101
  110. data/Gemfile +0 -15
  111. data/Gemfile.lock +0 -70
  112. data/NEWS.md +0 -986
  113. data/Rakefile +0 -39
  114. data/custom_plan.rb +0 -88
  115. data/doc_config/gh-pages/index.html.erb +0 -9
  116. data/doc_config/yard/setup.rb +0 -22
  117. data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -5967
  118. data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +0 -12
  119. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +0 -62
  120. data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +0 -69
  121. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +0 -312
  122. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -32
  123. data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +0 -1
  124. data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +0 -8
  125. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -298
  126. data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +0 -1
  127. data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +0 -289
  128. data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +0 -6
  129. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +0 -8
  130. data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +0 -14
  131. data/doc_config/yard/templates/default/layout/html/fonts.erb +0 -1
  132. data/doc_config/yard/templates/default/layout/html/footer.erb +0 -6
  133. data/doc_config/yard/templates/default/layout/html/layout.erb +0 -23
  134. data/doc_config/yard/templates/default/layout/html/search.erb +0 -13
  135. data/doc_config/yard/templates/default/layout/html/setup.rb +0 -40
  136. data/doc_config/yard/templates/default/method_details/html/source.erb +0 -10
  137. data/doc_config/yard/templates/default/module/html/box_info.erb +0 -31
  138. data/gemfiles/4.0.0.gemfile +0 -38
  139. data/gemfiles/4.0.0.gemfile.lock +0 -223
  140. data/gemfiles/4.0.1.gemfile +0 -38
  141. data/gemfiles/4.0.1.gemfile.lock +0 -225
  142. data/gemfiles/4.1.gemfile +0 -38
  143. data/gemfiles/4.1.gemfile.lock +0 -220
  144. data/gemfiles/4.2.gemfile +0 -38
  145. data/gemfiles/4.2.gemfile.lock +0 -243
  146. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
  147. data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
  148. data/script/SUPPORTED_VERSIONS +0 -1
  149. data/script/install_gems_in_all_appraisals +0 -14
  150. data/script/run_all_tests +0 -14
  151. data/script/update_gem_in_all_appraisals +0 -15
  152. data/script/update_gems_in_all_appraisals +0 -14
  153. data/spec/acceptance/active_model_integration_spec.rb +0 -23
  154. data/spec/acceptance/independent_matchers_spec.rb +0 -125
  155. data/spec/acceptance/multiple_libraries_integration_spec.rb +0 -55
  156. data/spec/acceptance/rails_integration_spec.rb +0 -156
  157. data/spec/acceptance_spec_helper.rb +0 -23
  158. data/spec/doublespeak_spec_helper.rb +0 -2
  159. data/spec/report_warnings.rb +0 -7
  160. data/spec/spec_helper.rb +0 -21
  161. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +0 -133
  162. data/spec/support/acceptance/helpers/active_model_helpers.rb +0 -11
  163. data/spec/support/acceptance/helpers/array_helpers.rb +0 -13
  164. data/spec/support/acceptance/helpers/base_helpers.rb +0 -19
  165. data/spec/support/acceptance/helpers/command_helpers.rb +0 -55
  166. data/spec/support/acceptance/helpers/file_helpers.rb +0 -19
  167. data/spec/support/acceptance/helpers/gem_helpers.rb +0 -31
  168. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -11
  169. data/spec/support/acceptance/helpers/n_unit_helpers.rb +0 -25
  170. data/spec/support/acceptance/helpers/pluralization_helpers.rb +0 -13
  171. data/spec/support/acceptance/helpers/rails_version_helpers.rb +0 -11
  172. data/spec/support/acceptance/helpers/rspec_helpers.rb +0 -24
  173. data/spec/support/acceptance/helpers/ruby_version_helpers.rb +0 -9
  174. data/spec/support/acceptance/helpers/step_helpers.rb +0 -127
  175. data/spec/support/acceptance/helpers.rb +0 -31
  176. data/spec/support/acceptance/matchers/have_output.rb +0 -31
  177. data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +0 -55
  178. data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +0 -103
  179. data/spec/support/tests/bundle.rb +0 -94
  180. data/spec/support/tests/command_runner.rb +0 -230
  181. data/spec/support/tests/current_bundle.rb +0 -61
  182. data/spec/support/tests/database.rb +0 -28
  183. data/spec/support/tests/database_adapters/postgresql.rb +0 -25
  184. data/spec/support/tests/database_adapters/sqlite3.rb +0 -26
  185. data/spec/support/tests/database_configuration.rb +0 -33
  186. data/spec/support/tests/database_configuration_registry.rb +0 -28
  187. data/spec/support/tests/filesystem.rb +0 -100
  188. data/spec/support/tests/version.rb +0 -45
  189. data/spec/support/unit/active_record/create_table.rb +0 -54
  190. data/spec/support/unit/attribute.rb +0 -47
  191. data/spec/support/unit/capture.rb +0 -40
  192. data/spec/support/unit/change_value.rb +0 -111
  193. data/spec/support/unit/create_model_arguments/basic.rb +0 -135
  194. data/spec/support/unit/create_model_arguments/has_many.rb +0 -15
  195. data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +0 -74
  196. data/spec/support/unit/helpers/active_model_helpers.rb +0 -27
  197. data/spec/support/unit/helpers/active_model_versions.rb +0 -28
  198. data/spec/support/unit/helpers/active_record_versions.rb +0 -24
  199. data/spec/support/unit/helpers/active_resource_builder.rb +0 -27
  200. data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +0 -15
  201. data/spec/support/unit/helpers/class_builder.rb +0 -90
  202. data/spec/support/unit/helpers/column_type_helpers.rb +0 -26
  203. data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +0 -17
  204. data/spec/support/unit/helpers/controller_builder.rb +0 -63
  205. data/spec/support/unit/helpers/database_helpers.rb +0 -20
  206. data/spec/support/unit/helpers/i18n_faker.rb +0 -15
  207. data/spec/support/unit/helpers/mailer_builder.rb +0 -12
  208. data/spec/support/unit/helpers/model_builder.rb +0 -114
  209. data/spec/support/unit/helpers/rails_versions.rb +0 -28
  210. data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +0 -44
  211. data/spec/support/unit/i18n.rb +0 -7
  212. data/spec/support/unit/load_environment.rb +0 -12
  213. data/spec/support/unit/matchers/deprecate.rb +0 -60
  214. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +0 -51
  215. data/spec/support/unit/matchers/fail_with_message_matcher.rb +0 -62
  216. data/spec/support/unit/matchers/print_warning_including.rb +0 -59
  217. data/spec/support/unit/model_creation_strategies/active_model.rb +0 -111
  218. data/spec/support/unit/model_creation_strategies/active_record.rb +0 -77
  219. data/spec/support/unit/model_creators/active_model.rb +0 -39
  220. data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +0 -95
  221. data/spec/support/unit/model_creators/active_record/has_many.rb +0 -67
  222. data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +0 -42
  223. data/spec/support/unit/model_creators/active_record.rb +0 -43
  224. data/spec/support/unit/model_creators/basic.rb +0 -97
  225. data/spec/support/unit/model_creators.rb +0 -19
  226. data/spec/support/unit/rails_application.rb +0 -126
  227. data/spec/support/unit/record_builder_with_i18n_validation_message.rb +0 -69
  228. data/spec/support/unit/record_validating_confirmation_builder.rb +0 -51
  229. data/spec/support/unit/record_with_different_error_attribute_builder.rb +0 -92
  230. data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +0 -79
  231. data/spec/support/unit/shared_examples/numerical_submatcher.rb +0 -17
  232. data/spec/support/unit/shared_examples/set_session_or_flash.rb +0 -360
  233. data/spec/support/unit/validation_matcher_scenario.rb +0 -62
  234. data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +0 -82
  235. data/spec/unit/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +0 -28
  236. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +0 -592
  237. data/spec/unit/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +0 -42
  238. data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +0 -76
  239. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +0 -62
  240. data/spec/unit/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +0 -90
  241. data/spec/unit/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +0 -31
  242. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -330
  243. data/spec/unit/shoulda/matchers/action_controller/route_params_spec.rb +0 -30
  244. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +0 -67
  245. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -17
  246. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +0 -562
  247. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -115
  248. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +0 -823
  249. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -86
  250. data/spec/unit/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +0 -20
  251. data/spec/unit/shoulda/matchers/active_model/helpers_spec.rb +0 -162
  252. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +0 -266
  253. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +0 -91
  254. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -149
  255. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -207
  256. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -1015
  257. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -288
  258. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +0 -1837
  259. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -380
  260. data/spec/unit/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -107
  261. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +0 -1242
  262. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +0 -251
  263. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +0 -168
  264. data/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +0 -111
  265. data/spec/unit/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +0 -85
  266. data/spec/unit/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +0 -41
  267. data/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb +0 -86
  268. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +0 -1418
  269. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +0 -190
  270. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +0 -21
  271. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +0 -271
  272. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +0 -77
  273. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +0 -72
  274. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +0 -101
  275. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +0 -80
  276. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +0 -27
  277. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +0 -43
  278. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -517
  279. data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +0 -242
  280. data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +0 -252
  281. data/spec/unit_spec_helper.rb +0 -46
  282. data/spec/warnings_spy/filesystem.rb +0 -45
  283. data/spec/warnings_spy/partitioner.rb +0 -36
  284. data/spec/warnings_spy/reader.rb +0 -53
  285. data/spec/warnings_spy/reporter.rb +0 -88
  286. data/spec/warnings_spy.rb +0 -64
  287. data/tasks/documentation.rb +0 -199
  288. data/zeus.json +0 -11
@@ -1,242 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe 'Shoulda::Matchers::Routing::RouteMatcher', type: :routing do
4
- before do
5
- define_controller('ThingsController')
6
- end
7
-
8
- shared_examples_for 'core tests' do
9
- context 'when the given method, path, controller, and action match an existing route' do
10
- it 'accepts' do
11
- define_routes { get '/', to: 'things#index' }
12
-
13
- assert_accepts add_target_to(
14
- route(:get, '/'),
15
- controller: 'things',
16
- action: 'index'
17
- )
18
- end
19
-
20
- context 'and the expected controller is specified as a symbol' do
21
- it 'accepts' do
22
- define_routes { get '/', to: 'things#index' }
23
-
24
- assert_accepts add_target_to(
25
- route(:get, '/'),
26
- controller: :things,
27
- action: 'index'
28
- )
29
- end
30
- end
31
-
32
- context 'and the expected action is specified as a symbol' do
33
- it 'accepts' do
34
- define_routes { get '/', to: 'things#index' }
35
-
36
- assert_accepts add_target_to(
37
- route(:get, '/'),
38
- controller: 'things',
39
- action: :index
40
- )
41
- end
42
- end
43
- end
44
-
45
- context 'when the given method, path, controller, and action do not match an existing route' do
46
- it 'rejects' do
47
- assert_rejects add_target_to(
48
- route(:get, '/non_existent_route'),
49
- controller: 'no_controller',
50
- action: 'no_action'
51
- )
52
- end
53
- end
54
-
55
- context 'when the given path, controller, and action match an existing route but the method does not' do
56
- it 'rejects' do
57
- define_routes { post '/', to: 'things#index' }
58
-
59
- assert_rejects add_target_to(
60
- route(:get, '/'),
61
- controller: 'things',
62
- action: 'index'
63
- )
64
- end
65
- end
66
-
67
- context 'when the given method, controller, and action match an existing route but the path does not' do
68
- it 'rejects' do
69
- define_routes { get '/', to: 'things#index' }
70
-
71
- assert_rejects add_target_to(
72
- route(:get, '/different_path'),
73
- controller: 'things',
74
- action: 'index'
75
- )
76
- end
77
- end
78
-
79
- context 'when the given method and path match an existing route but the controller does not' do
80
- it 'rejects' do
81
- define_routes { get '/', to: 'another_controller#index' }
82
-
83
- assert_rejects add_target_to(
84
- route(:get, '/'),
85
- controller: 'things',
86
- action: 'index'
87
- )
88
- end
89
- end
90
-
91
- context 'when the given method, path, and controller match an existing route but the action does not' do
92
- it 'rejects' do
93
- define_routes { get '/', to: 'things#index' }
94
-
95
- assert_rejects add_target_to(
96
- route(:get, '/'),
97
- controller: 'things',
98
- action: 'another_action'
99
- )
100
- end
101
- end
102
-
103
- context 'when the actual route has a param' do
104
- context 'and the expected params include that param' do
105
- it 'accepts' do
106
- define_routes { get '/things/:id', to: 'things#show' }
107
-
108
- assert_accepts add_target_to(
109
- route(:get, '/things/1'),
110
- controller: 'things',
111
- action: 'show',
112
- id: '1'
113
- )
114
- end
115
-
116
- context 'but its value was not specified as a string' do
117
- it 'accepts, treating it as a string' do
118
- define_routes { get '/things/:id', to: 'things#show' }
119
-
120
- assert_accepts add_target_to(
121
- route(:get, '/things/1'),
122
- controller: 'things',
123
- action: 'show',
124
- id: 1
125
- )
126
- end
127
- end
128
- end
129
-
130
- context 'and the expected params do not match the actual params' do
131
- it 'rejects' do
132
- define_routes { get '/things/:id', to: 'things#show' }
133
-
134
- params = {
135
- controller: 'things',
136
- action: 'show',
137
- some: 'other',
138
- params: 'here'
139
- }
140
- assert_rejects add_target_to(
141
- route(:get, '/things/:id'),
142
- params
143
- )
144
- end
145
- end
146
- end
147
-
148
- context 'when the actual route has a default param whose value is a symbol' do
149
- context 'and the expected params include a value for it' do
150
- context 'as a symbol' do
151
- it 'accepts' do
152
- define_routes do
153
- post '/things(.:format)',
154
- to: 'things#create',
155
- defaults: { format: :json }
156
- end
157
-
158
- assert_accepts add_target_to(
159
- route(:post, '/things'),
160
- controller: 'things',
161
- action: 'create',
162
- format: :json
163
- )
164
- end
165
- end
166
-
167
- context 'as a string' do
168
- it 'accepts' do
169
- define_routes do
170
- post '/things(.:format)',
171
- to: 'things#create',
172
- defaults: { format: :json }
173
- end
174
-
175
- assert_accepts add_target_to(
176
- route(:post, '/things'),
177
- controller: 'things',
178
- action: 'create',
179
- format: 'json'
180
- )
181
- end
182
- end
183
- end
184
- end
185
-
186
- context 'when the existing route has a glob segment' do
187
- context 'and a param is given which represents the segment' do
188
- it 'accepts' do
189
- define_routes { get '/things/*id', to: 'things#whatever' }
190
-
191
- assert_accepts add_target_to(
192
- route(:get, '/things/foo/bar'),
193
- controller: 'things',
194
- action: 'whatever',
195
- id: 'foo/bar'
196
- )
197
- end
198
- end
199
-
200
- context 'and no param is given which represents the segment' do
201
- it 'rejects' do
202
- define_routes { get '/things/*id', to: 'things#whatever' }
203
-
204
- assert_rejects add_target_to(
205
- route(:get, '/things'),
206
- controller: 'things',
207
- action: 'whatever'
208
- )
209
- end
210
- end
211
- end
212
- end
213
-
214
- context 'given a controller and action specified as individual options' do
215
- include_examples 'core tests'
216
-
217
- def add_target_to(route_matcher, params)
218
- route_matcher.to(params)
219
- end
220
- end
221
-
222
- context 'given a controller and action joined together in a string' do
223
- include_examples 'core tests'
224
-
225
- def add_target_to(route_matcher, args)
226
- controller = args.fetch(:controller)
227
- action = args.fetch(:action)
228
- route_matcher.to(
229
- "#{controller}##{action}",
230
- args.except(:controller, :action)
231
- )
232
- end
233
- end
234
-
235
- def assert_accepts(matcher)
236
- should(matcher)
237
- end
238
-
239
- def assert_rejects(matcher)
240
- should_not(matcher)
241
- end
242
- end
@@ -1,252 +0,0 @@
1
- require 'spec_helper'
2
- require 'shoulda/matchers/util/word_wrap'
3
-
4
- describe Shoulda::Matchers, ".word_wrap" do
5
- it "can wrap a simple paragraph" do
6
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
7
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat
8
- MESSAGE
9
-
10
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
11
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus,
12
- ipsum sit amet efficitur feugiat
13
- MESSAGE
14
- end
15
-
16
- it "does not split words up when wrapping" do
17
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
18
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean lusciousness, ipsum sit amet efficitur feugiat
19
- MESSAGE
20
-
21
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
22
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
23
- lusciousness, ipsum sit amet efficitur feugiat
24
- MESSAGE
25
- end
26
-
27
- it "considers punctuation as part of a word" do
28
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
29
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luscious, ipsum sit amet efficitur feugiat
30
- MESSAGE
31
-
32
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
33
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
34
- luscious, ipsum sit amet efficitur feugiat
35
- MESSAGE
36
- end
37
-
38
- it "does not break at the maximum line length, but afterward" do
39
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
40
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luscius, ipsum sit amet efficitur feugiat
41
- MESSAGE
42
-
43
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
44
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luscius,
45
- ipsum sit amet efficitur feugiat
46
- MESSAGE
47
- end
48
-
49
- it "re-wraps entire paragraphs" do
50
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
51
- Lorem ipsum dolor sit amet,
52
- consectetur adipiscing elit.
53
- Aenean luctus,
54
- ipsum sit amet efficitur feugiat,
55
- dolor mauris fringilla erat, sed posuere diam ex ut velit.
56
- MESSAGE
57
-
58
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
59
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus,
60
- ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed
61
- posuere diam ex ut velit.
62
- MESSAGE
63
- end
64
-
65
- it "can wrap multiple paragraphs" do
66
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
67
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
68
-
69
- Etiam ultrices cursus ligula eget feugiat. Vestibulum eget tincidunt risus, non faucibus sem.
70
- MESSAGE
71
-
72
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
73
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus,
74
- ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed
75
- posuere diam ex ut velit.
76
-
77
- Etiam ultrices cursus ligula eget feugiat. Vestibulum eget tincidunt
78
- risus, non faucibus sem.
79
- MESSAGE
80
- end
81
-
82
- it "can wrap a bulleted list" do
83
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
84
- * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
85
- * And the beat goes on.
86
- MESSAGE
87
-
88
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
89
- * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
90
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat,
91
- sed posuere diam ex ut velit.
92
- * And the beat goes on.
93
- MESSAGE
94
- end
95
-
96
- it "re-wraps bulleted lists" do
97
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
98
- * Lorem ipsum dolor sit amet,
99
- consectetur adipiscing elit.
100
- Aenean luctus,
101
- ipsum sit amet efficitur feugiat,
102
- dolor mauris fringilla erat,
103
- sed posuere diam ex ut velit.
104
- * And the beat goes on.
105
- MESSAGE
106
-
107
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
108
- * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
109
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat,
110
- sed posuere diam ex ut velit.
111
- * And the beat goes on.
112
- MESSAGE
113
- end
114
-
115
- it "can wrap a numbered list" do
116
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
117
- 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
118
- 2. And the beat goes on.
119
- MESSAGE
120
-
121
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
122
- 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
123
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla
124
- erat, sed posuere diam ex ut velit.
125
- 2. And the beat goes on.
126
- MESSAGE
127
- end
128
-
129
- it "re-wraps numbered lists" do
130
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
131
- 1. Lorem ipsum dolor sit amet,
132
- consectetur adipiscing elit.
133
- Aenean luctus,
134
- ipsum sit amet efficitur feugiat,
135
- dolor mauris fringilla erat,
136
- sed posuere diam ex ut velit.
137
- 2. And the beat goes on.
138
- MESSAGE
139
-
140
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
141
- 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
142
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla
143
- erat, sed posuere diam ex ut velit.
144
- 2. And the beat goes on.
145
- MESSAGE
146
- end
147
-
148
- it "can wrap a numbered list, using x) instead of x. as the leader" do
149
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
150
- 1) Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
151
- 2) And the beat goes on.
152
- MESSAGE
153
-
154
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
155
- 1) Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
156
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla
157
- erat, sed posuere diam ex ut velit.
158
- 2) And the beat goes on.
159
- MESSAGE
160
- end
161
-
162
- it "re-wraps numbered lists using x) instead of x. as the leader" do
163
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
164
- 1) Lorem ipsum dolor sit amet,
165
- consectetur adipiscing elit.
166
- Aenean luctus,
167
- ipsum sit amet efficitur feugiat,
168
- dolor mauris fringilla erat,
169
- sed posuere diam ex ut velit.
170
- 2) And the beat goes on.
171
- MESSAGE
172
-
173
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
174
- 1) Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
175
- luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla
176
- erat, sed posuere diam ex ut velit.
177
- 2) And the beat goes on.
178
- MESSAGE
179
- end
180
-
181
- it "doesn't mess with indented blocks" do
182
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
183
- Some text is gonna go here.
184
-
185
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
186
-
187
- And now we return.
188
- MESSAGE
189
-
190
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
191
- Some text is gonna go here.
192
-
193
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
194
-
195
- And now we return.
196
- MESSAGE
197
- end
198
-
199
- context "given a string with a word longer than the max character limit" do
200
- context "which stands on its own" do
201
- it "simply returns the string" do
202
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
203
- Foo bar baz and stuff and things Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat,
204
- MESSAGE
205
-
206
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
207
- Foo bar baz and stuff and things
208
- Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat,
209
- MESSAGE
210
- end
211
- end
212
-
213
- context "which is preceded by some text" do
214
- it "leaves the word on its own line" do
215
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
216
- Foo bar baz and stuff and things Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat,
217
- MESSAGE
218
-
219
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
220
- Foo bar baz and stuff and things
221
- Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat,
222
- MESSAGE
223
- end
224
- end
225
-
226
- context "which is followed by some text" do
227
- it "leaves the word on its own line" do
228
- wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
229
- Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat, and something goes after this
230
- MESSAGE
231
-
232
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
233
- Loremipsumdolorsitamet,consecteturadipiscingelit.Aeneanluctus,ipsumsitametefficiturfeugiat,
234
- and something goes after this
235
- MESSAGE
236
- end
237
- end
238
- end
239
-
240
- context "when :indent is given" do
241
- it "uses the given indentation level when determining where to wrap lines" do
242
- wrapped_message = described_class.word_wrap(<<-MESSAGE.strip, indent: 2)
243
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat
244
- MESSAGE
245
-
246
- expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
247
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
248
- luctus, ipsum sit amet efficitur feugiat
249
- MESSAGE
250
- end
251
- end
252
- end
@@ -1,46 +0,0 @@
1
- require_relative 'support/unit/load_environment'
2
-
3
- require 'rspec/rails'
4
- require 'shoulda-matchers'
5
-
6
- require 'spec_helper'
7
-
8
- Dir[ File.join(File.expand_path('../support/unit/**/*.rb', __FILE__)) ].sort.each do |file|
9
- require file
10
- end
11
-
12
- RSpec.configure do |config|
13
- UnitTests::ActiveModelHelpers.configure_example_group(config)
14
- UnitTests::ActiveModelVersions.configure_example_group(config)
15
- UnitTests::ActiveResourceBuilder.configure_example_group(config)
16
- UnitTests::ClassBuilder.configure_example_group(config)
17
- UnitTests::ControllerBuilder.configure_example_group(config)
18
- UnitTests::I18nFaker.configure_example_group(config)
19
- UnitTests::MailerBuilder.configure_example_group(config)
20
- UnitTests::ModelBuilder.configure_example_group(config)
21
- UnitTests::RailsVersions.configure_example_group(config)
22
- UnitTests::ActiveRecordVersions.configure_example_group(config)
23
- UnitTests::ActiveModelVersions.configure_example_group(config)
24
- UnitTests::DatabaseHelpers.configure_example_group(config)
25
- UnitTests::ColumnTypeHelpers.configure_example_group(config)
26
- UnitTests::ValidationMatcherScenarioHelpers.configure_example_group(config)
27
-
28
- config.include UnitTests::Matchers
29
-
30
- config.infer_spec_type_from_file_location!
31
- config.example_status_persistence_file_path = "spec/examples.txt"
32
- config.alias_it_behaves_like_to(:it_supports, "it supports")
33
-
34
- config.before(:all, type: :controller) do
35
- self.class.controller(ApplicationController) { }
36
- end
37
- end
38
-
39
- ActiveSupport::Deprecation.behavior = :stderr
40
-
41
- Shoulda::Matchers.configure do |config|
42
- config.integrate do |with|
43
- with.test_framework :rspec
44
- with.library :rails
45
- end
46
- end
@@ -1,45 +0,0 @@
1
- require 'fileutils'
2
-
3
- class WarningsSpy
4
- class Filesystem
5
- PROJECT_DIR = File.expand_path('../../..', __FILE__)
6
- TEMP_DIR = File.join(PROJECT_DIR, 'tmp')
7
-
8
- def initialize
9
- @files_by_name = Hash.new do |hash, name|
10
- FileUtils.mkdir_p(TEMP_DIR)
11
- hash[name] = file_for(name)
12
- end
13
- end
14
-
15
- def warnings_file
16
- files_by_name['all_warnings']
17
- end
18
-
19
- def irrelevant_warnings_file
20
- files_by_name['irrelevant_warnings']
21
- end
22
-
23
- def relevant_warnings_file
24
- files_by_name['relevant_warnings']
25
- end
26
-
27
- def project_dir
28
- PROJECT_DIR
29
- end
30
-
31
- protected
32
-
33
- attr_reader :files_by_name
34
-
35
- private
36
-
37
- def path_for(name)
38
- File.join(TEMP_DIR, "#{name}.txt")
39
- end
40
-
41
- def file_for(name)
42
- File.open(path_for(name), 'w+')
43
- end
44
- end
45
- end
@@ -1,36 +0,0 @@
1
- require 'forwardable'
2
-
3
- class WarningsSpy
4
- class Partitioner
5
- extend Forwardable
6
-
7
- attr_reader :relevant_warning_groups, :irrelevant_warning_groups
8
-
9
- def initialize(reader, filesystem)
10
- @reader = reader
11
- @search_text = filesystem.project_dir
12
- end
13
-
14
- def partition
15
- @relevant_warning_groups, @irrelevant_warning_groups =
16
- warning_groups.partition { |group| relevant_warnings?(group) }
17
- end
18
-
19
- protected
20
-
21
- attr_reader :reader, :search_text
22
-
23
- private
24
-
25
- def_delegators :reader, :warning_groups
26
-
27
- def relevant_warnings?(group)
28
- first_line = group[0]
29
- first_line.start_with?("#{project_root}/lib")
30
- end
31
-
32
- def project_root
33
- File.expand_path('../../..')
34
- end
35
- end
36
- end
@@ -1,53 +0,0 @@
1
- class WarningsSpy
2
- class Reader
3
- attr_reader :warning_groups
4
-
5
- def initialize(filesystem)
6
- @warnings_file = filesystem.warnings_file
7
-
8
- @current_group = []
9
- @warning_groups = []
10
- end
11
-
12
- def read
13
- warnings_file.rewind
14
-
15
- warnings_file.each_line do |line|
16
- process_line(line)
17
- end
18
-
19
- add_group(current_group)
20
- end
21
-
22
- protected
23
-
24
- attr_reader :warnings_file, :current_group
25
-
26
- private
27
-
28
- def process_line(line)
29
- if start_of_group?(line)
30
- add_group(current_group)
31
- @current_group = []
32
- end
33
-
34
- current_group << line
35
- end
36
-
37
- def start_of_group?(line)
38
- line =~ /^\S/
39
- end
40
-
41
- def add_group(group)
42
- unless group.empty? || group_already_added?(group)
43
- warning_groups << group
44
- end
45
- end
46
-
47
- def group_already_added?(group_to_be_added)
48
- warning_groups.any? do |group|
49
- group == group_to_be_added
50
- end
51
- end
52
- end
53
- end