ridecharge-rubocop 0.0.1

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.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGELOG.md +0 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +35 -0
  9. data/Rakefile +22 -0
  10. data/bin/ridecharge-rubocop +49 -0
  11. data/config/0default.yml +8 -0
  12. data/config/fleet-magic-todo.yml +380 -0
  13. data/config/rc-todo.yml +190 -0
  14. data/config/ridecharge-rubocop_todo.yml +73 -0
  15. data/config/rubocop/default.yml +308 -0
  16. data/config/rubocop/disabled.yml +9 -0
  17. data/config/rubocop/enabled.yml +648 -0
  18. data/config/standard-todo.yml +24 -0
  19. data/config/tabs.yml +15 -0
  20. data/config/vehicle-todo.yml +195 -0
  21. data/lib/ridecharge/rubocop.rb +2 -0
  22. data/lib/ridecharge/rubocop/version.rb +5 -0
  23. data/lib/rubocop/config_loader_monkeypatch.rb +117 -0
  24. data/lib/rubocop/ridecharge.rb +1 -0
  25. data/ridecharge-rubocop.gemspec +25 -0
  26. data/spec/isolated_environment_spec.rb +24 -0
  27. data/spec/project_spec.rb +118 -0
  28. data/spec/rubocop/cli_spec.rb +1385 -0
  29. data/spec/rubocop/config_loader_spec.rb +328 -0
  30. data/spec/rubocop/config_spec.rb +179 -0
  31. data/spec/rubocop/config_store_spec.rb +53 -0
  32. data/spec/rubocop/cop/commissioner_spec.rb +83 -0
  33. data/spec/rubocop/cop/cop_spec.rb +114 -0
  34. data/spec/rubocop/cop/corrector_spec.rb +59 -0
  35. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
  36. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
  37. data/spec/rubocop/cop/lint/assignment_in_condition_spec.rb +107 -0
  38. data/spec/rubocop/cop/lint/block_alignment_spec.rb +411 -0
  39. data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
  40. data/spec/rubocop/cop/lint/debugger_spec.rb +39 -0
  41. data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
  42. data/spec/rubocop/cop/lint/empty_ensure_spec.rb +27 -0
  43. data/spec/rubocop/cop/lint/end_alignment_spec.rb +136 -0
  44. data/spec/rubocop/cop/lint/end_in_method_spec.rb +29 -0
  45. data/spec/rubocop/cop/lint/ensure_return_spec.rb +39 -0
  46. data/spec/rubocop/cop/lint/eval_spec.rb +35 -0
  47. data/spec/rubocop/cop/lint/handle_exceptions_spec.rb +30 -0
  48. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
  49. data/spec/rubocop/cop/lint/literal_in_condition_spec.rb +63 -0
  50. data/spec/rubocop/cop/lint/loop_spec.rb +27 -0
  51. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +57 -0
  52. data/spec/rubocop/cop/lint/require_parentheses_spec.rb +82 -0
  53. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +131 -0
  54. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +237 -0
  55. data/spec/rubocop/cop/lint/syntax_spec.rb +34 -0
  56. data/spec/rubocop/cop/lint/unreachable_code_spec.rb +63 -0
  57. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +1570 -0
  58. data/spec/rubocop/cop/lint/useless_comparison_spec.rb +30 -0
  59. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
  60. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +149 -0
  61. data/spec/rubocop/cop/lint/void_spec.rb +57 -0
  62. data/spec/rubocop/cop/offence_spec.rb +133 -0
  63. data/spec/rubocop/cop/rails/default_scope_spec.rb +37 -0
  64. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +13 -0
  65. data/spec/rubocop/cop/rails/output_spec.rb +41 -0
  66. data/spec/rubocop/cop/rails/read_attribute_spec.rb +13 -0
  67. data/spec/rubocop/cop/rails/validation_spec.rb +21 -0
  68. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +361 -0
  69. data/spec/rubocop/cop/style/accessor_method_name_spec.rb +81 -0
  70. data/spec/rubocop/cop/style/alias_spec.rb +59 -0
  71. data/spec/rubocop/cop/style/align_array_spec.rb +75 -0
  72. data/spec/rubocop/cop/style/align_hash_spec.rb +310 -0
  73. data/spec/rubocop/cop/style/align_parameters_spec.rb +222 -0
  74. data/spec/rubocop/cop/style/and_or_spec.rb +57 -0
  75. data/spec/rubocop/cop/style/ascii_comments_spec.rb +22 -0
  76. data/spec/rubocop/cop/style/ascii_identifiers_spec.rb +36 -0
  77. data/spec/rubocop/cop/style/attr_spec.rb +19 -0
  78. data/spec/rubocop/cop/style/begin_block_spec.rb +13 -0
  79. data/spec/rubocop/cop/style/block_comments_spec.rb +21 -0
  80. data/spec/rubocop/cop/style/block_nesting_spec.rb +156 -0
  81. data/spec/rubocop/cop/style/blocks_spec.rb +99 -0
  82. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +284 -0
  83. data/spec/rubocop/cop/style/case_equality_spec.rb +12 -0
  84. data/spec/rubocop/cop/style/case_indentation_spec.rb +289 -0
  85. data/spec/rubocop/cop/style/character_literal_spec.rb +37 -0
  86. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +40 -0
  87. data/spec/rubocop/cop/style/class_length_spec.rb +131 -0
  88. data/spec/rubocop/cop/style/class_methods_spec.rb +45 -0
  89. data/spec/rubocop/cop/style/class_vars_spec.rb +19 -0
  90. data/spec/rubocop/cop/style/collection_methods_spec.rb +48 -0
  91. data/spec/rubocop/cop/style/colon_method_call_spec.rb +60 -0
  92. data/spec/rubocop/cop/style/comment_annotation_spec.rb +86 -0
  93. data/spec/rubocop/cop/style/constant_name_spec.rb +65 -0
  94. data/spec/rubocop/cop/style/cyclomatic_complexity_spec.rb +204 -0
  95. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +39 -0
  96. data/spec/rubocop/cop/style/documentation_spec.rb +123 -0
  97. data/spec/rubocop/cop/style/dot_position_spec.rb +94 -0
  98. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +127 -0
  99. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +56 -0
  100. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +131 -0
  101. data/spec/rubocop/cop/style/empty_lines_spec.rb +40 -0
  102. data/spec/rubocop/cop/style/empty_literal_spec.rb +100 -0
  103. data/spec/rubocop/cop/style/encoding_spec.rb +56 -0
  104. data/spec/rubocop/cop/style/end_block_spec.rb +13 -0
  105. data/spec/rubocop/cop/style/end_of_line_spec.rb +47 -0
  106. data/spec/rubocop/cop/style/even_odd_spec.rb +75 -0
  107. data/spec/rubocop/cop/style/favor_join_spec.rb +31 -0
  108. data/spec/rubocop/cop/style/favor_sprintf_spec.rb +47 -0
  109. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +76 -0
  110. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +41 -0
  111. data/spec/rubocop/cop/style/final_newline_spec.rb +30 -0
  112. data/spec/rubocop/cop/style/flip_flop_spec.rb +23 -0
  113. data/spec/rubocop/cop/style/for_spec.rb +105 -0
  114. data/spec/rubocop/cop/style/global_vars_spec.rb +34 -0
  115. data/spec/rubocop/cop/style/hash_methods_spec.rb +45 -0
  116. data/spec/rubocop/cop/style/hash_syntax_spec.rb +131 -0
  117. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +128 -0
  118. data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +19 -0
  119. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
  120. data/spec/rubocop/cop/style/indentation_width_spec.rb +470 -0
  121. data/spec/rubocop/cop/style/lambda_call_spec.rb +65 -0
  122. data/spec/rubocop/cop/style/lambda_spec.rb +41 -0
  123. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +64 -0
  124. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +34 -0
  125. data/spec/rubocop/cop/style/line_length_spec.rb +20 -0
  126. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +59 -0
  127. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +60 -0
  128. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +106 -0
  129. data/spec/rubocop/cop/style/method_length_spec.rb +147 -0
  130. data/spec/rubocop/cop/style/method_name_spec.rb +125 -0
  131. data/spec/rubocop/cop/style/module_function_spec.rb +24 -0
  132. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +78 -0
  133. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +107 -0
  134. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
  135. data/spec/rubocop/cop/style/nested_ternary_operator_spec.rb +21 -0
  136. data/spec/rubocop/cop/style/nil_comparison_spec.rb +30 -0
  137. data/spec/rubocop/cop/style/not_spec.rb +22 -0
  138. data/spec/rubocop/cop/style/numeric_literals_spec.rb +64 -0
  139. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +13 -0
  140. data/spec/rubocop/cop/style/op_method_spec.rb +74 -0
  141. data/spec/rubocop/cop/style/parameter_lists_spec.rb +44 -0
  142. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +122 -0
  143. data/spec/rubocop/cop/style/perl_backrefs_spec.rb +17 -0
  144. data/spec/rubocop/cop/style/predicate_name_spec.rb +25 -0
  145. data/spec/rubocop/cop/style/proc_spec.rb +27 -0
  146. data/spec/rubocop/cop/style/raise_args_spec.rb +82 -0
  147. data/spec/rubocop/cop/style/redundant_begin_spec.rb +57 -0
  148. data/spec/rubocop/cop/style/redundant_exception_spec.rb +27 -0
  149. data/spec/rubocop/cop/style/redundant_return_spec.rb +171 -0
  150. data/spec/rubocop/cop/style/redundant_self_spec.rb +142 -0
  151. data/spec/rubocop/cop/style/regexp_literal_spec.rb +83 -0
  152. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +116 -0
  153. data/spec/rubocop/cop/style/semicolon_spec.rb +100 -0
  154. data/spec/rubocop/cop/style/signal_exception_spec.rb +266 -0
  155. data/spec/rubocop/cop/style/single_line_block_params_spec.rb +68 -0
  156. data/spec/rubocop/cop/style/single_line_methods_spec.rb +52 -0
  157. data/spec/rubocop/cop/style/space_after_colon_spec.rb +38 -0
  158. data/spec/rubocop/cop/style/space_after_comma_spec.rb +30 -0
  159. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +84 -0
  160. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +70 -0
  161. data/spec/rubocop/cop/style/space_after_not_spec.rb +22 -0
  162. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +23 -0
  163. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +283 -0
  164. data/spec/rubocop/cop/style/space_around_equals_in_parameter_default_spec.rb +33 -0
  165. data/spec/rubocop/cop/style/space_around_operators_spec.rb +325 -0
  166. data/spec/rubocop/cop/style/space_before_modifier_keyword_spec.rb +70 -0
  167. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +52 -0
  168. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +138 -0
  169. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +34 -0
  170. data/spec/rubocop/cop/style/special_global_vars_spec.rb +56 -0
  171. data/spec/rubocop/cop/style/string_literals_spec.rb +212 -0
  172. data/spec/rubocop/cop/style/symbol_array_spec.rb +37 -0
  173. data/spec/rubocop/cop/style/tab_spec.rb +17 -0
  174. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +43 -0
  175. data/spec/rubocop/cop/style/trailing_comma_spec.rb +230 -0
  176. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +30 -0
  177. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +415 -0
  178. data/spec/rubocop/cop/style/unless_else_spec.rb +25 -0
  179. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +47 -0
  180. data/spec/rubocop/cop/style/variable_name_spec.rb +107 -0
  181. data/spec/rubocop/cop/style/when_then_spec.rb +41 -0
  182. data/spec/rubocop/cop/style/while_until_do_spec.rb +53 -0
  183. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
  184. data/spec/rubocop/cop/style/word_array_spec.rb +97 -0
  185. data/spec/rubocop/cop/team_spec.rb +156 -0
  186. data/spec/rubocop/cop/util_spec.rb +49 -0
  187. data/spec/rubocop/cop/variable_inspector/assignment_spec.rb +213 -0
  188. data/spec/rubocop/cop/variable_inspector/locatable_spec.rb +734 -0
  189. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +184 -0
  190. data/spec/rubocop/cop/variable_inspector/variable_spec.rb +73 -0
  191. data/spec/rubocop/cop/variable_inspector/variable_table_spec.rb +269 -0
  192. data/spec/rubocop/cop/variable_inspector_spec.rb +29 -0
  193. data/spec/rubocop/file_inspector_spec.rb +78 -0
  194. data/spec/rubocop/formatter/base_formatter_spec.rb +191 -0
  195. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +114 -0
  196. data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
  197. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +50 -0
  198. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +62 -0
  199. data/spec/rubocop/formatter/file_list_formatter_spec.rb +33 -0
  200. data/spec/rubocop/formatter/formatter_set_spec.rb +132 -0
  201. data/spec/rubocop/formatter/json_formatter_spec.rb +148 -0
  202. data/spec/rubocop/formatter/offence_count_formatter_spec.rb +52 -0
  203. data/spec/rubocop/formatter/progress_formatter_spec.rb +182 -0
  204. data/spec/rubocop/formatter/simple_text_formatter_spec.rb +123 -0
  205. data/spec/rubocop/options_spec.rb +145 -0
  206. data/spec/rubocop/path_util_spec.rb +42 -0
  207. data/spec/rubocop/processed_source_spec.rb +114 -0
  208. data/spec/rubocop/source_parser_spec.rb +139 -0
  209. data/spec/rubocop/target_finder_spec.rb +180 -0
  210. data/spec/rubocop/token_spec.rb +25 -0
  211. data/spec/spec_helper.rb +136 -0
  212. data/spec/support/ast_helper.rb +15 -0
  213. data/spec/support/file_helper.rb +21 -0
  214. data/spec/support/isolated_environment.rb +34 -0
  215. data/spec/support/mri_syntax_checker.rb +73 -0
  216. data/spec/support/shared_context.rb +22 -0
  217. data/spec/support/shared_examples.rb +33 -0
  218. data/spec/support/statement_modifier_helper.rb +41 -0
  219. metadata +511 -0
