shoulda_matchmakers 0.1.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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +21 -0
  4. data/lib/controller/action_controller/action_controller_controller_sm_model.rb +53 -0
  5. data/lib/controller/action_controller/action_controller_controller_sm_model_helper.rb +73 -0
  6. data/lib/controller/action_controller/matchmakers/callbacks.rb +56 -0
  7. data/lib/controller/action_controller/matchmakers/filter_param.rb +69 -0
  8. data/lib/controller/action_controller/matchmakers/permit.rb +510 -0
  9. data/lib/controller/action_controller/matchmakers/redirect_to.rb +126 -0
  10. data/lib/controller/action_controller/matchmakers/render_template.rb +198 -0
  11. data/lib/controller/action_controller/matchmakers/render_with_layout.rb +72 -0
  12. data/lib/controller/action_controller/matchmakers/rescue_from.rb +96 -0
  13. data/lib/controller/action_controller/matchmakers/respond_with.rb +71 -0
  14. data/lib/controller/action_controller/matchmakers/route.rb +586 -0
  15. data/lib/controller/action_controller/matchmakers/set_flash.rb +136 -0
  16. data/lib/controller/action_controller/matchmakers/set_session.rb +115 -0
  17. data/lib/controller/action_controller/permitted_params_definition.rb +60 -0
  18. data/lib/generators/shoulda_matchmakers/controller_matcher_generator.rb +87 -0
  19. data/lib/generators/shoulda_matchmakers/controller_matcher_generator_helper.rb +92 -0
  20. data/lib/generators/shoulda_matchmakers/factory_generator.rb +86 -0
  21. data/lib/generators/shoulda_matchmakers/install_generator.rb +10 -0
  22. data/lib/generators/shoulda_matchmakers/model_matcher_generator.rb +87 -0
  23. data/lib/generators/shoulda_matchmakers/model_matcher_generator_helper.rb +107 -0
  24. data/lib/model/active_record/active_record_model_sm_model.rb +50 -0
  25. data/lib/model/active_record/active_record_model_sm_model_helper.rb +206 -0
  26. data/lib/model/active_record/factory_sm_model.rb +28 -0
  27. data/lib/model/active_record/factory_sm_model_helper.rb +124 -0
  28. data/lib/model/active_record/matchmakers/accept_nested_attributes_for.rb +66 -0
  29. data/lib/model/active_record/matchmakers/allow_value.rb +137 -0
  30. data/lib/model/active_record/matchmakers/associations.rb +52 -0
  31. data/lib/model/active_record/matchmakers/define_enum_for.rb +53 -0
  32. data/lib/model/active_record/matchmakers/delegate_method.rb +101 -0
  33. data/lib/model/active_record/matchmakers/have_db_column.rb +33 -0
  34. data/lib/model/active_record/matchmakers/have_db_index.rb +39 -0
  35. data/lib/model/active_record/matchmakers/have_readonly_attribute.rb +32 -0
  36. data/lib/model/active_record/matchmakers/have_secure_password.rb +32 -0
  37. data/lib/model/active_record/matchmakers/serialize.rb +67 -0
  38. data/lib/model/active_record/matchmakers/validations.rb +169 -0
  39. data/lib/model/active_record/options_definition.rb +160 -0
  40. data/lib/shoulda_matchmakers.rb +48 -0
  41. data/lib/shoulda_matchmakers/version.rb +3 -0
  42. data/lib/support/command_line_interface.rb +100 -0
  43. data/lib/support/controller_generator.rb +198 -0
  44. data/lib/support/indefinite_article.rb +70 -0
  45. data/lib/support/to_discard/belong_to.rb +94 -0
  46. data/lib/support/to_discard/have_and_belong_to_many.rb +83 -0
  47. data/lib/support/to_discard/have_many.rb +96 -0
  48. data/lib/support/to_discard/have_one.rb +98 -0
  49. data/lib/support/to_discard/permit_refactor.rb +270 -0
  50. data/lib/support/to_discard/render_template_new.rb +204 -0
  51. data/lib/support/to_discard/render_template_reconstruction.rb +188 -0
  52. data/lib/support/to_discard/use_around_action.rb +20 -0
  53. data/lib/support/to_discard/use_before_action.rb +20 -0
  54. data/lib/support/to_discard/validate_absence_of.rb +16 -0
  55. data/lib/support/to_discard/validate_acceptance_of.rb +16 -0
  56. data/lib/support/to_discard/validate_confirmation_of.rb +16 -0
  57. data/lib/support/to_discard/validate_exclusion_of.rb +145 -0
  58. data/lib/support/to_discard/validate_inclusion_of.rb +94 -0
  59. data/lib/support/to_discard/validate_length_of.rb +16 -0
  60. data/lib/support/to_discard/validate_numericality_of.rb +16 -0
  61. data/lib/support/to_discard/validate_presence_of.rb +16 -0
  62. data/lib/support/to_discard/validate_uniqueness_of.rb +16 -0
  63. data/lib/support/to_discard/validation_old.rb +37 -0
  64. data/lib/support/to_discard/validations.rb +41 -0
  65. data/lib/support/to_discard/validations_conditional.rb +146 -0
  66. data/lib/support/trace_debug_lines.txt +319 -0
  67. data/lib/support/util.rb +15 -0
  68. data/lib/templates/controller/action_controller/controller_spec_template.haml +146 -0
  69. data/lib/templates/factory/active_record/factory_template.haml +13 -0
  70. data/lib/templates/model/active_record/model_spec_template.haml +233 -0
  71. data/lib/templates/shoulda_matchmakers.rb +112 -0
  72. metadata +263 -0
