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,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
|