shoulda_matchmakers 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +21 -0
  4. data/lib/controller/action_controller/action_controller_controller_sm_model.rb +53 -0
  5. data/lib/controller/action_controller/action_controller_controller_sm_model_helper.rb +73 -0
  6. data/lib/controller/action_controller/matchmakers/callbacks.rb +56 -0
  7. data/lib/controller/action_controller/matchmakers/filter_param.rb +69 -0
  8. data/lib/controller/action_controller/matchmakers/permit.rb +510 -0
  9. data/lib/controller/action_controller/matchmakers/redirect_to.rb +126 -0
  10. data/lib/controller/action_controller/matchmakers/render_template.rb +198 -0
  11. data/lib/controller/action_controller/matchmakers/render_with_layout.rb +72 -0
  12. data/lib/controller/action_controller/matchmakers/rescue_from.rb +96 -0
  13. data/lib/controller/action_controller/matchmakers/respond_with.rb +71 -0
  14. data/lib/controller/action_controller/matchmakers/route.rb +586 -0
  15. data/lib/controller/action_controller/matchmakers/set_flash.rb +136 -0
  16. data/lib/controller/action_controller/matchmakers/set_session.rb +115 -0
  17. data/lib/controller/action_controller/permitted_params_definition.rb +60 -0
  18. data/lib/generators/shoulda_matchmakers/controller_matcher_generator.rb +87 -0
  19. data/lib/generators/shoulda_matchmakers/controller_matcher_generator_helper.rb +92 -0
  20. data/lib/generators/shoulda_matchmakers/factory_generator.rb +86 -0
  21. data/lib/generators/shoulda_matchmakers/install_generator.rb +10 -0
  22. data/lib/generators/shoulda_matchmakers/model_matcher_generator.rb +87 -0
  23. data/lib/generators/shoulda_matchmakers/model_matcher_generator_helper.rb +107 -0
  24. data/lib/model/active_record/active_record_model_sm_model.rb +50 -0
  25. data/lib/model/active_record/active_record_model_sm_model_helper.rb +206 -0
  26. data/lib/model/active_record/factory_sm_model.rb +28 -0
  27. data/lib/model/active_record/factory_sm_model_helper.rb +124 -0
  28. data/lib/model/active_record/matchmakers/accept_nested_attributes_for.rb +66 -0
  29. data/lib/model/active_record/matchmakers/allow_value.rb +137 -0
  30. data/lib/model/active_record/matchmakers/associations.rb +52 -0
  31. data/lib/model/active_record/matchmakers/define_enum_for.rb +53 -0
  32. data/lib/model/active_record/matchmakers/delegate_method.rb +101 -0
  33. data/lib/model/active_record/matchmakers/have_db_column.rb +33 -0
  34. data/lib/model/active_record/matchmakers/have_db_index.rb +39 -0
  35. data/lib/model/active_record/matchmakers/have_readonly_attribute.rb +32 -0
  36. data/lib/model/active_record/matchmakers/have_secure_password.rb +32 -0
  37. data/lib/model/active_record/matchmakers/serialize.rb +67 -0
  38. data/lib/model/active_record/matchmakers/validations.rb +169 -0
  39. data/lib/model/active_record/options_definition.rb +160 -0
  40. data/lib/shoulda_matchmakers.rb +48 -0
  41. data/lib/shoulda_matchmakers/version.rb +3 -0
  42. data/lib/support/command_line_interface.rb +100 -0
  43. data/lib/support/controller_generator.rb +198 -0
  44. data/lib/support/indefinite_article.rb +70 -0
  45. data/lib/support/to_discard/belong_to.rb +94 -0
  46. data/lib/support/to_discard/have_and_belong_to_many.rb +83 -0
  47. data/lib/support/to_discard/have_many.rb +96 -0
  48. data/lib/support/to_discard/have_one.rb +98 -0
  49. data/lib/support/to_discard/permit_refactor.rb +270 -0
  50. data/lib/support/to_discard/render_template_new.rb +204 -0
  51. data/lib/support/to_discard/render_template_reconstruction.rb +188 -0
  52. data/lib/support/to_discard/use_around_action.rb +20 -0
  53. data/lib/support/to_discard/use_before_action.rb +20 -0
  54. data/lib/support/to_discard/validate_absence_of.rb +16 -0
  55. data/lib/support/to_discard/validate_acceptance_of.rb +16 -0
  56. data/lib/support/to_discard/validate_confirmation_of.rb +16 -0
  57. data/lib/support/to_discard/validate_exclusion_of.rb +145 -0
  58. data/lib/support/to_discard/validate_inclusion_of.rb +94 -0
  59. data/lib/support/to_discard/validate_length_of.rb +16 -0
  60. data/lib/support/to_discard/validate_numericality_of.rb +16 -0
  61. data/lib/support/to_discard/validate_presence_of.rb +16 -0
  62. data/lib/support/to_discard/validate_uniqueness_of.rb +16 -0
  63. data/lib/support/to_discard/validation_old.rb +37 -0
  64. data/lib/support/to_discard/validations.rb +41 -0
  65. data/lib/support/to_discard/validations_conditional.rb +146 -0
  66. data/lib/support/trace_debug_lines.txt +319 -0
  67. data/lib/support/util.rb +15 -0
  68. data/lib/templates/controller/action_controller/controller_spec_template.haml +146 -0
  69. data/lib/templates/factory/active_record/factory_template.haml +13 -0
  70. data/lib/templates/model/active_record/model_spec_template.haml +233 -0
  71. data/lib/templates/shoulda_matchmakers.rb +112 -0
  72. metadata +263 -0
