shoulda_matchmakers 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|