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,101 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module DelegateMethod
|
6
|
+
|
7
|
+
|
8
|
+
def delegate_method_matcher_tests
|
9
|
+
delegate_method_occurrences = get_delegate_method_occurrences(@app_class_name)
|
10
|
+
if delegate_method_occurrences.present?
|
11
|
+
generate_delegate_method_matcher_tests(delegate_method_occurrences)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def get_delegate_method_occurrences(app_class_name)
|
21
|
+
delegate_method_occurrences = []
|
22
|
+
app_model_file_path = compose_extended_model_file_path(app_class_name)
|
23
|
+
if File.exists?(app_model_file_path)
|
24
|
+
File.open(app_model_file_path, 'r') do |app_model_file|
|
25
|
+
app_model_file.each_line do |app_model_file_line|
|
26
|
+
if app_model_file_line =~ /^\s+delegate(?:\s*\(\s*|\s+):[A-Za-z0-9_@]+/
|
27
|
+
delegate_method_occurrences = delegate_method_occurrences + get_delegate_delegate_method_occurrences(app_model_file_line)
|
28
|
+
elsif app_model_file_line =~ /^\s+def(?:_instance)?_delegators?(?:\s*\(\s*|\s+):[A-Za-z0-9_@]+/
|
29
|
+
delegate_method_occurrences = delegate_method_occurrences + get_def_delegate_delegate_method_occurrences(app_model_file_line)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
delegate_method_occurrences = []
|
35
|
+
end
|
36
|
+
delegate_method_occurrences
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_delegate_delegate_method_occurrences(app_model_file_line)
|
40
|
+
delegate_delegate_method_occurrences = []
|
41
|
+
delegated_methods = app_model_file_line.scan(/(?:^\s+delegate(?:\s*\(\s*|\s+)|,\s*)(:[A-Za-z0-9_@]+)/).flatten
|
42
|
+
delegate = app_model_file_line.scan(/,\s*to:\s+(:?[A-Za-z0-9_@]+)/).flatten
|
43
|
+
if delegate.present? && delegated_methods.present?
|
44
|
+
prefix = app_model_file_line.scan(/,\s*prefix:\s+(:?[A-Za-z0-9_@]+)/).flatten
|
45
|
+
arguments = app_model_file_line.scan(/,\s*([A-Za-z0-9_@]+:\s+:?[A-Za-z0-9_@]+)/)
|
46
|
+
arguments = arguments.flatten.reject{ |argument| argument =~ /^to:/ || argument =~ /^prefix:/ }
|
47
|
+
delegated_methods.each do |delegated_method|
|
48
|
+
delegate_method_hash = { delegate: delegate[0], method: delegated_method, prefix: "", arguments: [] }
|
49
|
+
delegate_method_hash[:prefix] = prefix[0] if prefix.present?
|
50
|
+
delegate_method_hash[:arguments] = arguments if arguments.present?
|
51
|
+
delegate_delegate_method_occurrences = append_element(delegate_method_hash, delegate_delegate_method_occurrences)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
delegate_delegate_method_occurrences
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_def_delegate_delegate_method_occurrences(app_model_file_line)
|
58
|
+
def_delegate_delegate_method_occurrences = []
|
59
|
+
delegate = app_model_file_line.scan(/^\s+def(?:_instance)?_delegators?(?:\s*\(\s*|\s+)(:[A-Za-z0-9_@]+)/).flatten
|
60
|
+
delegated_methods = app_model_file_line.scan(/,\s*(:[A-Za-z0-9_@]+)/).flatten
|
61
|
+
if delegate.present? && delegated_methods.present?
|
62
|
+
delegated_methods.each do |delegated_method|
|
63
|
+
delegate_method_hash = { delegate: delegate[0], method: delegated_method, prefix: "", arguments: [] }
|
64
|
+
def_delegate_delegate_method_occurrences = append_element(delegate_method_hash, def_delegate_delegate_method_occurrences)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def_delegate_delegate_method_occurrences
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_delegate_method_matcher_tests(delegate_method_occurrences)
|
71
|
+
delegate_method_tests = []
|
72
|
+
delegate_method_occurrences.sort_by!{ |dmo| [dmo[:method], dmo[:delegate], dmo[:prefix], dmo[:arguments]] }
|
73
|
+
delegate_method_occurrences = delegate_method_occurrences.uniq
|
74
|
+
delegate_method_occurrences.each do |delegate_method_occurrence|
|
75
|
+
delegate_method_test = generate_delegate_method_test(delegate_method_occurrence)
|
76
|
+
delegate_method_tests = append_element(delegate_method_test, delegate_method_tests)
|
77
|
+
end
|
78
|
+
format_tests(delegate_method_tests)
|
79
|
+
end
|
80
|
+
|
81
|
+
def generate_delegate_method_test(delegate_method_occurrence)
|
82
|
+
delegate_method_test = " it { is_expected.to delegate_method(#{ delegate_method_occurrence[:method] }).to(#{ delegate_method_occurrence[:delegate] })"
|
83
|
+
if delegate_method_occurrence[:prefix].present?
|
84
|
+
delegate_method_test.concat(".with_prefix(#{ delegate_method_occurrence[:prefix] })")
|
85
|
+
end
|
86
|
+
if delegate_method_occurrence[:arguments].present?
|
87
|
+
delegate_method_test.concat(".with_arguments(")
|
88
|
+
delegate_method_occurrence[:arguments].each do |delegate_method_argument|
|
89
|
+
delegate_method_test.concat("#{ delegate_method_argument }, ")
|
90
|
+
end
|
91
|
+
delegate_method_test.chomp!(", ").concat(")")
|
92
|
+
end
|
93
|
+
delegate_method_test.concat(" }")
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module HaveDbColumn
|
6
|
+
|
7
|
+
|
8
|
+
def have_db_column_matcher_tests
|
9
|
+
db_columns = @app_class_name.constantize.columns
|
10
|
+
if db_columns.present?
|
11
|
+
generate_have_db_column_matcher_tests(db_columns)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_have_db_column_matcher_tests(db_columns)
|
21
|
+
db_column_tests = []
|
22
|
+
db_columns.each do |db_column|
|
23
|
+
db_column_test = " it { is_expected.to have_db_column(:#{ db_column.name }).of_type(:#{ db_column.type }) }"
|
24
|
+
db_column_tests = append_element(db_column_test, db_column_tests)
|
25
|
+
end
|
26
|
+
format_tests(db_column_tests)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module HaveDbIndex
|
6
|
+
|
7
|
+
def have_db_index_matcher_tests
|
8
|
+
# IMPLEMENTATION TODO: Determine if it is possible to indexes where 'using=:gin' (or anything not :btree)
|
9
|
+
db_indexes = ::ActiveRecord::Base.connection.indexes(@app_class_name.tableize.gsub("/", "_")).select{ |ndx| ndx.using == :btree }
|
10
|
+
if db_indexes.present?
|
11
|
+
generate_have_db_index_matcher_tests(db_indexes)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_have_db_index_matcher_tests(db_indexes)
|
21
|
+
db_index_tests = []
|
22
|
+
db_indexes.map do |ndx|
|
23
|
+
if ndx.columns.length == 1
|
24
|
+
db_index_test = " it { is_expected.to have_db_index(:#{ ndx.columns[0] })"
|
25
|
+
else
|
26
|
+
db_index_test = " it { is_expected.to have_db_index(#{ ndx.columns.map { |c| c.to_sym } })"
|
27
|
+
end
|
28
|
+
db_index_test.concat(".unique") if ndx.unique
|
29
|
+
db_index_test.concat(" }")
|
30
|
+
db_index_tests = append_element(db_index_test, db_index_tests)
|
31
|
+
end
|
32
|
+
format_tests(db_index_tests)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module HaveReadonlyAttribute
|
6
|
+
|
7
|
+
def have_readonly_attribute_matcher_tests
|
8
|
+
readonly_attributes = @app_class_name.constantize.readonly_attributes
|
9
|
+
if readonly_attributes.present?
|
10
|
+
generate_have_readonly_attribute_matcher_tests(readonly_attributes)
|
11
|
+
else
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def generate_have_readonly_attribute_matcher_tests(readonly_attributes)
|
20
|
+
readonly_attribute_tests = []
|
21
|
+
readonly_attributes.each do |attribute|
|
22
|
+
readonly_attribute_test = " it { is_expected.to have_readonly_attribute(:#{ attribute }) }"
|
23
|
+
readonly_attribute_tests = append_element(readonly_attribute_test, readonly_attribute_tests)
|
24
|
+
end
|
25
|
+
format_tests(readonly_attribute_tests)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module HaveSecurePassword
|
6
|
+
|
7
|
+
def have_secure_password_matcher_tests
|
8
|
+
model_methods = @app_class_name.constantize.methods
|
9
|
+
model_instance_methods = @app_class_name.constantize.instance_methods
|
10
|
+
if model_methods.present? && model_instance_methods.present?
|
11
|
+
generate_have_secure_password_matcher_tests(model_methods, model_instance_methods)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_have_secure_password_matcher_tests(model_methods, model_instance_methods)
|
21
|
+
secure_password_test = ""
|
22
|
+
if model_instance_methods.include?(:password_digest) && model_methods.exclude?(:devise_parameter_filter)
|
23
|
+
secure_password_test = " it { is_expected.to have_secure_password }"
|
24
|
+
end
|
25
|
+
secure_password_test
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module Serialize
|
6
|
+
|
7
|
+
|
8
|
+
def serialize_matcher_tests
|
9
|
+
serialized_attributes = @app_class_name.constantize.serialized_attributes
|
10
|
+
if serialized_attributes.present?
|
11
|
+
generate_serialize_matcher_tests(serialized_attributes)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_serialize_matcher_tests(serialized_attributes)
|
21
|
+
serialize_tests = []
|
22
|
+
serialized_attributes.map do |attribute, cast_type|
|
23
|
+
object_class = cast_type.try(:object_class)
|
24
|
+
if %w(Array Hash Object).include?(object_class.to_s) || (object_class == nil && cast_type.to_s.include?("JSON"))
|
25
|
+
serialize_test = generate_serialize_test(attribute, object_class)
|
26
|
+
serialize_tests = append_element(serialize_test, serialize_tests)
|
27
|
+
else
|
28
|
+
custom_serialize_test = generate_custom_serialize_test(attribute, cast_type, object_class)
|
29
|
+
serialize_tests = append_element(custom_serialize_test, serialize_tests)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
format_tests(serialize_tests)
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_serialize_test(attribute, object_class)
|
36
|
+
case object_class.to_s
|
37
|
+
when "Array", "Hash"
|
38
|
+
serialize_test = " it { is_expected.to serialize(:#{ attribute }).as(#{ object_class }) }"
|
39
|
+
when "Object"
|
40
|
+
serialize_test = " it { is_expected.to serialize(:#{ attribute }) }"
|
41
|
+
else
|
42
|
+
serialize_test = " it { is_expected.to serialize(:#{ attribute }).as(JSON) }"
|
43
|
+
end
|
44
|
+
serialize_test
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_custom_serialize_test(attribute, cast_type, object_class)
|
48
|
+
if object_class == nil
|
49
|
+
custom_serializer_class = cast_type.to_s
|
50
|
+
custom_serializer_class = custom_serializer_class.gsub(/#\</, "").gsub(/:.*\z/, "") if cast_type.to_s.include?("#<")
|
51
|
+
custom_serialize_test = " it { is_expected.to serialize(:#{ attribute }).as(#{ custom_serializer_class }) }"
|
52
|
+
else
|
53
|
+
custom_serializer_class = object_class.to_s
|
54
|
+
custom_serializer_class = custom_serializer_class.gsub(/#\</, "").gsub(/:.*\z/, "") if object_class.to_s.include?("#<")
|
55
|
+
custom_serialize_test = " it { is_expected.to serialize(:#{ attribute }).as_instance_of(#{ custom_serializer_class }) }"
|
56
|
+
end
|
57
|
+
if custom_serialize_test.length > @working_generated_code_line_length
|
58
|
+
custom_serialize_test = custom_serialize_test.sub(" it { ", " it do\n ").sub(").as", ").\n as").sub("}) }", "})\n end")
|
59
|
+
end
|
60
|
+
custom_serialize_test
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Model
|
3
|
+
module ActiveRecord
|
4
|
+
module Matchmaker
|
5
|
+
module Validations
|
6
|
+
|
7
|
+
|
8
|
+
def validator_matcher_tests(validation_type)
|
9
|
+
validators = extract_validators(@app_class_name, validation_type)
|
10
|
+
if validators.present?
|
11
|
+
generate_validation_matcher_tests(validators)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_validation_matcher_tests(validators)
|
21
|
+
validation_tests = []
|
22
|
+
validators.map do |validator|
|
23
|
+
if conditional_options_exist(validator.options)
|
24
|
+
conditional_validation_tests = generate_conditional_validation_tests(validator)
|
25
|
+
validation_tests = validation_tests + conditional_validation_tests
|
26
|
+
else
|
27
|
+
validation_test = generate_validation_test(validator, validator.options)
|
28
|
+
validation_tests = append_element(validation_test, validation_tests)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
format_tests(validation_tests)
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_validation_test(validator, validator_options)
|
35
|
+
validation_test = " it { is_expected.to validate_#{ validator.kind.to_s }_of(:#{ validator.attributes.first.to_s })"
|
36
|
+
if (validator.kind == :exclusion || validator.kind == :inclusion) && custom_exclusion_inclusion_test_required(validator_options)
|
37
|
+
validation_test.sub!(" it {", " xit {")
|
38
|
+
custom_exclusion_inclusion_test_comment = get_custom_exclusion_inclusion_test_comment(validator_options)
|
39
|
+
validation_test.prepend(custom_exclusion_inclusion_test_comment).concat(" }")
|
40
|
+
else
|
41
|
+
if validator.kind == :exclusion || validator.kind == :inclusion
|
42
|
+
refined_validator_options = refine_exclusion_inclusion_non_conditional_option(validator_options)
|
43
|
+
else
|
44
|
+
refined_validator_options = validator_options
|
45
|
+
end
|
46
|
+
validator_options_string = get_options_string(refined_validator_options)
|
47
|
+
validation_test.concat(validator_options_string + " }")
|
48
|
+
if validation_test.length > @working_generated_code_line_length
|
49
|
+
validation_test = generate_validation_test_multiple_lines(validator, validator_options_string)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
validation_test
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_validation_test_multiple_lines(validator, validator_options_string)
|
56
|
+
validation_test = " it do\n is_expected.to validate_#{ validator.kind.to_s }_of(:#{ validator.attributes.first })"
|
57
|
+
validator_options_string = validator_options_string.gsub(".", ".\n ")
|
58
|
+
validation_test.concat(validator_options_string).concat("\n end")
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_conditional_validation_tests(validator)
|
62
|
+
conditional_validation_tests = []
|
63
|
+
validator_options = parse_validator_options(validator.options.dup)
|
64
|
+
if (validator.kind == :exclusion || validator.kind == :inclusion) && validator_options[:non_conditional_options].present?
|
65
|
+
validator_options[:non_conditional_options] = refine_exclusion_inclusion_non_conditional_option(validator_options[:non_conditional_options])
|
66
|
+
end
|
67
|
+
if all_option_values_are_symbols(validator_options[:if_option_values]) &&
|
68
|
+
all_option_values_are_symbols(validator_options[:unless_option_values])
|
69
|
+
conditional_validating_test = generate_conditional_validating_test(validator, validator_options)
|
70
|
+
conditional_validation_tests = append_element(conditional_validating_test, conditional_validation_tests)
|
71
|
+
conditional_non_validating_tests = generate_conditional_non_validating_tests(validator, validator_options)
|
72
|
+
conditional_validation_tests = conditional_validation_tests + conditional_non_validating_tests
|
73
|
+
# else
|
74
|
+
# Skip tests due to non-symbol conditions (see below)
|
75
|
+
end
|
76
|
+
conditional_validation_tests
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_conditional_validating_test(validator, validator_options)
|
80
|
+
conditional_validating_test = compose_conditional_validating_context_string(validator_options)
|
81
|
+
validating_permutation = get_validating_true_false_permutation(validator_options)
|
82
|
+
conditional_validating_test.concat(compose_conditional_before_strings(validator_options, validating_permutation))
|
83
|
+
validating_test = generate_validation_test(validator, validator_options[:non_conditional_options])
|
84
|
+
validating_test = adjust_conditional_test_indentation(validating_test)
|
85
|
+
conditional_validating_test.concat(validating_test).concat("\n end").prepend("# Conditional validating test\n#\n")
|
86
|
+
end
|
87
|
+
|
88
|
+
def generate_conditional_non_validating_tests(validator, validator_options)
|
89
|
+
conditional_non_validating_tests = []
|
90
|
+
possible_conditional_permutations = get_possible_true_false_permutations(validator_options)
|
91
|
+
validating_permutation = get_validating_true_false_permutation(validator_options)
|
92
|
+
non_validating_permutations = possible_conditional_permutations - [validating_permutation]
|
93
|
+
non_validating_permutations.each do |non_validating_permutation|
|
94
|
+
conditional_non_validating_test = generate_conditional_non_validating_test(validator, validator_options, non_validating_permutation)
|
95
|
+
conditional_non_validating_tests << conditional_non_validating_test
|
96
|
+
end
|
97
|
+
if validator.options.key?(:unless)
|
98
|
+
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")
|
99
|
+
end
|
100
|
+
conditional_non_validating_tests[0] = conditional_non_validating_tests[0].prepend("# Conditional non-validating test(s)\n#\n")
|
101
|
+
conditional_non_validating_tests
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_conditional_non_validating_test(validator, validator_options, non_validating_permutation)
|
105
|
+
conditional_non_validating_test = compose_conditional_non_validating_context_string(validator_options, non_validating_permutation)
|
106
|
+
conditional_non_validating_test.concat(compose_conditional_before_strings(validator_options, non_validating_permutation))
|
107
|
+
non_validating_test = generate_validation_test(validator, validator_options[:non_conditional_options])
|
108
|
+
non_validating_test.sub!("is_expected.to","is_expected.not_to")
|
109
|
+
non_validating_test = adjust_conditional_test_indentation(non_validating_test)
|
110
|
+
conditional_non_validating_test.concat(non_validating_test)
|
111
|
+
conditional_non_validating_test.concat("\n end")
|
112
|
+
end
|
113
|
+
|
114
|
+
def custom_exclusion_inclusion_test_required(exclusion_inclusion_option)
|
115
|
+
exclusion_inclusion_enumerable = exclusion_inclusion_option[:in] || exclusion_inclusion_option[:within]
|
116
|
+
if exclusion_inclusion_enumerable.is_a?(Array) || exclusion_inclusion_enumerable.is_a?(Range)
|
117
|
+
false
|
118
|
+
else
|
119
|
+
true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_custom_exclusion_inclusion_test_comment(exclusion_inclusion_option)
|
124
|
+
exclusion_inclusion_enumerable = exclusion_inclusion_option[:in] || exclusion_inclusion_option[:within]
|
125
|
+
# CONFIRMATION TODO: Confirm whether or not enumerable could be a 'Proc' that isn't a 'lambda'
|
126
|
+
custom_exclusion_inclusion_test_comment = if exclusion_inclusion_enumerable.lambda?
|
127
|
+
"# Note: Your 'in:/within:' configuration option value is a 'Lambda'." +
|
128
|
+
" You will need to implement a customized test.\n"
|
129
|
+
elsif exclusion_inclusion_enumerable.respond_to?(:call)
|
130
|
+
"# Note: Your 'in:/within:' configuration option value is a 'Proc'." +
|
131
|
+
" You will need to implement a customized test.\n"
|
132
|
+
else
|
133
|
+
"# Alert: Invalid 'in:/within:' enumerable object type: '#{ exclusion_enumerable.class.name.to_s }'\n" +
|
134
|
+
"# Valid exclusion 'in:/within:' enumerable object types: 'Array', 'Range'" +
|
135
|
+
" (or a proc, lambda or symbol which returns an enumerable)\n"
|
136
|
+
end
|
137
|
+
custom_exclusion_inclusion_test_comment.concat("# Remove the 'x' from 'xit' once test customization has been implemented.\n")
|
138
|
+
end
|
139
|
+
|
140
|
+
def refine_exclusion_inclusion_non_conditional_option(exclusion_inclusion_option)
|
141
|
+
refined_exclusion_inclusion_option = {}
|
142
|
+
exclusion_inclusion_enumerable = exclusion_inclusion_option[:in] || exclusion_inclusion_option[:within]
|
143
|
+
if exclusion_inclusion_enumerable.is_a?(Array)
|
144
|
+
refined_exclusion_inclusion_option = { in_array: exclusion_inclusion_enumerable }
|
145
|
+
elsif exclusion_inclusion_enumerable.is_a?(Range)
|
146
|
+
refined_exclusion_inclusion_option = { in_range: exclusion_inclusion_enumerable }
|
147
|
+
end
|
148
|
+
refined_exclusion_inclusion_option
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# else
|
158
|
+
# Skip tests due to non-symbol conditions (see below)
|
159
|
+
# validator.attributes.map do |attribute|
|
160
|
+
# skip = true
|
161
|
+
# presence_test = generate_presence_test_single_line(validator_options, attribute, skip)
|
162
|
+
# if presence_test[0].length > 100 || validator_options.count > 1
|
163
|
+
# presence_test = generate_presence_test_multiple_lines(validator_options, attribute, skip)
|
164
|
+
# end
|
165
|
+
# presence_test_comment = " # This test is currently skipped due to if: and/or unless: conditions that aren't symbols.\n"
|
166
|
+
# presence_test_comment.concat(" # Provide ")
|
167
|
+
# presence_test.prepend(presence_test_comment)
|
168
|
+
# presence_tests << presence_test
|
169
|
+
# end
|