@@ -0,0 +1,136 @@
1
+ module ShouldaMatchmakers
2
+ module Controller
3
+ module ActionController
4
+ module Matchmaker
5
+ module SetFlash
6
+
7
+
8
+ def set_flash_matcher_tests
9
+ set_flash_occurrences = get_set_flash_occurrences(@app_controller_name)
10
+ if set_flash_occurrences.present?
11
+ generate_set_flash_matcher_tests(@app_controller_name, set_flash_occurrences)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def get_set_flash_occurrences(app_controller_name)
21
+ app_controller_file_path = compose_extended_app_controller_file_path(app_controller_name)
22
+ if File.exists?(app_controller_file_path)
23
+ set_flash_occurrences = parse_controller_for_set_flash_occurrences(app_controller_name, app_controller_file_path)
24
+ else
25
+ set_flash_occurrences = []
26
+ end
27
+ set_flash_occurrences
28
+ end
29
+
30
+ def parse_controller_for_set_flash_occurrences(app_controller_name, app_controller_file_path)
31
+ set_flash_occurrences = []
32
+ current_app_controller_method = nil
33
+ File.open(app_controller_file_path, 'r') do |app_controller_file|
34
+ app_controller_file.each_line do |app_controller_file_line|
35
+ flash_key_value_option = {}
36
+ if app_controller_file_line =~ /\s+def\s[A-Za-z0-9_][A-Za-z0-9_!\?=]+/
37
+ current_app_controller_method = app_controller_file_line.scan(/\s+def\s([A-Za-z0-9_][A-Za-z0-9_!\?=]+)/).flatten.first
38
+ elsif app_controller_file_line =~ /^\s+flash\[:[A-Za-z0-9_]+\]\s*=/ || app_controller_file_line =~ /^\s+flash.now\[:[A-Za-z0-9_]+\]\s*=/
39
+ flash_key_value_option = get_flash_key_value_option(app_controller_file_line)
40
+ elsif app_controller_file_line =~ /^\s+set_flash_message[\s\(]\s*:[A-Za-z0-9_]+\s*,/
41
+ flash_key_value_option = get_set_flash_message_key_and_value(app_controller_file_line)
42
+ end
43
+ if current_app_controller_method.present? && containing_method_is_action(app_controller_name, current_app_controller_method) && flash_key_value_option[:flash_key].present?
44
+ set_flash_occurrences << { controller_action: current_app_controller_method, flash_hash: flash_key_value_option }
45
+ end
46
+ end
47
+ end
48
+ consolidate_set_flash_occurrences(set_flash_occurrences) if set_flash_occurrences.present?
49
+ end
50
+
51
+ def get_flash_key_value_option(app_controller_file_line)
52
+ flash_key = ""
53
+ flash_value = ""
54
+ flash_option = ""
55
+ if app_controller_file_line =~ /^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/
56
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/).captures
57
+ elsif app_controller_file_line =~ /^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/
58
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/).captures
59
+ elsif app_controller_file_line =~ /^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/
60
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/).captures
61
+ elsif app_controller_file_line =~ /^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/
62
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/).captures
63
+ flash_option = "now"
64
+ elsif app_controller_file_line =~ /^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/
65
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/).captures
66
+ flash_option = "now"
67
+ elsif app_controller_file_line =~ /^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/
68
+ flash_key, flash_value = app_controller_file_line.match(/^\s+flash\.now\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/).captures
69
+ flash_option = "now"
70
+ end
71
+ { flash_key: flash_key, flash_value: flash_value, flash_option: flash_option }
72
+ end
73
+
74
+ def get_set_flash_message_key_and_value(app_controller_file_line)
75
+ flash_key = ""
76
+ flash_value = ""
77
+ if app_controller_file_line =~ /^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*:[A-Za-z0-9_]+,\s*'.+'\s*(?:\)\s*.*$|.*$)/
78
+ flash_key, flash_value = app_controller_file_line.match(/^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*(:[A-Za-z0-9_]+),\s*'(.+)'\s*(?:\)\s*.*$|.*$)/).captures
79
+ elsif app_controller_file_line =~ /^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*:[A-Za-z0-9_]+,\s*".+"\s*(?:\)\s*.*$|.*$)/
80
+ flash_key, flash_value = app_controller_file_line.match(/^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*(:[A-Za-z0-9_]+),\s*"(.+)"\s*(?:\)\s*.*$|.*$)/).captures
81
+ elsif app_controller_file_line =~ /^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*:[A-Za-z0-9_]+,\s*(?::[a-zA-Z0-9_]+|[a-zA-Z0-9_]+|"[a-zA-Z0-9_\s'{}#.]+"|'[a-zA-Z0-9_\s"{}#.]+'|:"[a-zA-Z0-9_\s'{}#.]+"|:'[a-zA-Z0-9_\s"{}#.]+')\s*(?:$|,.*$|\).*$|\s.*$)/
82
+ flash_key, flash_value = app_controller_file_line.match(/^\s+set_flash_message(?:\s|\(|\!\s|\!\()\s*(:[A-Za-z0-9_]+),\s*(:[a-zA-Z0-9_]+|[a-zA-Z0-9_]+|"[a-zA-Z0-9_\s'{}#.]+"|'[a-zA-Z0-9_\s"{}#.]+'|:"[a-zA-Z0-9_\s'{}#.]+"|:'[a-zA-Z0-9_\s"{}#.]+')\s*(?:$|,.*$|\).*$|\s.*$)/).captures
83
+ end
84
+ { flash_key: flash_key, flash_value: flash_value, flash_option: "" }
85
+ end
86
+
87
+ def consolidate_set_flash_occurrences(set_flash_occurrences)
88
+ consolidated_occurrences = []
89
+ consolidated_occurrence = {}
90
+ previous_controller_action = ""
91
+ set_flash_occurrences.sort_by!{ |sfo| [sfo[:controller_action], sfo[:flash_hash][:flash_option], sfo[:flash_hash][:flash_key], sfo[:flash_hash][:flash_value]] }
92
+ set_flash_occurrences.each do |set_flash_occurrence|
93
+ if set_flash_occurrence[:controller_action] == previous_controller_action
94
+ consolidated_occurrence[:flash_hashes] << set_flash_occurrence[:flash_hash]
95
+ else
96
+ consolidated_occurrences = append_element(consolidated_occurrence, consolidated_occurrences)
97
+ consolidated_occurrence = { controller_action: set_flash_occurrence[:controller_action], flash_hashes: [set_flash_occurrence[:flash_hash]] }
98
+ previous_controller_action = set_flash_occurrence[:controller_action]
99
+ end
100
+ end
101
+ append_element(consolidated_occurrence, consolidated_occurrences)
102
+ end
103
+
104
+ def generate_set_flash_matcher_tests(app_controller_name, set_flash_occurrences)
105
+ set_flash_tests = []
106
+ set_flash_occurrences.each do |set_flash_occurrence|
107
+ app_controller_route_controller = app_controller_name.underscore.sub(/_controller$/, "")
108
+ app_controller_action_routes = get_app_controller_routes_by_action(app_controller_route_controller, set_flash_occurrence[:controller_action])
109
+ if app_controller_action_routes.present?
110
+ app_controller_action_routes.each do |app_controller_action_route|
111
+ set_flash_test = generate_set_flash_test(app_controller_action_route, set_flash_occurrence)
112
+ set_flash_tests = append_element(set_flash_test, set_flash_tests)
113
+ end
114
+ # else
115
+ # set_flash_occurrence exists in non-action method
116
+ end
117
+ end
118
+ format_tests(set_flash_tests)
119
+ end
120
+
121
+ def generate_set_flash_test(app_controller_action_route, set_flash_occurrence)
122
+ app_controller_route_http_method = get_route_http_method(app_controller_action_route)
123
+ set_flash_test = " describe '#{ app_controller_route_http_method } ##{ set_flash_occurrence[:controller_action] }' do\n"
124
+ set_flash_test.concat(" before { #{ app_controller_route_http_method.downcase } :#{ set_flash_occurrence[:controller_action] } }\n\n")
125
+ set_flash_occurrence[:flash_hashes].each do |flash_hash|
126
+ set_flash_test.concat(" it { is_expected.to set_flash[#{ flash_hash[:flash_key] }].to(#{ flash_hash[:flash_value] }) }\n")
127
+ set_flash_test.sub!(" set_flash", " set_flash.now") if flash_hash[:flash_option] == "now"
128
+ end
129
+ set_flash_test.concat(" end")
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,115 @@
1
+ module ShouldaMatchmakers
2
+ module Controller
3
+ module ActionController
4
+ module Matchmaker
5
+ module SetSession
6
+
7
+
8
+ def set_session_matcher_tests
9
+ set_session_occurrences = get_set_session_occurrences(@app_controller_name)
10
+ if set_session_occurrences.present?
11
+ generate_set_session_matcher_tests(@app_controller_name, set_session_occurrences)
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def get_set_session_occurrences(app_controller_name)
21
+ app_controller_file_path = compose_extended_app_controller_file_path(app_controller_name)
22
+ if File.exists?(app_controller_file_path)
23
+ set_session_occurrences = parse_controller_for_set_session_occurrences(app_controller_name, app_controller_file_path)
24
+ if set_session_occurrences.present?
25
+ set_session_occurrences = consolidate_set_session_occurrences(set_session_occurrences)
26
+ end
27
+ else
28
+ set_session_occurrences = []
29
+ end
30
+ set_session_occurrences
31
+ end
32
+
33
+ def parse_controller_for_set_session_occurrences(app_controller_name, app_controller_file_path)
34
+ set_session_occurrences = []
35
+ current_app_controller_method = nil
36
+ File.open(app_controller_file_path, 'r') do |app_controller_file|
37
+ app_controller_file.each_line do |app_controller_file_line|
38
+ session_key_and_value = {}
39
+ if app_controller_file_line =~ /\s+def\s[A-Za-z0-9_][A-Za-z0-9_!\?=]+/
40
+ current_app_controller_method = app_controller_file_line.scan(/\s+def\s([A-Za-z0-9_][A-Za-z0-9_!\?=]+)/).flatten.first
41
+ elsif app_controller_file_line =~ /^\s+session\[:[A-Za-z0-9_]+\]\s*=/
42
+ session_key_and_value = get_session_key_and_value(app_controller_file_line)
43
+ end
44
+ if current_app_controller_method.present? && session_key_and_value[:session_key].present?
45
+ if containing_method_is_action(app_controller_name, current_app_controller_method)
46
+ set_session_occurrences << { controller_action: current_app_controller_method, session_hash: session_key_and_value }
47
+ end
48
+ end
49
+ end
50
+ end
51
+ set_session_occurrences
52
+ end
53
+
54
+ def get_session_key_and_value(app_controller_file_line)
55
+ session_key = ""
56
+ session_value = ""
57
+ if app_controller_file_line =~ /^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/
58
+ session_key, session_value = app_controller_file_line.match(/^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*('.+')(?:\s+[^(\s\?)].*$|\s*$)/).captures
59
+ elsif app_controller_file_line =~ /^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/
60
+ session_key, session_value = app_controller_file_line.match(/^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*(".+")(?:\s+[^(\s\?)].*$|\s*$)/).captures
61
+ elsif app_controller_file_line =~ /^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/
62
+ session_key, session_value = app_controller_file_line.match(/^\s+session\[(:[A-Za-z0-9_]+)\]\s*=\s*([a-zA-Z0-9_:]+)(\s+[^(\s\?)].*$|\s*$)/).captures
63
+ end
64
+ { session_key: session_key, session_value: session_value }
65
+ end
66
+
67
+ def consolidate_set_session_occurrences(set_session_occurrences)
68
+ consolidated_occurrences = []
69
+ consolidated_occurrence = {}
70
+ previous_controller_action = ""
71
+ set_session_occurrences.sort_by!{ |sso| [sso[:controller_action], sso[:session_hash][:session_key], sso[:session_hash][:session_value]] }
72
+ set_session_occurrences.each do |set_session_occurrence|
73
+ if set_session_occurrence[:controller_action] == previous_controller_action
74
+ consolidated_occurrence[:session_hashes] << set_session_occurrence[:session_hash]
75
+ else
76
+ consolidated_occurrences = append_element(consolidated_occurrence, consolidated_occurrences)
77
+ consolidated_occurrence = { controller_action: set_session_occurrence[:controller_action], session_hashes: [set_session_occurrence[:session_hash]] }
78
+ previous_controller_action = set_session_occurrence[:controller_action]
79
+ end
80
+ end
81
+ append_element(consolidated_occurrence, consolidated_occurrences)
82
+ end
83
+
84
+ def generate_set_session_matcher_tests(app_controller_name, set_session_occurrences)
85
+ set_session_tests = []
86
+ set_session_occurrences.each do |set_session_occurrence|
87
+ app_controller_route_controller = app_controller_name.underscore.sub(/_controller$/, "")
88
+ app_controller_action_routes = get_app_controller_routes_by_action(app_controller_route_controller, set_session_occurrence[:controller_action])
89
+ if app_controller_action_routes.present?
90
+ app_controller_action_routes.each do |app_controller_action_route|
91
+ set_session_test = generate_set_session_test(app_controller_action_route, set_session_occurrence)
92
+ set_session_tests << set_session_test
93
+ end
94
+ # else
95
+ # set_session_occurrence exists in non-action method
96
+ end
97
+ end
98
+ format_tests(set_session_tests)
99
+ end
100
+
101
+ def generate_set_session_test(app_controller_action_route, set_session_occurrence)
102
+ app_controller_route_http_method = get_route_http_method(app_controller_action_route)
103
+ set_session_test = " describe '#{ app_controller_route_http_method } ##{ set_session_occurrence[:controller_action] }' do\n"
104
+ set_session_test.concat(" before { #{ app_controller_route_http_method.downcase } :#{ set_session_occurrence[:controller_action] } }\n\n")
105
+ set_session_occurrence[:session_hashes].each do |session_hash|
106
+ set_session_test.concat(" it { is_expected.to set_session[#{ session_hash[:session_key] }].to(#{ session_hash[:session_value] }) }\n")
107
+ end
108
+ set_session_test.concat(" end")
109
+ end
110
+
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,60 @@
1
+ module ShouldaMatchmakers
2
+ module Controller
3
+ module ActionController
4
+ class PermittedParamsDefinition
5
+
6
+ ### Attribute Accessors ###
7
+ attr_accessor :calls,
8
+ :defining_controller,
9
+ :defining_method,
10
+ :params_array_type,
11
+ :params_class,
12
+ :params_class_controller_action,
13
+ :permitted_params,
14
+ :permitted_params_string
15
+
16
+ def initialize(defining_controller, defining_method, params_class)
17
+ @calls = []
18
+ @defining_controller = defining_controller
19
+ @defining_method = defining_method
20
+ @params_array_type = ""
21
+ @params_class = params_class
22
+ @params_class_controller_action = nil
23
+ @permitted_params = []
24
+ @permitted_params_string = ""
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ # module ShouldaMatchmakers
34
+ # module Controller
35
+ # module ActionController
36
+ # class PermittedParamsDefinition
37
+ #
38
+ # ### Attribute Accessors ###
39
+ # attr_accessor :calling_controller,
40
+ # :defining_method,
41
+ # :defining_method_calls,
42
+ # :params_class,
43
+ # :permitted_params,
44
+ # :permitted_params_string,
45
+ # :params_array_type
46
+ #
47
+ # def initialize(controller, defining_method, params_class, line)
48
+ # @calling_controller = controller
49
+ # @defining_method = defining_method
50
+ # @defining_method_calls = []
51
+ # @params_class = params_class
52
+ # @permitted_params = []
53
+ # @permitted_params_string = line
54
+ # @params_array_type = ""
55
+ # end
56
+ #
57
+ # end
58
+ # end
59
+ # end
60
+ # end
@@ -0,0 +1,87 @@
1
+ require 'haml'
2
+ require_relative 'controller_matcher_generator_helper'
3
+ require 'controller/action_controller/action_controller_controller_sm_model'
4
+ require 'spin_to_win'
5
+
6
+ module ShouldaMatchmakers
7
+ class ControllerMatcherGenerator < Rails::Generators::Base
8
+
9
+ include Generator::ActionController::ControllerMatcherGeneratorHelper
10
+
11
+ source_root(File.expand_path(File.dirname(__FILE__)))
12
+
13
+ class_option :include, type: :array,
14
+ require: false,
15
+ aliases: '-i',
16
+ default: [],
17
+ desc: "Sets list of application ActionController controllers to INCLUDE in generated tests.\n" +
18
+ " By default, tests are generated for all ActionController::Base descendants.\n" +
19
+ " When used, '_included' and '_excluded' settings in '~/config/initializers/shoulda_matchmakers.rb'\n" +
20
+ " configuration file are ignored. Example (space delimited, include namespaces):\n\n" +
21
+ " -i DriversController LicensesController Vehicle::CarsController Vehicle::BusesController\n\n\n"
22
+
23
+ class_option :exclude, type: :array,
24
+ require: false,
25
+ aliases: '-e',
26
+ default: [],
27
+ desc: "Sets list of application ActionController controllers to EXCLUDE from generated tests.\n" +
28
+ " By default, no ActionController::Base descendants are excluded from generated tests.\n" +
29
+ " When used, '_included' and '_excluded' settings in '~/config/initializers/shoulda_matchmakers.rb'\n" +
30
+ " configuration file are ignored. Example (space delimited, include namespaces):\n\n" +
31
+ " -e DriversController Vehicle::CarsController\n\n\n"
32
+
33
+ class_option :include_and_config, type: :array,
34
+ require: false,
35
+ aliases: '-I',
36
+ default: [],
37
+ desc: "Same as '-i/-include', except that '_included' and '_excluded' settings in\n" +
38
+ " '~/config/initializers/shoulda_matchmakers.rb' are not ignored. Configuration file\n" +
39
+ " settings are applied first then the controller names listed with this option are applied.\n" +
40
+ " Example (space delimited, include namespaces):\n\n" +
41
+ " -I DriversController LicensesController Vehicle::CarsController Vehicle::BusesController\n\n\n"
42
+
43
+ class_option :exclude_and_config, type: :array,
44
+ require: false,
45
+ aliases: '-E',
46
+ default: [],
47
+ desc: "Same as '-e/-exclude', except that '_included' and '_excluded' settings in\n" +
48
+ " '~/config/initializers/shoulda_matchmakers.rb' are not ignored. Configuration file\n" +
49
+ " settings are applied first then the controller names listed with this option are applied.\n" +
50
+ " Example (space delimited, include namespaces):\n\n" +
51
+ " -E DriversController Vehicle::CarsController\n\n\n"
52
+
53
+ def create_controller_matchmakers
54
+ puts "\n"
55
+ generator_options = options.to_hash
56
+ working_generated_code_line_length = ShouldaMatchmakers.configuration.preferred_generated_code_line_length - 6
57
+ SpinToWin.with_spinner('ShouldaMatchmakers:ControllerMatchers') do |spinner|
58
+ spinner.banner('initializing...')
59
+ load_application
60
+ @app_action_controller_descendants_names = get_app_action_controller_descendants_names
61
+ end
62
+ puts "\n"
63
+ generate_action_controller_controller_matchmakers(generator_options, @app_action_controller_descendants_names, working_generated_code_line_length)
64
+ end
65
+
66
+
67
+ private
68
+
69
+ def generate_action_controller_controller_matchmakers(generator_options, app_action_controller_descendants_names, code_line_length)
70
+ if app_action_controller_descendants_names.present?
71
+ selected_app_action_controller_descendants_names = filter_app_action_controller_descendants_names(app_action_controller_descendants_names, generator_options)
72
+ selected_app_action_controller_descendants_names.each do |app_controller_name|
73
+ save_generate(app_controller_name) do
74
+ @action_controller_controller_sm_model = ::ShouldaMatchmakers::Controller::ActionController::ActionControllerControllerSmModel.new(app_controller_name, app_action_controller_descendants_names, code_line_length)
75
+ template_filename = File.expand_path('../../templates/controller/action_controller/controller_spec_template.haml', File.dirname(__FILE__))
76
+ template = File.read(template_filename)
77
+ create_file "#{ ShouldaMatchmakers.configuration.action_controller_controller_tests_path }/#{ app_controller_name.underscore }_spec.rb",
78
+ Haml::Engine.new(template, filename: template_filename, format: :html5).to_html(binding)
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+
85
+ end
86
+ end
87
+
@@ -0,0 +1,92 @@
1
+ module ShouldaMatchmakers
2
+ module Generator
3
+ module ActionController
4
+ module ControllerMatcherGeneratorHelper
5
+
6
+ def load_application
7
+ Rails.application.try(:eager_load!)
8
+ end
9
+
10
+ def get_app_action_controller_descendants_names
11
+ if defined?(::ActionController::Base)
12
+ ::ActionController::Base.descendants.map(&:name)
13
+ else
14
+ []
15
+ end
16
+ end
17
+
18
+ def save_generate(controller_name)
19
+ begin
20
+ yield
21
+ rescue => e
22
+ puts "Cannot create controller spec for #{ controller_name }. Reason #{ e.message }"
23
+ end
24
+ end
25
+
26
+ def filter_app_action_controller_descendants_names(app_action_controller_descendants_names, generator_options)
27
+ generator_include_option_action_controller_controller_names = generator_options.fetch('include')
28
+ generator_exclude_option_action_controller_controller_names = generator_options.fetch('exclude')
29
+ generator_include_and_config_options_action_controller_controller_names = generator_options.fetch('include_and_config')
30
+ generator_exclude_and_config_options_action_controller_controller_names = generator_options.fetch('exclude_and_config')
31
+ if generator_include_option_action_controller_controller_names.present?
32
+ filter_action_controller_controller_names_with_include_option(app_action_controller_descendants_names, generator_include_option_action_controller_controller_names)
33
+ elsif generator_exclude_option_action_controller_controller_names.present?
34
+ filter_action_controller_controller_names_with_exclude_option(app_action_controller_descendants_names, generator_exclude_option_action_controller_controller_names)
35
+ elsif generator_include_and_config_options_action_controller_controller_names.present?
36
+ filter_action_controller_controller_names_with_generator_include_and_config_options(app_action_controller_descendants_names, generator_include_and_config_options_action_controller_controller_names)
37
+ elsif generator_exclude_and_config_options_action_controller_controller_names.present?
38
+ filter_action_controller_controller_names_with_generator_exclude_and_config_options(app_action_controller_descendants_names, generator_exclude_and_config_options_action_controller_controller_names)
39
+ else
40
+ selected_app_action_controller_descendants_names = filter_action_controller_controller_names_with_config_options(app_action_controller_descendants_names)
41
+ if selected_app_action_controller_descendants_names.present?
42
+ selected_app_action_controller_descendants_names
43
+ else
44
+ app_action_controller_descendants_names.uniq.sort
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ def filter_action_controller_controller_names_with_include_option(app_action_controller_descendants_names, include_option_action_controller_controller_names)
51
+ app_action_controller_descendants_names.map.select { |app_controller_name| include_option_action_controller_controller_names.include? app_controller_name }.uniq.sort
52
+ end
53
+
54
+ def filter_action_controller_controller_names_with_exclude_option(app_action_controller_descendants_names, exclude_option_action_controller_controller_names)
55
+ app_action_controller_descendants_names.map.reject { |app_controller_name| exclude_option_action_controller_controller_names.include? app_controller_name }.uniq.sort
56
+ end
57
+
58
+ def filter_action_controller_controller_names_with_generator_include_and_config_options(app_action_controller_descendants_names, generator_include_and_config_options_action_controller_controller_names)
59
+ selected_app_action_controller_descendants_names = filter_action_controller_controller_names_with_config_options(app_action_controller_descendants_names)
60
+ if selected_app_action_controller_descendants_names.present?
61
+ selected_app_action_controller_descendants_names +
62
+ filter_action_controller_controller_names_with_include_option(app_action_controller_descendants_names, generator_include_and_config_options_action_controller_controller_names).uniq.sort
63
+ else
64
+ filter_action_controller_controller_names_with_include_option(app_action_controller_descendants_names, generator_include_and_config_options_action_controller_controller_names).uniq.sort
65
+ end
66
+ end
67
+
68
+ def filter_action_controller_controller_names_with_generator_exclude_and_config_options(app_action_controller_descendants_names, generator_exclude_and_config_options_action_controller_controller_names)
69
+ selected_action_controller_controller_names = filter_action_controller_controller_names_with_config_options(app_action_controller_descendants_names)
70
+ if selected_action_controller_controller_names.present?
71
+ filter_action_controller_controller_names_with_exclude_option(selected_action_controller_controller_names, generator_exclude_and_config_options_action_controller_controller_names).uniq.sort
72
+ else
73
+ filter_action_controller_controller_names_with_exclude_option(app_action_controller_descendants_names, generator_exclude_and_config_options_action_controller_controller_names).uniq.sort
74
+ end
75
+ end
76
+
77
+ def filter_action_controller_controller_names_with_config_options(app_action_controller_descendants_names)
78
+ config_included_option_action_controller_controller_names = ShouldaMatchmakers.configuration.action_controller_controller_names_included
79
+ config_excluded_option_action_controller_controller_names = ShouldaMatchmakers.configuration.action_controller_controller_names_excluded
80
+ if config_included_option_action_controller_controller_names.present?
81
+ filter_action_controller_controller_names_with_include_option(app_action_controller_descendants_names, config_included_option_action_controller_controller_names).uniq.sort
82
+ elsif config_excluded_option_action_controller_controller_names.present?
83
+ filter_action_controller_controller_names_with_exclude_option(app_action_controller_descendants_names, config_excluded_option_action_controller_controller_names).uniq.sort
84
+ else
85
+ []
86
+ end
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end