@@ -0,0 +1,28 @@
1
+ require_relative 'active_record_model_sm_model_helper'
2
+ require_relative 'factory_sm_model_helper'
3
+
4
+ module ShouldaMatchmakers
5
+ module Model
6
+ module ActiveRecord
7
+ class FactorySmModel
8
+
9
+ ### Includes ###
10
+ include ActiveRecordModelSmModelHelper
11
+ include FactorySmModelHelper
12
+
13
+
14
+ ### Attribute Accessors ###
15
+ attr_accessor :app_class_name,
16
+ :working_generated_code_line_length
17
+
18
+
19
+ ### Methods ###
20
+ def initialize(app_class_name, code_line_length)
21
+ @app_class_name = app_class_name
22
+ @working_generated_code_line_length = code_line_length
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,124 @@
1
+ module ShouldaMatchmakers
2
+ module Model
3
+ module ActiveRecord
4
+ module FactorySmModelHelper
5
+
6
+
7
+ def factory_attributes
8
+ attributes_for_factory = get_validation_attributes(@app_class_name)
9
+ attributes_for_factory = attributes_for_factory | get_required_attributes(@app_class_name)
10
+ attributes_for_factory = attributes_for_factory - get_attributes_with_defaults(@app_class_name)
11
+ attributes_for_factory = attributes_for_factory.flatten.compact.uniq.sort
12
+ factory_attributes_string = ""
13
+ attributes_for_factory.each do |attribute|
14
+ factory_attributes_string.concat(" # " + attribute.to_s + "\n")
15
+ end
16
+ factory_attributes_string
17
+ end
18
+
19
+
20
+ private
21
+
22
+ def get_validation_attributes(app_class_name)
23
+ validation_attributes = []
24
+ validation_attributes = validation_attributes | get_absence_attributes(app_class_name)
25
+ validation_attributes = validation_attributes | get_acceptance_attributes(app_class_name)
26
+ validation_attributes = validation_attributes | get_confirmation_attributes(app_class_name)
27
+ validation_attributes = validation_attributes | get_exclusion_attributes(app_class_name)
28
+ validation_attributes = validation_attributes | get_inclusion_attributes(app_class_name)
29
+ validation_attributes = validation_attributes | get_length_attributes(app_class_name)
30
+ validation_attributes = validation_attributes | get_numericality_attributes(app_class_name)
31
+ validation_attributes = validation_attributes | get_presence_attributes(app_class_name)
32
+ validation_attributes | get_uniqueness_attributes(app_class_name)
33
+ end
34
+
35
+ def get_attributes_with_defaults(app_class_name)
36
+ app_class_name.constantize.columns.select{ |column| !column.default.nil? }.map(&:name).map(&:to_sym)
37
+ # The following line of code doesn't work for the class 'SuperAdminUser', but only that class.
38
+ # app_class_name.constantize.column_defaults.select{ |attribute, default| !default.nil? }.keys.map(&:to_sym)
39
+ end
40
+
41
+ def get_required_attributes(app_class_name)
42
+ required_attributes = []
43
+ required_attributes.concat(app_class_name.constantize.columns.select{ |column| !column.null }.map(&:name))
44
+ required_attributes.map(&:to_sym) - [:id, :encrypted_password, :created_at, :updated_at]
45
+ end
46
+
47
+ def get_absence_attributes(app_class_name)
48
+ absence_attributes = []
49
+ extract_validators(app_class_name, ::ActiveModel::Validations::AbsenceValidator).flatten.map do |validator|
50
+ absence_attributes.concat(validator.attributes)
51
+ end
52
+ absence_attributes
53
+ end
54
+
55
+ def get_acceptance_attributes(app_class_name)
56
+ acceptance_attributes = []
57
+ extract_validators(app_class_name, ::ActiveModel::Validations::AcceptanceValidator).flatten.map do |validator|
58
+ acceptance_attributes.concat(validator.attributes)
59
+ end
60
+ acceptance_attributes
61
+ end
62
+
63
+ def get_confirmation_attributes(app_class_name)
64
+ confirmation_attributes = []
65
+ extract_validators(app_class_name, ::ActiveModel::Validations::ConfirmationValidator).flatten.map do |validator|
66
+ confirmation_attributes.concat(validator.attributes)
67
+ end
68
+ confirmation_attributes
69
+ end
70
+
71
+ def get_exclusion_attributes(app_class_name)
72
+ exclusion_attributes = []
73
+ extract_validators(app_class_name, ::ActiveModel::Validations::ExclusionValidator).flatten.map do |validator|
74
+ exclusion_attributes.concat(validator.attributes)
75
+ end
76
+ exclusion_attributes
77
+ end
78
+
79
+ def get_inclusion_attributes(app_class_name)
80
+ inclusion_attributes = []
81
+ extract_validators(app_class_name, ::ActiveModel::Validations::InclusionValidator).flatten.map do |validator|
82
+ inclusion_attributes.concat(validator.attributes)
83
+ end
84
+ inclusion_attributes
85
+ end
86
+
87
+ def get_length_attributes(app_class_name)
88
+ length_attributes = []
89
+ extract_validators(app_class_name, ::ActiveModel::Validations::LengthValidator).flatten.map do |validator|
90
+ length_attributes.concat(validator.attributes)
91
+ end
92
+ length_attributes
93
+ end
94
+
95
+ def get_numericality_attributes(app_class_name)
96
+ numericality_attributes = []
97
+ extract_validators(app_class_name, ::ActiveModel::Validations::NumericalityValidator).flatten.map do |validator|
98
+ numericality_attributes.concat(validator.attributes)
99
+ end
100
+ numericality_attributes
101
+ end
102
+
103
+ def get_presence_attributes(app_class_name)
104
+ presence_attributes = []
105
+ extract_validators(app_class_name, ::ActiveRecord::Validations::PresenceValidator).flatten.map do |validator|
106
+ presence_attributes.concat(validator.attributes)
107
+ end
108
+ presence_attributes
109
+ end
110
+
111
+ def get_uniqueness_attributes(app_class_name)
112
+ uniqueness_attributes = []
113
+ extract_validators(app_class_name, ::ActiveRecord::Validations::UniquenessValidator).flatten.map do |validator|
114
+ uniqueness_attributes.concat(validator.attributes)
115
+ end
116
+ uniqueness_attributes
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+
@@ -0,0 +1,66 @@
1
+ module ShouldaMatchmakers
2
+ module Model
3
+ module ActiveRecord
4
+ module Matchmaker
5
+ module AcceptNestedAttributesFor
6
+
7
+
8
+ def accept_nested_attributes_for_matcher_tests
9
+ nested_attributes_options = @app_class_name.constantize.nested_attributes_options
10
+ if nested_attributes_options.present?
11
+ generate_accept_nested_attributes_for_matcher_tests(nested_attributes_options)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def generate_accept_nested_attributes_for_matcher_tests(nested_attributes_options)
21
+ nested_attributes_tests = []
22
+ nested_attributes_options.map do |class_name, options|
23
+ nested_attributes_class_name = class_name.to_s
24
+ nested_attributes_options = trim_options(options)
25
+ nested_attributes_test = generate_nested_attributes_test(nested_attributes_class_name, nested_attributes_options)
26
+ nested_attributes_tests = append_element(nested_attributes_test, nested_attributes_tests)
27
+ end
28
+ format_tests(nested_attributes_tests)
29
+ end
30
+
31
+ def generate_nested_attributes_test(nested_attributes_class_name, nested_attributes_options)
32
+ nested_attributes_test = generate_nested_attributes_test_single_line(nested_attributes_class_name, nested_attributes_options)
33
+ if nested_attributes_test.length > @working_generated_code_line_length
34
+ nested_attributes_test = generate_nested_attributes_test_multiple_lines(nested_attributes_class_name, nested_attributes_options)
35
+ end
36
+ nested_attributes_test
37
+ end
38
+
39
+ def generate_nested_attributes_test_single_line(nested_attributes_class_name, nested_attributes_options)
40
+ nested_attributes_test = " it { is_expected.to accept_nested_attributes_for(:#{ nested_attributes_class_name })"
41
+ nested_attributes_options_string = get_options_string(nested_attributes_options)
42
+ nested_attributes_test.concat(nested_attributes_options_string + " }")
43
+ nested_attributes_test
44
+ end
45
+
46
+ def generate_nested_attributes_test_multiple_lines(nested_attributes_class_name, nested_attributes_options)
47
+ nested_attributes_test = " it do\n is_expected.to accept_nested_attributes_for(:#{ nested_attributes_class_name })"
48
+ nested_attributes_options_string = get_options_string(nested_attributes_options)
49
+ nested_attributes_options_string = nested_attributes_options_string.gsub(".", ".\n ")
50
+ nested_attributes_test.concat(nested_attributes_options_string + "\n end")
51
+ nested_attributes_test
52
+ end
53
+
54
+ def trim_options(options)
55
+ options_untrimmed = options.dup
56
+ options_trimmed = {}
57
+ options_untrimmed.delete(:allow_destroy) if options[:allow_destroy].to_s == "false"
58
+ options_untrimmed.delete(:update_only) if options[:update_only].to_s == "false"
59
+ options_trimmed.merge(options_untrimmed)
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,137 @@
1
+ module ShouldaMatchmakers
2
+ module Model
3
+ module ActiveRecord
4
+ module Matchmaker
5
+ module AllowValue
6
+
7
+
8
+ def allow_value_matcher_tests
9
+ allow_value_validators = extract_validators(@app_class_name, ::ActiveModel::Validations::FormatValidator)
10
+ if allow_value_validators.present?
11
+ generate_allow_value_matcher_tests(allow_value_validators)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def generate_allow_value_matcher_tests(validators)
21
+ allow_value_tests = []
22
+ validators.map do |validator|
23
+ if conditional_options_exist(validator.options)
24
+ allow_value_tests = allow_value_tests + generate_conditional_allow_value_tests(validator)
25
+ else
26
+ allow_value_test = generate_allow_value_test(validator, validator.options)
27
+ allow_value_tests = append_element(allow_value_test, allow_value_tests)
28
+ allow_value_expected_not_to_test = generate_allow_value_expected_not_to_test(allow_value_test)
29
+ allow_value_tests = append_element(allow_value_expected_not_to_test, allow_value_tests)
30
+ end
31
+ end
32
+ format_tests(allow_value_tests)
33
+ end
34
+
35
+ def generate_allow_value_test(validator, validator_options)
36
+ allow_value_test = " xit { is_expected.to allow_values('','').for(:#{ validator.attributes.first })"
37
+ allow_value_options_string = get_options_string(validator_options)
38
+ allow_value_test.concat(allow_value_options_string + " }")
39
+ if allow_value_test.length > @working_generated_code_line_length
40
+ allow_value_test = generate_allow_value_test_multiple_lines(validator, allow_value_options_string)
41
+ end
42
+ allow_value_test_comment = get_allow_value_test_comment(validator)
43
+ allow_value_test.prepend(allow_value_test_comment)
44
+ end
45
+
46
+ def generate_allow_value_test_multiple_lines(validator, allow_value_options_string)
47
+ allow_value_test = " xit do\n is_expected.to allow_values('','').\n for(:#{ validator.attributes.first })"
48
+ allow_value_options_string = allow_value_options_string.gsub(".", ".\n ")
49
+ allow_value_test.concat(allow_value_options_string).concat("\n end")
50
+ end
51
+
52
+ def generate_allow_value_expected_not_to_test(allow_value_test)
53
+ if allow_value_test.include?("DO NOT MATCH")
54
+ allow_value_test.sub("DO NOT MATCH", "MATCH").gsub("is_expected.to", "is_expected.not_to")
55
+ else
56
+ allow_value_test.sub("MATCH", "DO NOT MATCH").gsub("is_expected.to", "is_expected.not_to")
57
+ end
58
+ end
59
+
60
+ def generate_conditional_allow_value_tests(validator)
61
+ conditional_allow_value_tests = []
62
+ allow_value_options = parse_validator_options(validator.options.dup)
63
+ if all_option_values_are_symbols(allow_value_options[:if_option_values]) &&
64
+ all_option_values_are_symbols(allow_value_options[:unless_option_values])
65
+ conditional_allow_value_validating_test = generate_conditional_allow_value_validating_test(validator, allow_value_options)
66
+ conditional_allow_value_tests = append_element(conditional_allow_value_validating_test, conditional_allow_value_tests)
67
+ conditional_allow_value_non_validating_tests = generate_conditional_allow_value_non_validating_tests(validator, allow_value_options)
68
+ conditional_allow_value_tests = conditional_allow_value_tests + conditional_allow_value_non_validating_tests
69
+ # else
70
+ # Skip tests due to non-symbol conditions (see below)
71
+ end
72
+ conditional_allow_value_tests
73
+ end
74
+
75
+ def generate_conditional_allow_value_validating_test(validator, allow_value_options)
76
+ conditional_validating_test = compose_conditional_validating_context_string(allow_value_options)
77
+ validating_permutation = get_validating_true_false_permutation(allow_value_options)
78
+ conditional_validating_test.concat(compose_conditional_before_strings(allow_value_options, validating_permutation))
79
+ validating_test = generate_allow_value_test(validator, allow_value_options[:non_conditional_options])
80
+ validating_test = adjust_conditional_test_indentation(validating_test)
81
+ conditional_validating_test.concat(validating_test).concat("\n end").prepend("# Conditional validating test\n#\n")
82
+ end
83
+
84
+ def generate_conditional_allow_value_non_validating_tests(validator, allow_value_options)
85
+ conditional_non_validating_tests = []
86
+ possible_conditional_permutations = get_possible_true_false_permutations(allow_value_options)
87
+ validating_permutation = get_validating_true_false_permutation(allow_value_options)
88
+ non_validating_permutations = possible_conditional_permutations - [validating_permutation]
89
+ non_validating_permutations.each do |non_validating_permutation|
90
+ conditional_non_validating_test = generate_conditional_allow_value_non_validating_test(validator, allow_value_options, non_validating_permutation)
91
+ conditional_non_validating_tests = append_element(conditional_non_validating_test, conditional_non_validating_tests)
92
+ end
93
+ if validator.options.key?(:unless)
94
+ conditional_non_validating_tests[0] = conditional_non_validating_tests[0].prepend("# For more natural readability of 'is_expected.not_to' context lines, 'unless' is represented by 'if not'\n# and 'unless not' is represented by 'if'.\n#\n")
95
+ end
96
+ conditional_non_validating_tests[0] = conditional_non_validating_tests[0].prepend("# Conditional non-validating test(s)\n#\n")
97
+ conditional_non_validating_tests
98
+ end
99
+
100
+ def generate_conditional_allow_value_non_validating_test(validator, allow_value_options, non_validating_permutation)
101
+ conditional_non_validating_test = compose_conditional_non_validating_context_string(allow_value_options, non_validating_permutation)
102
+ conditional_non_validating_test.concat(compose_conditional_before_strings(allow_value_options, non_validating_permutation))
103
+ non_validating_test = generate_allow_value_test(validator, allow_value_options[:non_conditional_options])
104
+ non_validating_test.sub!("is_expected.to","is_expected.not_to")
105
+ non_validating_test = adjust_conditional_test_indentation(non_validating_test)
106
+ conditional_non_validating_test.concat(non_validating_test)
107
+ conditional_non_validating_test.concat("\n end")
108
+ end
109
+
110
+ def get_allow_value_test_comment(validator)
111
+ allow_value_test_comment = ""
112
+ if validator.options.key? :with
113
+ expected_to_match_value_format = get_value_format(validator.options[:with].source.to_s)
114
+ allow_value_test_comment = "#\n# Enter values that MATCH this format: #{ expected_to_match_value_format }\n"
115
+ elsif validator.options.key? :without
116
+ expected_to_match_value_format = get_value_format(validator.options[:without].source.to_s)
117
+ allow_value_test_comment = "#\n# Enter values that DO NOT MATCH this format: #{ expected_to_match_value_format }\n"
118
+ end
119
+ allow_value_test_comment
120
+ end
121
+
122
+ def get_value_format(format)
123
+ # IMPLEMENTATION TODO: Add additional predefined Rails regexp's, if they exist
124
+ uri_regexp_string = URI.regexp.to_s.gsub(/^\(\?x-mi:/,"").gsub('\/', '/').chomp(")")
125
+ case format
126
+ when uri_regexp_string
127
+ "URI.regexp"
128
+ else
129
+ format
130
+ end
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,52 @@
1
+ module ShouldaMatchmakers
2
+ module Model
3
+ module ActiveRecord
4
+ module Matchmaker
5
+ module Associations
6
+
7
+
8
+ def association_matcher_tests(association_type)
9
+ association_type_instances = @app_class_name.constantize.reflect_on_all_associations(association_type.to_sym)
10
+ if association_type_instances.present?
11
+ generate_association_matcher_tests(association_type, association_type_instances)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def generate_association_matcher_tests(association_type, association_type_instances)
21
+ association_tests = []
22
+ association_type_instances = association_type_instances.map{ |ati| { association_class_name: ati.name, association_options: ati.options } }
23
+ association_type_instances.each do |association_type_instance|
24
+ association_test = generate_association_test_single_line(association_type, association_type_instance)
25
+ if association_test.length > @working_generated_code_line_length
26
+ association_test = generate_association_test_multiple_lines(association_type, association_type_instance)
27
+ end
28
+ association_tests = append_element(association_test, association_tests)
29
+ end
30
+ format_tests(association_tests)
31
+ end
32
+
33
+ def generate_association_test_single_line(association_type, association_type_instance)
34
+ association_matcher = association_type.sub("belongs", "belong").sub("has", "have")
35
+ association_test = " it { is_expected.to #{ association_matcher }(:#{ association_type_instance[:association_class_name].to_s })"
36
+ association_options_string = get_options_string(association_type_instance[:association_options])
37
+ association_test.concat(association_options_string + " }")
38
+ end
39
+
40
+ def generate_association_test_multiple_lines(association_type, association_type_instance)
41
+ association_matcher = association_type.sub("belongs", "belong").sub("has", "have")
42
+ association_test = " it do\n is_expected.to #{ association_matcher }(:#{ association_type_instance[:association_class_name].to_s })"
43
+ association_options_string = get_options_string(association_type_instance[:association_options])
44
+ association_options_string = association_options_string.gsub(".", ".\n ")
45
+ association_test.concat(association_options_string + "\n end")
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ module ShouldaMatchmakers
2
+ module Model
3
+ module ActiveRecord
4
+ module Matchmaker
5
+ module DefineEnumFor
6
+
7
+
8
+ def define_enum_for_matcher_tests
9
+ defined_enums = @app_class_name.constantize.defined_enums
10
+ if defined_enums.present?
11
+ generate_define_enum_for_matcher_tests(defined_enums)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def generate_define_enum_for_matcher_tests(defined_enums)
21
+ define_enum_tests = []
22
+ defined_enums.each do |attribute, enum_hash|
23
+ define_enum_test = generate_enum_qualifier_examples(attribute, enum_hash)
24
+ define_enum_test.concat(" it { is_expected.to define_enum_for(:#{ attribute }) }")
25
+ define_enum_tests = append_element(define_enum_test, define_enum_tests)
26
+ end
27
+ format_tests(define_enum_tests)
28
+ end
29
+
30
+ def generate_enum_qualifier_examples(attribute, enum_hash)
31
+ enum_names = get_enum_names(enum_hash)
32
+ define_enum_test = "# You can use the 'with' qualifier to test that your enum has been defined with a certain set of known values.\n"
33
+ if enum_names.join.length < 40
34
+ define_enum_test.concat("# Example: 'it { is_expected.to define_enum_for(:#{ attribute }).with(#{ enum_names }) }'\n")
35
+ else
36
+ define_enum_test.concat("# Example: 'it { is_expected.to define_enum_for(:#{ attribute }).with([#{ enum_names[0] }, #{ enum_names[1] }, ...]) }'\n")
37
+ end
38
+ define_enum_test.concat("#\n# Source: https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb\n#\n")
39
+ end
40
+
41
+ def get_enum_names(enum_hash)
42
+ enum_names = []
43
+ enum_hash.keys.each do |enum_name|
44
+ enum_names = append_element(enum_name.to_sym, enum_names)
45
+ end
46
+ enum_names
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end