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,126 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Controller
|
3
|
+
module ActionController
|
4
|
+
module Matchmaker
|
5
|
+
module RedirectTo
|
6
|
+
|
7
|
+
|
8
|
+
def redirect_to_matcher_tests
|
9
|
+
redirect_to_occurrences = get_redirect_to_occurrences(@app_controller_name)
|
10
|
+
if redirect_to_occurrences.present?
|
11
|
+
generate_redirect_to_matcher_tests(@app_controller_name, redirect_to_occurrences)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def get_redirect_to_occurrences(app_controller_name)
|
21
|
+
redirect_to_occurrences = []
|
22
|
+
app_controller_file_path = compose_extended_app_controller_file_path(app_controller_name)
|
23
|
+
if File.exists?(app_controller_file_path)
|
24
|
+
redirect_to_occurrences = parse_app_controller_for_redirect_to_occurrences(app_controller_file_path)
|
25
|
+
end
|
26
|
+
redirect_to_occurrences
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_app_controller_for_redirect_to_occurrences(app_controller_file_path)
|
30
|
+
redirect_to_occurrences = []
|
31
|
+
File.open(app_controller_file_path, 'r') do |app_controller_file|
|
32
|
+
current_app_controller_method = nil
|
33
|
+
continued_from_previous_line = false
|
34
|
+
app_controller_file.each_line do |app_controller_file_line|
|
35
|
+
if continued_from_previous_line
|
36
|
+
redirect_location = app_controller_file_line.scan(/^\s+(:?[a-z0-9_]+)/).flatten.first
|
37
|
+
if current_app_controller_method.present? && redirect_location.present?
|
38
|
+
redirect_to_occurrences << { controller_action: current_app_controller_method, redirect_location: redirect_location }
|
39
|
+
end
|
40
|
+
continued_from_previous_line = false
|
41
|
+
elsif app_controller_file_line =~ /\s+def\s[A-Za-z0-9_][A-Za-z0-9_!\?=]+/
|
42
|
+
current_app_controller_method = app_controller_file_line.scan(/\s+def\s([A-Za-z0-9_][A-Za-z0-9_!\?=]+)/).flatten.first
|
43
|
+
elsif app_controller_file_line =~ /^\s+redirect_to(?:\s+|\s*\()\s*:?[a-z0-9_]+/
|
44
|
+
redirect_location = app_controller_file_line.scan(/^\s+redirect_to(?:\s+|\s*\()\s*(:?[a-z0-9_]+)/).flatten.first
|
45
|
+
if current_app_controller_method.present? && redirect_location.present?
|
46
|
+
redirect_to_occurrences << { controller_action: current_app_controller_method, redirect_location: redirect_location }
|
47
|
+
end
|
48
|
+
elsif app_controller_file_line =~ /^\s+redirect_to(?:\s+|\s*\()\s*\n/
|
49
|
+
continued_from_previous_line = true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
redirect_to_occurrences
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_redirect_to_matcher_tests(app_controller_name, redirect_to_occurrences)
|
57
|
+
redirect_to_tests = []
|
58
|
+
app_controller_route_controller = compose_route_controller(app_controller_name)
|
59
|
+
redirect_to_occurrences.each do |redirect_to_occurrence|
|
60
|
+
app_controller_action_routes = get_app_controller_routes_by_action(app_controller_route_controller, redirect_to_occurrence[:controller_action])
|
61
|
+
app_controller_action_routes.each do |app_controller_action_route|
|
62
|
+
redirect_to_test = generate_redirect_to_test(app_controller_route_controller, app_controller_action_route, redirect_to_occurrence)
|
63
|
+
redirect_to_tests = append_element(redirect_to_test, redirect_to_tests)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
format_tests(redirect_to_tests)
|
67
|
+
end
|
68
|
+
|
69
|
+
def generate_redirect_to_test(app_controller_route_controller, app_controller_action_route, redirect_to_occurrence)
|
70
|
+
if redirect_to_occurrence[:redirect_location] =~ /^:/
|
71
|
+
redirect_to_action_and_path_hash = compose_redirect_to_action_and_path_hash_for_action(app_controller_route_controller, redirect_to_occurrence[:redirect_location])
|
72
|
+
elsif redirect_to_occurrence[:redirect_location] =~ /_path$/
|
73
|
+
redirect_to_action_and_path_hash = compose_redirect_to_action_and_path_hash_for_path(app_controller_action_route, redirect_to_occurrence[:redirect_location])
|
74
|
+
else
|
75
|
+
redirect_to_action_and_path_hash = { action: "", path: "" }
|
76
|
+
end
|
77
|
+
if redirect_to_action_and_path_hash[:action].present? || redirect_to_action_and_path_hash[:path].present?
|
78
|
+
compose_redirect_to_test(app_controller_action_route, redirect_to_action_and_path_hash)
|
79
|
+
else
|
80
|
+
""
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def compose_redirect_to_action_and_path_hash_for_action(app_controller_route_controller, redirect_location)
|
85
|
+
redirect_to_action_and_path_hash = {}
|
86
|
+
redirect_routes = get_app_controller_routes_by_action(app_controller_route_controller, redirect_location)
|
87
|
+
redirect_to_action_and_path_hash[:action] = redirect_location
|
88
|
+
if redirect_routes.present? && redirect_routes.first.name.present?
|
89
|
+
redirect_to_action_and_path_hash[:path] = redirect_routes.first.name.concat("_path")
|
90
|
+
else
|
91
|
+
redirect_to_action_and_path_hash[:path] = ""
|
92
|
+
end
|
93
|
+
redirect_to_action_and_path_hash
|
94
|
+
end
|
95
|
+
|
96
|
+
def compose_redirect_to_action_and_path_hash_for_path(app_controller_action_route, redirect_location)
|
97
|
+
redirect_to_action_and_path_hash = {}
|
98
|
+
redirect_routes = get_app_controller_routes_by_path(redirect_location)
|
99
|
+
if redirect_routes.present? && redirect_routes.first.defaults[:controller] == app_controller_action_route.defaults[:controller]
|
100
|
+
redirect_to_action_and_path_hash[:action] = redirect_routes.first.defaults[:action]
|
101
|
+
else
|
102
|
+
redirect_to_action_and_path_hash[:action] = ""
|
103
|
+
end
|
104
|
+
redirect_to_action_and_path_hash[:path] = redirect_location
|
105
|
+
redirect_to_action_and_path_hash
|
106
|
+
end
|
107
|
+
|
108
|
+
def compose_redirect_to_test(app_controller_action_route, redirect_to_action_and_path_hash)
|
109
|
+
app_controller_route_http_method = get_route_http_method(app_controller_action_route)
|
110
|
+
app_controller_action = app_controller_action_route.defaults[:action].to_s
|
111
|
+
redirect_to_test = " describe '#{ app_controller_route_http_method } ##{ app_controller_action }' do\n"
|
112
|
+
redirect_to_test.concat(" before { #{ app_controller_route_http_method.downcase } :#{ app_controller_action } }\n\n")
|
113
|
+
if redirect_to_action_and_path_hash[:path].present?
|
114
|
+
redirect_to_test.concat(" it { is_expected.to redirect_to(#{ redirect_to_action_and_path_hash[:path] }) }\n")
|
115
|
+
end
|
116
|
+
if redirect_to_action_and_path_hash[:action].present?
|
117
|
+
redirect_to_test.concat(" it { is_expected.to redirect_to(action: #{ redirect_to_action_and_path_hash[:action] }) }\n")
|
118
|
+
end
|
119
|
+
redirect_to_test.concat(" end\n")
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Controller
|
3
|
+
module ActionController
|
4
|
+
module Matchmaker
|
5
|
+
module RenderTemplate
|
6
|
+
|
7
|
+
|
8
|
+
def render_template_matcher_tests
|
9
|
+
render_template_occurrences = get_render_template_occurrences(@app_controller_name)
|
10
|
+
if render_template_occurrences.present?
|
11
|
+
generate_render_template_matcher_tests(render_template_occurrences)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def get_render_template_occurrences(app_controller_name)
|
21
|
+
render_template_occurrences = []
|
22
|
+
app_views_path = Rails.root.join("app", "views").to_s + "/"
|
23
|
+
app_controller_views_path = app_views_path + app_controller_name.underscore.sub(/_controller$/, "/")
|
24
|
+
%w(erb haml slim).each do |view_file_format|
|
25
|
+
render_template_occurrences = render_template_occurrences + get_render_template_occurrences_by_file_type(app_controller_name, app_views_path, app_controller_views_path, view_file_format)
|
26
|
+
end
|
27
|
+
render_template_occurrences
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_render_template_occurrences_by_file_type(app_controller_name, app_views_path, app_controller_views_path, view_file_format)
|
31
|
+
render_template_occurrences_by_file_type = []
|
32
|
+
Dir.glob(app_controller_views_path + "**/*.html." + view_file_format) do |view_file_path|
|
33
|
+
view_action_render_occurrences = parse_controller_for_view_action_render_occurrences(view_file_path, app_views_path)
|
34
|
+
if view_action_render_occurrences.present?
|
35
|
+
view_action = get_view_from_path(view_file_path).sub(".html." + view_file_format, "")
|
36
|
+
if containing_method_is_action(app_controller_name, view_action)
|
37
|
+
render_template_occurrence_hashes = compose_render_template_occurrence_hashes(app_controller_name, view_action, view_action_render_occurrences)
|
38
|
+
render_template_occurrences_by_file_type = render_template_occurrences_by_file_type + render_template_occurrence_hashes
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
render_template_occurrences_by_file_type
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_controller_for_view_action_render_occurrences(view_file_path, app_views_path)
|
46
|
+
view_action_render_occurrences = []
|
47
|
+
File.open(view_file_path, 'r') do |view_file|
|
48
|
+
view_file.each_line do |view_file_line|
|
49
|
+
if view_file_line =~ /(?:\s+render|=render)(?:\s+action:\s+|\s+:action\s+=\>\s+|\s+file:\s+|\s+:file\s+=\>\s+|\s+partial:\s+|\s+:partial\s+=\>\s+|\s+template:\s+|\s+:template\s+=\>\s+|\s+)["':][A-Za-z0-9_\/\.]+"*'*\s*$/
|
50
|
+
view_action_render_occurrence = compose_view_action_render_occurrence_hash(app_views_path, view_file_path, view_file_line)
|
51
|
+
view_action_render_occurrences = append_element(view_action_render_occurrence, view_action_render_occurrences)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
view_action_render_occurrences
|
56
|
+
end
|
57
|
+
|
58
|
+
def compose_view_action_render_occurrence_hash(app_views_path, view_file_path, view_file_line)
|
59
|
+
render_view_type, render_view_path = view_file_line.match(/(?:\s+render|=render)(\s+action:\s+|\s+:action\s+=\>\s+|\s+file:\s+|\s+:file\s+=\>\s+|\s+partial:\s+|\s+:partial\s+=\>\s+|\s+template:\s+|\s+:template\s+=\>\s+|\s+)["':]([A-Za-z0-9_\/\.]+)/).captures
|
60
|
+
if render_view_type.present?
|
61
|
+
render_view_type = render_view_type.gsub(/\s+/,"").gsub(":", "").gsub("=>","")
|
62
|
+
else
|
63
|
+
render_view_type = get_render_view_type(app_views_path, view_file_path, render_view_path)
|
64
|
+
end
|
65
|
+
{ render_view_type: render_view_type, render_view: render_view_path }
|
66
|
+
end
|
67
|
+
|
68
|
+
def compose_render_template_occurrence_hashes(app_controller_name, view_action, view_action_render_occurrences)
|
69
|
+
render_template_occurrence_hashes = []
|
70
|
+
app_controller_routes_controller = compose_route_controller(app_controller_name)
|
71
|
+
view_action_routes = get_app_controller_routes_by_action(app_controller_routes_controller, view_action)
|
72
|
+
view_action_routes.each do |view_action_route|
|
73
|
+
view_action_http_method = get_route_http_method(view_action_route)
|
74
|
+
render_template_occurrence_hashes << { view_action: view_action, view_action_http_method: view_action_http_method, view_action_render_occurrences: view_action_render_occurrences }
|
75
|
+
end
|
76
|
+
render_template_occurrence_hashes
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_render_template_matcher_tests(render_template_occurrences)
|
80
|
+
render_template_tests = []
|
81
|
+
render_template_occurrences.sort_by!{ |rto| [rto[:view_action], rto[:view_action_http_method]] }
|
82
|
+
render_template_occurrences.each do |render_template_occurrence|
|
83
|
+
render_template_test = generate_render_template_test_initial(render_template_occurrence)
|
84
|
+
render_template_occurrence[:view_action_render_occurrences].sort_by!{ |varo| [varo[:render_view_type], varo[:render_view]] }
|
85
|
+
render_template_occurrence[:view_action_render_occurrences].each do |view_action_render_occurrence|
|
86
|
+
view_action_render_occurrence_test = generate_view_action_render_occurrence_test(view_action_render_occurrence)
|
87
|
+
render_template_test.concat(view_action_render_occurrence_test)
|
88
|
+
end
|
89
|
+
render_template_test.concat(" end")
|
90
|
+
render_template_tests = append_element(render_template_test, render_template_tests)
|
91
|
+
end
|
92
|
+
format_tests(render_template_tests)
|
93
|
+
end
|
94
|
+
|
95
|
+
def generate_render_template_test_initial(render_template_occurrence)
|
96
|
+
render_template_test = " describe '#{ render_template_occurrence[:view_action_http_method] } ##{ render_template_occurrence[:view_action] }' do\n"
|
97
|
+
render_template_test.concat(" before { #{ render_template_occurrence[:view_action_http_method].downcase } :#{ render_template_occurrence[:view_action] } }\n\n")
|
98
|
+
render_template_test.concat(" it { is_expected.to render_template('#{ render_template_occurrence[:view_action] }') }\n")
|
99
|
+
end
|
100
|
+
|
101
|
+
def generate_view_action_render_occurrence_test(view_action_render_occurrence)
|
102
|
+
if view_action_render_occurrence[:render_view_type] == "partial" && view_action_render_occurrence[:render_view].include?("/") ||
|
103
|
+
view_action_render_occurrence[:render_view_type] == "file"
|
104
|
+
view_action_render_occurrence_test = " it { is_expected.to render_template(#{ view_action_render_occurrence[:render_view_type] }: '"
|
105
|
+
elsif view_action_render_occurrence[:render_view_type] == "partial"
|
106
|
+
view_action_render_occurrence_test = " it { is_expected.to render_template(#{ view_action_render_occurrence[:render_view_type] }: '_"
|
107
|
+
elsif view_action_render_occurrence[:render_view_type] == "unknown"
|
108
|
+
view_action_render_occurrence_test = " # Unknown view type. Remove 'x' from 'xit' once view type identified (e.g. 'partial:', 'file:', etc.)\n"
|
109
|
+
view_action_render_occurrence_test.concat(" xit { is_expected.to render_template('")
|
110
|
+
else
|
111
|
+
view_action_render_occurrence_test = " it { is_expected.to render_template('"
|
112
|
+
end
|
113
|
+
view_action_render_occurrence_test.concat("#{ view_action_render_occurrence[:render_view] }') }\n")
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_render_view_type(app_views_path, view_file_path, render_view_path)
|
117
|
+
render_view_and_directory = get_internal_render_view_and_directory(app_views_path, view_file_path, render_view_path)
|
118
|
+
render_view_type = identify_internal_render_view_type(render_view_and_directory, app_views_path)
|
119
|
+
if render_view_type == "unknown" && render_view_path.include?("/")
|
120
|
+
render_view_and_directory = get_external_render_view_and_directory(render_view_path)
|
121
|
+
render_view_type = identify_external_render_view_type(render_view_and_directory)
|
122
|
+
end
|
123
|
+
render_view_type
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_internal_render_view_and_directory(app_views_path, view_file_path, render_view_path)
|
127
|
+
if render_view_path.include?("/")
|
128
|
+
render_view_directory = get_view_directory_prepended(render_view_path,app_views_path)
|
129
|
+
render_view = get_view_from_path(render_view_path).sub(/^\s*_/,"")
|
130
|
+
else
|
131
|
+
render_view_directory = get_view_directory_from_path(view_file_path)
|
132
|
+
render_view = render_view_path.sub(/^\s*_/,"")
|
133
|
+
end
|
134
|
+
{ directory: render_view_directory, view: render_view }
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_external_render_view_and_directory(render_view_path)
|
138
|
+
render_view_directory = get_view_directory_from_path(render_view_path)
|
139
|
+
render_view = get_view_from_path(render_view_path)
|
140
|
+
{ directory: render_view_directory, view: render_view }
|
141
|
+
end
|
142
|
+
|
143
|
+
def get_view_from_path(view_path)
|
144
|
+
view_path.scan(/\/([a-zA-z0-9.]+)$/).last.first
|
145
|
+
end
|
146
|
+
|
147
|
+
def get_view_directory_from_path(view_path)
|
148
|
+
view_path.sub(/\/[a-zA-z0-9.]+$/,"/")
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_view_directory_prepended(view_path, prepend_path)
|
152
|
+
view_path.sub(/\/[a-zA-z0-9.]+$/,"/").prepend(prepend_path)
|
153
|
+
end
|
154
|
+
|
155
|
+
def identify_internal_render_view_type(render_view_and_directory, app_views_path)
|
156
|
+
render_view_type = "unknown"
|
157
|
+
if view_partial_exist(render_view_and_directory)
|
158
|
+
render_view_type = "partial"
|
159
|
+
elsif view_exist(render_view_and_directory)
|
160
|
+
render_view_controller_name = get_controller_name_from_view_directory_path(render_view_and_directory[:directory], app_views_path)
|
161
|
+
if render_view_controller_name.present? && containing_method_is_action(render_view_controller_name, render_view_and_directory[:view])
|
162
|
+
render_view_type = "action"
|
163
|
+
else
|
164
|
+
render_view_type = "template"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
render_view_type
|
168
|
+
end
|
169
|
+
|
170
|
+
def identify_external_render_view_type(render_view_and_directory)
|
171
|
+
render_view_type = "unknown"
|
172
|
+
if view_partial_exist(render_view_and_directory) || view_exist(render_view_and_directory)
|
173
|
+
render_view_type = "file"
|
174
|
+
end
|
175
|
+
render_view_type
|
176
|
+
end
|
177
|
+
|
178
|
+
def view_exist(render_view_and_directory)
|
179
|
+
File.exist?(render_view_and_directory[:directory] + render_view_and_directory[:view] + ".html.erb") ||
|
180
|
+
File.exist?(render_view_and_directory[:directory] + render_view_and_directory[:view] + ".html.haml") ||
|
181
|
+
File.exist?(render_view_and_directory[:directory] + render_view_and_directory[:view] + ".html.slim")
|
182
|
+
end
|
183
|
+
|
184
|
+
def view_partial_exist(render_view_and_directory)
|
185
|
+
File.exist?(render_view_and_directory[:directory] + "_" + render_view_and_directory[:view] + ".html.erb") ||
|
186
|
+
File.exist?(render_view_and_directory[:directory] + "_" + render_view_and_directory[:view] + ".html.haml") ||
|
187
|
+
File.exist?(render_view_and_directory[:directory] + "_" + render_view_and_directory[:view] + ".html.slim")
|
188
|
+
end
|
189
|
+
|
190
|
+
def get_controller_name_from_view_directory_path(view_directory_path, app_views_path)
|
191
|
+
view_directory_path.sub(app_views_path, "").sub(/\/$/,"").concat("_controller").camelize
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Controller
|
3
|
+
module ActionController
|
4
|
+
module Matchmaker
|
5
|
+
module RenderWithLayout
|
6
|
+
|
7
|
+
|
8
|
+
def render_with_layout_matcher_tests
|
9
|
+
render_with_layout_occurrences = get_render_with_layout_occurrences(@app_controller_name)
|
10
|
+
if render_with_layout_occurrences.present?
|
11
|
+
generate_render_with_layout_matcher_tests(@app_controller_name, render_with_layout_occurrences)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def get_render_with_layout_occurrences(app_controller_name)
|
21
|
+
render_with_layout_occurrences = []
|
22
|
+
app_controller_file_path = compose_extended_app_controller_file_path(app_controller_name)
|
23
|
+
if File.exists?(app_controller_file_path)
|
24
|
+
render_with_layout_occurrences = parse_app_controller_for_render_with_layout_occurrences(app_controller_file_path)
|
25
|
+
end
|
26
|
+
render_with_layout_occurrences
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_app_controller_for_render_with_layout_occurrences(app_controller_file_path)
|
30
|
+
render_with_layout_occurrences = []
|
31
|
+
current_app_controller_method = nil
|
32
|
+
File.open(app_controller_file_path, 'r') do |app_controller_file|
|
33
|
+
app_controller_file.each_line do |app_controller_file_line|
|
34
|
+
if app_controller_file_line =~ /\s+def\s[A-Za-z0-9_][A-Za-z0-9_!\?=]+/
|
35
|
+
current_app_controller_method = app_controller_file_line.scan(/\s+def\s([A-Za-z0-9_][A-Za-z0-9_!\?=]+)/).flatten.first
|
36
|
+
elsif app_controller_file_line.include?(" render layout:")
|
37
|
+
render_with_layout_layout = app_controller_file_line.scan(/\s+render\slayout:\s['"]([a-z0-9_]+)/).flatten.first
|
38
|
+
if current_app_controller_method.present? && render_with_layout_layout.present?
|
39
|
+
render_with_layout_occurrences << { controller_action: current_app_controller_method, layout: render_with_layout_layout }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
render_with_layout_occurrences
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_render_with_layout_matcher_tests(app_controller_name, render_with_layout_occurrences)
|
48
|
+
render_with_layout_tests = []
|
49
|
+
render_with_layout_occurrences.sort_by!{ |rwlo| [rwlo[:controller_action], rwlo[:layout]] }
|
50
|
+
render_with_layout_occurrences.each do |render_with_layout_occurrence|
|
51
|
+
app_controller_route_controller = compose_route_controller(app_controller_name)
|
52
|
+
app_controller_action_routes = get_app_controller_routes_by_action(app_controller_route_controller, render_with_layout_occurrence[:controller_action])
|
53
|
+
app_controller_action_routes.each do |app_controller_action_route|
|
54
|
+
render_with_layout_test = generate_render_with_layout_test(app_controller_action_route, render_with_layout_occurrence)
|
55
|
+
append_element(render_with_layout_test, render_with_layout_tests)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
format_tests(render_with_layout_tests)
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_render_with_layout_test(app_controller_action_route, render_with_layout_occurrence)
|
62
|
+
app_controller_route_http_method = get_route_http_method(app_controller_action_route)
|
63
|
+
render_with_layout_test = " describe '#{ app_controller_route_http_method } ##{ render_with_layout_occurrence[:controller_action] }' do\n"
|
64
|
+
render_with_layout_test.concat(" before { #{ app_controller_route_http_method.downcase } :#{ render_with_layout_occurrence[:controller_action] } }\n\n")
|
65
|
+
render_with_layout_test.concat(" it { is_expected.to render_with_layout('#{ render_with_layout_occurrence[:layout] }') }\n end\n")
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module ShouldaMatchmakers
|
2
|
+
module Controller
|
3
|
+
module ActionController
|
4
|
+
module Matchmaker
|
5
|
+
module RescueFrom
|
6
|
+
|
7
|
+
|
8
|
+
def rescue_from_matcher_tests
|
9
|
+
rescue_from_occurrences = get_rescue_from_occurrences(@app_controller_name)
|
10
|
+
if rescue_from_occurrences.present?
|
11
|
+
generate_rescue_from_matcher_tests(rescue_from_occurrences)
|
12
|
+
else
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def get_rescue_from_occurrences(app_controller_name)
|
21
|
+
rescue_from_occurrences = []
|
22
|
+
app_controller_file_path = compose_extended_app_controller_file_path(app_controller_name)
|
23
|
+
if File.exists?(app_controller_file_path)
|
24
|
+
rescue_from_occurrences = parse_app_controller_for_rescue_from_occurrences(app_controller_file_path)
|
25
|
+
end
|
26
|
+
rescue_from_occurrences
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_app_controller_for_rescue_from_occurrences(app_controller_file_path)
|
30
|
+
rescue_from_occurrences = []
|
31
|
+
rescue_from_occurrence = {}
|
32
|
+
continued_from_previous_line = false
|
33
|
+
File.open(app_controller_file_path, 'r') do |app_controller_file|
|
34
|
+
app_controller_file.each_line do |app_controller_file_line|
|
35
|
+
if continued_from_previous_line
|
36
|
+
if app_controller_file_line =~ /^\s*with:\s+[A-Za-z0-9:_]+\s*$/
|
37
|
+
rescue_from_handler = app_controller_file_line.scan(/^\s*with:\s+([A-Za-z0-9:_]+)/).flatten.first
|
38
|
+
rescue_from_occurrence[:handler] = rescue_from_handler
|
39
|
+
rescue_from_occurrences << rescue_from_occurrence
|
40
|
+
rescue_from_occurrence = {}
|
41
|
+
continued_from_previous_line = false
|
42
|
+
elsif !app_controller_file_line =~ /\s*\n/
|
43
|
+
rescue_from_occurrence[:handler] = ":unidentified_rescue_from_handler"
|
44
|
+
rescue_from_occurrences << rescue_from_occurrence
|
45
|
+
rescue_from_occurrence = {}
|
46
|
+
continued_from_previous_line = false
|
47
|
+
end
|
48
|
+
elsif app_controller_file_line =~ /^\s+rescue_from(?:\s+|\s*\()[A-Za-z0-9:]+\s*\)?,\s*with:\s+[A-Za-z0-9:_]+\s*$/
|
49
|
+
rescue_from_exception, rescue_from_handler = app_controller_file_line.match(/^\s+rescue_from(?:\s+|\s*\()([A-Za-z0-9:]+)\s*\)?,\s*with:\s+([A-Za-z0-9:_]+)/).captures
|
50
|
+
rescue_from_occurrence = { exception: rescue_from_exception, handler: rescue_from_handler }
|
51
|
+
rescue_from_occurrences << rescue_from_occurrence
|
52
|
+
rescue_from_occurrence = {}
|
53
|
+
continued_from_previous_line = false
|
54
|
+
elsif app_controller_file_line =~ /^\s+rescue_from(?:\s+|\s*\()[A-Za-z0-9:]+\s*\)?,\s*$/
|
55
|
+
rescue_from_exception = app_controller_file_line.scan(/^\s+rescue_from(?:\s+|\s*\()([A-Za-z0-9:]+)/).flatten.first
|
56
|
+
rescue_from_occurrence = { exception: rescue_from_exception }
|
57
|
+
continued_from_previous_line = true
|
58
|
+
elsif app_controller_file_line =~ /\s+rescue_from(?:\s+|\s*\()[A-Za-z0-9:]+\s*\)?/
|
59
|
+
rescue_from_exception = app_controller_file_line.scan(/^\s+rescue_from(?:\s+|\s*\()([A-Za-z0-9:]+)/).flatten.first
|
60
|
+
rescue_from_occurrence = { exception: rescue_from_exception, handler: ":unidentified_rescue_from_handler" }
|
61
|
+
rescue_from_occurrences << rescue_from_occurrence
|
62
|
+
rescue_from_occurrence = {}
|
63
|
+
continued_from_previous_line = false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
rescue_from_occurrences
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_rescue_from_matcher_tests(rescue_from_occurrences)
|
71
|
+
rescue_from_tests = []
|
72
|
+
rescue_from_occurrences.each do |rescue_from_occurrence|
|
73
|
+
rescue_from_test = generate_rescue_from_test(rescue_from_occurrence)
|
74
|
+
rescue_from_tests = append_element(rescue_from_test, rescue_from_tests)
|
75
|
+
end
|
76
|
+
format_tests(rescue_from_tests)
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_rescue_from_test(rescue_from_occurrence)
|
80
|
+
if rescue_from_occurrence[:handler] == ":unidentified_rescue_from_handler"
|
81
|
+
rescue_from_test = "# A rescue_from occurrence contains complexities that make it difficult for ShouldaMatchmakers to parse completely.\n"
|
82
|
+
rescue_from_test.concat("# Examine the rescue_from occurrence for '#{ rescue_from_occurrence[:exception] }' to determine the appropriate\n")
|
83
|
+
rescue_from_test.concat("# syntax for the test and any required values, such as ':unidentified_rescue_from_handler' below.\n")
|
84
|
+
rescue_from_test.concat("# Remove 'x' from 'xit' once the proper syntax has been established and required values have been provided.\n")
|
85
|
+
rescue_from_test.concat(" xit do\n is_expected.to rescue_from(#{ rescue_from_occurrence[:exception] }).\n")
|
86
|
+
else
|
87
|
+
rescue_from_test = " it do\n is_expected.to rescue_from(#{ rescue_from_occurrence[:exception] }).\n"
|
88
|
+
end
|
89
|
+
rescue_from_test.concat(" with(#{ rescue_from_occurrence[:handler] })\n end\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|