@@ -0,0 +1,184 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::VariableInspector::Scope do
6
+ include ASTHelper
7
+ include AST::Sexp
8
+
9
+ describe '.new' do
10
+ context 'when non scope node is passed' do
11
+ it 'raises error' do
12
+ node = s(:lvasgn)
13
+ expect { described_class.new(node) }.to raise_error(ArgumentError)
14
+ end
15
+ end
16
+
17
+ context 'when begin node is passed' do
18
+ it 'accepts that as pseudo scope for top level scope' do
19
+ node = s(:begin)
20
+ expect { described_class.new(node) }.not_to raise_error
21
+ end
22
+ end
23
+ end
24
+
25
+ let(:ast) do
26
+ ast = Rubocop::SourceParser.parse(source).ast
27
+ Rubocop::Cop::VariableInspector.wrap_with_top_level_node(ast)
28
+ end
29
+
30
+ let(:scope_node_type) { :def }
31
+
32
+ let(:scope_node) do
33
+ found_node = scan_node(ast, include_origin_node: true) do |node|
34
+ break node if node.type == scope_node_type
35
+ end
36
+ fail 'No scope node found!' unless found_node
37
+ found_node
38
+ end
39
+
40
+ subject(:scope) { described_class.new(scope_node) }
41
+
42
+ describe '#ancestors_of_node' do
43
+ let(:source) do
44
+ <<-END
45
+ puts 1
46
+
47
+ class SomeClass
48
+ def some_method
49
+ foo = 1
50
+
51
+ if foo > 0
52
+ while foo < 10
53
+ this_is_target
54
+ foo += 1
55
+ end
56
+ else
57
+ do_something
58
+ end
59
+ end
60
+ end
61
+ END
62
+ end
63
+
64
+ let(:target_node) do
65
+ found_node = scan_node(ast) do |node|
66
+ next unless node.type == :send
67
+ _receiver_node, method_name = *node
68
+ break node if method_name == :this_is_target
69
+ end
70
+ fail 'No target node found!' unless found_node
71
+ found_node
72
+ end
73
+
74
+ it 'returns nodes in between the scope node and the passed node' do
75
+ ancestor_nodes = scope.ancestors_of_node(target_node)
76
+ ancestor_types = ancestor_nodes.map(&:type)
77
+ expect(ancestor_types).to eq([:begin, :if, :while, :begin])
78
+ end
79
+ end
80
+
81
+ describe '#body_node' do
82
+ shared_examples 'returns the body node' do
83
+ it 'returns the body node' do
84
+ expect(scope.body_node.children[1]).to eq(:this_is_target)
85
+ end
86
+ end
87
+
88
+ context 'when the scope is instance method' do
89
+ let(:source) do
90
+ <<-END
91
+ def some_method
92
+ this_is_target
93
+ end
94
+ END
95
+ end
96
+
97
+ let(:scope_node_type) { :def }
98
+
99
+ include_examples 'returns the body node'
100
+ end
101
+
102
+ context 'when the scope is singleton method' do
103
+ let(:source) do
104
+ <<-END
105
+ def self.some_method
106
+ this_is_target
107
+ end
108
+ END
109
+ end
110
+
111
+ let(:scope_node_type) { :defs }
112
+
113
+ include_examples 'returns the body node'
114
+ end
115
+
116
+ context 'when the scope is module' do
117
+ let(:source) do
118
+ <<-END
119
+ module SomeModule
120
+ this_is_target
121
+ end
122
+ END
123
+ end
124
+
125
+ let(:scope_node_type) { :module }
126
+
127
+ include_examples 'returns the body node'
128
+ end
129
+
130
+ context 'when the scope is class' do
131
+ let(:source) do
132
+ <<-END
133
+ class SomeClass
134
+ this_is_target
135
+ end
136
+ END
137
+ end
138
+
139
+ let(:scope_node_type) { :class }
140
+
141
+ include_examples 'returns the body node'
142
+ end
143
+
144
+ context 'when the scope is singleton class' do
145
+ let(:source) do
146
+ <<-END
147
+ class << self
148
+ this_is_target
149
+ end
150
+ END
151
+ end
152
+
153
+ let(:scope_node_type) { :sclass }
154
+
155
+ include_examples 'returns the body node'
156
+ end
157
+
158
+ context 'when the scope is block' do
159
+ let(:source) do
160
+ <<-END
161
+ 1.times do
162
+ this_is_target
163
+ end
164
+ END
165
+ end
166
+
167
+ let(:scope_node_type) { :block }
168
+
169
+ include_examples 'returns the body node'
170
+ end
171
+
172
+ context 'when the scope is top level' do
173
+ let(:source) do
174
+ <<-END
175
+ this_is_target
176
+ END
177
+ end
178
+
179
+ let(:scope_node_type) { :top_level }
180
+
181
+ include_examples 'returns the body node'
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::VariableInspector::Variable do
6
+ include AST::Sexp
7
+
8
+ describe '.new' do
9
+ context 'when non variable declaration node is passed' do
10
+ it 'raises error' do
11
+ name = :foo
12
+ declaration_node = s(:def)
13
+ scope = Rubocop::Cop::VariableInspector::Scope.new(s(:class))
14
+ expect { described_class.new(name, declaration_node, scope) }
15
+ .to raise_error(ArgumentError)
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '#referenced?' do
21
+ let(:name) { :foo }
22
+ let(:declaration_node) { s(:arg, name) }
23
+ let(:scope) { double('scope') }
24
+ let(:variable) { described_class.new(name, declaration_node, scope) }
25
+
26
+ subject { variable.referenced? }
27
+
28
+ context 'when the variable is not yet assigned' do
29
+ it { should be_false }
30
+ end
31
+
32
+ context 'when the variable has an assignment' do
33
+ before do
34
+ variable.assign(s(:lvasgn, :foo))
35
+ end
36
+
37
+ context 'and the assignment is not yet referenced' do
38
+ it { should be_false }
39
+ end
40
+
41
+ context 'and the assignment is referenced' do
42
+ before do
43
+ variable.assignments.first.reference!
44
+ end
45
+
46
+ it { should be_true }
47
+ end
48
+ end
49
+
50
+ context 'when the variable has multiple assignments' do
51
+ before do
52
+ variable.assign(s(:lvasgn, :foo))
53
+ variable.assign(s(:lvasgn, :foo))
54
+ end
55
+
56
+ context 'and only once assignment is referenced' do
57
+ before do
58
+ variable.assignments[1].reference!
59
+ end
60
+
61
+ it { should be_true }
62
+ end
63
+
64
+ context 'and all assignments are referenced' do
65
+ before do
66
+ variable.assignments.each { |a| a.reference! }
67
+ end
68
+
69
+ it { should be_true }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,269 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::VariableInspector::VariableTable do
6
+ include AST::Sexp
7
+
8
+ subject(:variable_table) { described_class.new }
9
+
10
+ describe '#push_scope' do
11
+ it 'returns pushed scope object' do
12
+ node = s(:def)
13
+ scope = variable_table.push_scope(node)
14
+ expect(scope).to equal(variable_table.current_scope)
15
+ expect(scope.node).to equal(node)
16
+ end
17
+ end
18
+
19
+ describe '#pop_scope' do
20
+ before do
21
+ node = s(:def)
22
+ variable_table.push_scope(node)
23
+ end
24
+
25
+ it 'returns popped scope object' do
26
+ last_scope = variable_table.current_scope
27
+ popped_scope = variable_table.pop_scope
28
+ expect(popped_scope).to equal(last_scope)
29
+ end
30
+ end
31
+
32
+ describe '#current_scope_level' do
33
+ before do
34
+ variable_table.push_scope(s(:def))
35
+ end
36
+
37
+ it 'increases by pushing scope' do
38
+ last_scope_level = variable_table.current_scope_level
39
+ variable_table.push_scope(s(:def))
40
+ expect(variable_table.current_scope_level)
41
+ .to eq(last_scope_level + 1)
42
+ end
43
+
44
+ it 'decreases by popping scope' do
45
+ last_scope_level = variable_table.current_scope_level
46
+ variable_table.pop_scope
47
+ expect(variable_table.current_scope_level)
48
+ .to eq(last_scope_level - 1)
49
+ end
50
+ end
51
+
52
+ describe '#declare_variable' do
53
+ before do
54
+ 2.times do
55
+ node = s(:def)
56
+ variable_table.push_scope(node)
57
+ end
58
+ end
59
+
60
+ it 'adds variable to current scope with its name as key' do
61
+ node = s(:lvasgn, :foo)
62
+ variable_table.declare_variable(:foo, node)
63
+ expect(variable_table.current_scope.variables)
64
+ .to have_key(:foo)
65
+ expect(variable_table.scope_stack[-2].variables)
66
+ .to be_empty
67
+ variable = variable_table.current_scope.variables[:foo]
68
+ expect(variable.declaration_node).to equal(node)
69
+ end
70
+
71
+ it 'returns the added variable' do
72
+ node = s(:lvasgn, :foo)
73
+ variable = variable_table.declare_variable(:foo, node)
74
+ expect(variable.declaration_node).to equal(node)
75
+ end
76
+ end
77
+
78
+ describe '#find_variable' do
79
+ before do
80
+ variable_table.push_scope(s(:class))
81
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
82
+
83
+ variable_table.push_scope(s(:def))
84
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
85
+ end
86
+
87
+ context 'when current scope is block' do
88
+ before do
89
+ variable_table.push_scope(s(:block))
90
+ end
91
+
92
+ context 'when a variable with the target name exists ' \
93
+ 'in current scope' do
94
+ before do
95
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
96
+ end
97
+
98
+ context 'and does not exist in outer scope' do
99
+ it 'returns the current scope variable' do
100
+ found_variable = variable_table.find_variable(:foo)
101
+ expect(found_variable.name).to eq(:foo)
102
+ end
103
+ end
104
+
105
+ context 'and also exists in outer scope' do
106
+ before do
107
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
108
+ end
109
+
110
+ it 'returns the current scope variable' do
111
+ found_variable = variable_table.find_variable(:bar)
112
+ expect(found_variable.name).to equal(:bar)
113
+ expect(variable_table.current_scope.variables)
114
+ .to have_value(found_variable)
115
+ expect(variable_table.scope_stack[-2].variables)
116
+ .not_to have_value(found_variable)
117
+ end
118
+ end
119
+ end
120
+
121
+ context 'when a variable with the target name does not exist ' \
122
+ 'in current scope' do
123
+ context 'but exists in the direct outer scope' do
124
+ it 'returns the direct outer scope variable' do
125
+ found_variable = variable_table.find_variable(:bar)
126
+ expect(found_variable.name).to equal(:bar)
127
+ end
128
+ end
129
+
130
+ context 'but exists in a indirect outer scope' do
131
+ context 'when the direct outer scope is block' do
132
+ before do
133
+ variable_table.pop_scope
134
+ variable_table.pop_scope
135
+
136
+ variable_table.push_scope(s(:block))
137
+ variable_table.push_scope(s(:block))
138
+ end
139
+
140
+ it 'returns the indirect outer scope variable' do
141
+ found_variable = variable_table.find_variable(:baz)
142
+ expect(found_variable.name).to equal(:baz)
143
+ end
144
+ end
145
+
146
+ context 'when the direct outer scope is not block' do
147
+ it 'returns nil' do
148
+ found_variable = variable_table.find_variable(:baz)
149
+ expect(found_variable).to be_nil
150
+ end
151
+ end
152
+ end
153
+
154
+ context 'and does not exist in all outer scopes' do
155
+ it 'returns nil' do
156
+ found_variable = variable_table.find_variable(:non)
157
+ expect(found_variable).to be_nil
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'when current scope is not block' do
164
+ before do
165
+ variable_table.push_scope(s(:def))
166
+ end
167
+
168
+ context 'when a variable with the target name exists ' \
169
+ 'in current scope' do
170
+ before do
171
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
172
+ end
173
+
174
+ context 'and does not exist in outer scope' do
175
+ it 'returns the current scope variable' do
176
+ found_variable = variable_table.find_variable(:foo)
177
+ expect(found_variable.name).to eq(:foo)
178
+ end
179
+ end
180
+
181
+ context 'and also exists in outer scope' do
182
+ it 'returns the current scope variable' do
183
+ found_variable = variable_table.find_variable(:foo)
184
+ expect(found_variable.name).to equal(:foo)
185
+ expect(variable_table.current_scope.variables)
186
+ .to have_value(found_variable)
187
+ expect(variable_table.scope_stack[-2].variables)
188
+ .not_to have_value(found_variable)
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'when a variable with the target name does not exist ' \
194
+ 'in current scope' do
195
+ context 'but exists in the direct outer scope' do
196
+ it 'returns nil' do
197
+ found_variable = variable_table.find_variable(:bar)
198
+ expect(found_variable).to be_nil
199
+ end
200
+ end
201
+
202
+ context 'and does not exist in all outer scopes' do
203
+ it 'returns nil' do
204
+ found_variable = variable_table.find_variable(:non)
205
+ expect(found_variable).to be_nil
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ describe '#accessible_variables' do
213
+ let(:accessible_variable_names) do
214
+ variable_table.accessible_variables.map(&:name)
215
+ end
216
+
217
+ before do
218
+ variable_table.push_scope(s(:class))
219
+ end
220
+
221
+ context 'when there are no variables' do
222
+ it 'returns empty array' do
223
+ expect(variable_table.accessible_variables).to be_empty
224
+ end
225
+ end
226
+
227
+ context 'when the current scope has some variables' do
228
+ before do
229
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
230
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
231
+ end
232
+
233
+ it 'returns all the variables' do
234
+ expect(accessible_variable_names).to match_array([:foo, :bar])
235
+ end
236
+ end
237
+
238
+ context 'when the direct outer scope has some variables' do
239
+ before do
240
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
241
+ end
242
+
243
+ context 'and the current scope is block' do
244
+ before do
245
+ variable_table.push_scope(s(:block))
246
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
247
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
248
+ end
249
+
250
+ it 'returns the current and direct outer scope variables' do
251
+ expect(accessible_variable_names)
252
+ .to match_array([:foo, :bar, :baz])
253
+ end
254
+ end
255
+
256
+ context 'and the current scope is not block' do
257
+ before do
258
+ variable_table.push_scope(s(:def))
259
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
260
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
261
+ end
262
+
263
+ it 'returns only the current scope variables' do
264
+ expect(accessible_variable_names).to match_array([:bar, :baz])
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end