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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +21 -0
- data/lib/controller/action_controller/action_controller_controller_sm_model.rb +53 -0
- data/lib/controller/action_controller/action_controller_controller_sm_model_helper.rb +73 -0
- data/lib/controller/action_controller/matchmakers/callbacks.rb +56 -0
- data/lib/controller/action_controller/matchmakers/filter_param.rb +69 -0
- data/lib/controller/action_controller/matchmakers/permit.rb +510 -0
- data/lib/controller/action_controller/matchmakers/redirect_to.rb +126 -0
- data/lib/controller/action_controller/matchmakers/render_template.rb +198 -0
- data/lib/controller/action_controller/matchmakers/render_with_layout.rb +72 -0
- data/lib/controller/action_controller/matchmakers/rescue_from.rb +96 -0
- data/lib/controller/action_controller/matchmakers/respond_with.rb +71 -0
- data/lib/controller/action_controller/matchmakers/route.rb +586 -0
- data/lib/controller/action_controller/matchmakers/set_flash.rb +136 -0
- data/lib/controller/action_controller/matchmakers/set_session.rb +115 -0
- data/lib/controller/action_controller/permitted_params_definition.rb +60 -0
- data/lib/generators/shoulda_matchmakers/controller_matcher_generator.rb +87 -0
- data/lib/generators/shoulda_matchmakers/controller_matcher_generator_helper.rb +92 -0
- data/lib/generators/shoulda_matchmakers/factory_generator.rb +86 -0
- data/lib/generators/shoulda_matchmakers/install_generator.rb +10 -0
- data/lib/generators/shoulda_matchmakers/model_matcher_generator.rb +87 -0
- data/lib/generators/shoulda_matchmakers/model_matcher_generator_helper.rb +107 -0
- data/lib/model/active_record/active_record_model_sm_model.rb +50 -0
- data/lib/model/active_record/active_record_model_sm_model_helper.rb +206 -0
- data/lib/model/active_record/factory_sm_model.rb +28 -0
- data/lib/model/active_record/factory_sm_model_helper.rb +124 -0
- data/lib/model/active_record/matchmakers/accept_nested_attributes_for.rb +66 -0
- data/lib/model/active_record/matchmakers/allow_value.rb +137 -0
- data/lib/model/active_record/matchmakers/associations.rb +52 -0
- data/lib/model/active_record/matchmakers/define_enum_for.rb +53 -0
- data/lib/model/active_record/matchmakers/delegate_method.rb +101 -0
- data/lib/model/active_record/matchmakers/have_db_column.rb +33 -0
- data/lib/model/active_record/matchmakers/have_db_index.rb +39 -0
- data/lib/model/active_record/matchmakers/have_readonly_attribute.rb +32 -0
- data/lib/model/active_record/matchmakers/have_secure_password.rb +32 -0
- data/lib/model/active_record/matchmakers/serialize.rb +67 -0
- data/lib/model/active_record/matchmakers/validations.rb +169 -0
- data/lib/model/active_record/options_definition.rb +160 -0
- data/lib/shoulda_matchmakers.rb +48 -0
- data/lib/shoulda_matchmakers/version.rb +3 -0
- data/lib/support/command_line_interface.rb +100 -0
- data/lib/support/controller_generator.rb +198 -0
- data/lib/support/indefinite_article.rb +70 -0
- data/lib/support/to_discard/belong_to.rb +94 -0
- data/lib/support/to_discard/have_and_belong_to_many.rb +83 -0
- data/lib/support/to_discard/have_many.rb +96 -0
- data/lib/support/to_discard/have_one.rb +98 -0
- data/lib/support/to_discard/permit_refactor.rb +270 -0
- data/lib/support/to_discard/render_template_new.rb +204 -0
- data/lib/support/to_discard/render_template_reconstruction.rb +188 -0
- data/lib/support/to_discard/use_around_action.rb +20 -0
- data/lib/support/to_discard/use_before_action.rb +20 -0
- data/lib/support/to_discard/validate_absence_of.rb +16 -0
- data/lib/support/to_discard/validate_acceptance_of.rb +16 -0
- data/lib/support/to_discard/validate_confirmation_of.rb +16 -0
- data/lib/support/to_discard/validate_exclusion_of.rb +145 -0
- data/lib/support/to_discard/validate_inclusion_of.rb +94 -0
- data/lib/support/to_discard/validate_length_of.rb +16 -0
- data/lib/support/to_discard/validate_numericality_of.rb +16 -0
- data/lib/support/to_discard/validate_presence_of.rb +16 -0
- data/lib/support/to_discard/validate_uniqueness_of.rb +16 -0
- data/lib/support/to_discard/validation_old.rb +37 -0
- data/lib/support/to_discard/validations.rb +41 -0
- data/lib/support/to_discard/validations_conditional.rb +146 -0
- data/lib/support/trace_debug_lines.txt +319 -0
- data/lib/support/util.rb +15 -0
- data/lib/templates/controller/action_controller/controller_spec_template.haml +146 -0
- data/lib/templates/factory/active_record/factory_template.haml +13 -0
- data/lib/templates/model/active_record/model_spec_template.haml +233 -0
- data/lib/templates/shoulda_matchmakers.rb +112 -0
- 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
|