rubocop 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (279) hide show
  1. data/CHANGELOG.md +40 -0
  2. data/README.md +49 -8
  3. data/config/default.yml +40 -0
  4. data/config/enabled.yml +37 -9
  5. data/lib/rubocop.rb +24 -10
  6. data/lib/rubocop/cli.rb +41 -106
  7. data/lib/rubocop/config.rb +3 -2
  8. data/lib/rubocop/cop/commissioner.rb +15 -5
  9. data/lib/rubocop/cop/cop.rb +47 -32
  10. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  11. data/lib/rubocop/cop/lint/block_alignment.rb +30 -9
  12. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  13. data/lib/rubocop/cop/lint/end_alignment.rb +4 -4
  14. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  15. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  16. data/lib/rubocop/cop/lint/eval.rb +1 -3
  17. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  18. data/lib/rubocop/cop/lint/literal_in_condition.rb +6 -4
  19. data/lib/rubocop/cop/lint/loop.rb +1 -1
  20. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  21. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  22. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -8
  23. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  24. data/lib/rubocop/cop/lint/useless_assignment.rb +57 -60
  25. data/lib/rubocop/cop/lint/useless_comparison.rb +1 -1
  26. data/lib/rubocop/cop/lint/useless_setter_call.rb +85 -0
  27. data/lib/rubocop/cop/lint/void.rb +6 -8
  28. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -1
  29. data/lib/rubocop/cop/rails/read_attribute.rb +1 -1
  30. data/lib/rubocop/cop/rails/validation.rb +1 -1
  31. data/lib/rubocop/cop/style/access_control.rb +4 -6
  32. data/lib/rubocop/cop/style/alias.rb +1 -3
  33. data/lib/rubocop/cop/style/align_array.rb +47 -0
  34. data/lib/rubocop/cop/style/align_hash.rb +145 -0
  35. data/lib/rubocop/cop/style/align_parameters.rb +9 -3
  36. data/lib/rubocop/cop/style/and_or.rb +3 -4
  37. data/lib/rubocop/cop/style/ascii_comments.rb +1 -3
  38. data/lib/rubocop/cop/style/ascii_identifiers.rb +1 -1
  39. data/lib/rubocop/cop/style/attr.rb +1 -4
  40. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  41. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  42. data/lib/rubocop/cop/style/block_nesting.rb +2 -2
  43. data/lib/rubocop/cop/style/blocks.rb +14 -2
  44. data/lib/rubocop/cop/style/case_equality.rb +1 -3
  45. data/lib/rubocop/cop/style/case_indentation.rb +1 -1
  46. data/lib/rubocop/cop/style/character_literal.rb +1 -2
  47. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +1 -1
  48. data/lib/rubocop/cop/style/class_methods.rb +1 -3
  49. data/lib/rubocop/cop/style/{avoid_class_vars.rb → class_vars.rb} +6 -2
  50. data/lib/rubocop/cop/style/collection_methods.rb +7 -9
  51. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  52. data/lib/rubocop/cop/style/comment_annotation.rb +6 -6
  53. data/lib/rubocop/cop/style/constant_name.rb +1 -3
  54. data/lib/rubocop/cop/style/def_parentheses.rb +4 -12
  55. data/lib/rubocop/cop/style/documentation.rb +2 -2
  56. data/lib/rubocop/cop/style/dot_position.rb +2 -4
  57. data/lib/rubocop/cop/style/empty_line_between_defs.rb +21 -6
  58. data/lib/rubocop/cop/style/empty_lines.rb +1 -1
  59. data/lib/rubocop/cop/style/empty_literal.rb +3 -12
  60. data/lib/rubocop/cop/style/encoding.rb +6 -6
  61. data/lib/rubocop/cop/style/end_block.rb +1 -1
  62. data/lib/rubocop/cop/style/end_of_line.rb +5 -5
  63. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  64. data/lib/rubocop/cop/style/favor_join.rb +1 -3
  65. data/lib/rubocop/cop/style/favor_modifier.rb +7 -3
  66. data/lib/rubocop/cop/style/favor_sprintf.rb +1 -1
  67. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -1
  68. data/lib/rubocop/cop/style/final_newline.rb +23 -0
  69. data/lib/rubocop/cop/style/{avoid_for.rb → for.rb} +2 -2
  70. data/lib/rubocop/cop/style/{avoid_global_vars.rb → global_vars.rb} +19 -6
  71. data/lib/rubocop/cop/style/hash_methods.rb +3 -5
  72. data/lib/rubocop/cop/style/hash_syntax.rb +4 -4
  73. data/lib/rubocop/cop/style/if_then_else.rb +1 -1
  74. data/lib/rubocop/cop/style/indentation_width.rb +4 -4
  75. data/lib/rubocop/cop/style/lambda.rb +2 -2
  76. data/lib/rubocop/cop/style/leading_comment_space.rb +1 -1
  77. data/lib/rubocop/cop/style/line_length.rb +7 -8
  78. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +1 -1
  79. data/lib/rubocop/cop/style/method_call_parentheses.rb +1 -4
  80. data/lib/rubocop/cop/style/method_length.rb +4 -4
  81. data/lib/rubocop/cop/style/module_function.rb +1 -3
  82. data/lib/rubocop/cop/style/multiline_block_chain.rb +44 -0
  83. data/lib/rubocop/cop/style/nil_comparison.rb +1 -3
  84. data/lib/rubocop/cop/style/not.rb +1 -1
  85. data/lib/rubocop/cop/style/numeric_literals.rb +26 -6
  86. data/lib/rubocop/cop/style/op_method.rb +2 -2
  87. data/lib/rubocop/cop/style/parameter_lists.rb +4 -4
  88. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  89. data/lib/rubocop/cop/style/perl_backrefs.rb +26 -0
  90. data/lib/rubocop/cop/style/proc.rb +1 -3
  91. data/lib/rubocop/cop/style/reduce_arguments.rb +7 -5
  92. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  93. data/lib/rubocop/cop/style/redundant_return.rb +9 -2
  94. data/lib/rubocop/cop/style/redundant_self.rb +9 -2
  95. data/lib/rubocop/cop/style/regexp_literal.rb +7 -8
  96. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  97. data/lib/rubocop/cop/style/semicolon.rb +10 -10
  98. data/lib/rubocop/cop/style/signal_exception.rb +2 -4
  99. data/lib/rubocop/cop/style/single_line_methods.rb +2 -4
  100. data/lib/rubocop/cop/style/space_after_comma_etc.rb +1 -1
  101. data/lib/rubocop/cop/style/space_after_control_keyword.rb +1 -1
  102. data/lib/rubocop/cop/style/space_after_method_name.rb +1 -1
  103. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +34 -0
  104. data/lib/rubocop/cop/style/{avoid_perlisms.rb → special_global_vars.rb} +17 -8
  105. data/lib/rubocop/cop/style/string_literals.rb +1 -2
  106. data/lib/rubocop/cop/style/surrounding_space.rb +9 -8
  107. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  108. data/lib/rubocop/cop/style/symbol_name.rb +9 -2
  109. data/lib/rubocop/cop/style/tab.rb +5 -5
  110. data/lib/rubocop/cop/style/ternary_operator.rb +2 -6
  111. data/lib/rubocop/cop/style/trailing_blank_lines.rb +32 -0
  112. data/lib/rubocop/cop/style/trailing_whitespace.rb +5 -6
  113. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  114. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  115. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -3
  116. data/lib/rubocop/cop/style/when_then.rb +1 -4
  117. data/lib/rubocop/cop/style/while_until_do.rb +7 -5
  118. data/lib/rubocop/cop/style/word_array.rb +1 -1
  119. data/lib/rubocop/cop/team.rb +100 -0
  120. data/lib/rubocop/cop/variable_inspector.rb +323 -235
  121. data/lib/rubocop/cop/variable_inspector/assignment.rb +103 -0
  122. data/lib/rubocop/cop/variable_inspector/locatable.rb +162 -0
  123. data/lib/rubocop/cop/variable_inspector/reference.rb +31 -0
  124. data/lib/rubocop/cop/variable_inspector/scope.rb +70 -0
  125. data/lib/rubocop/cop/variable_inspector/variable.rb +87 -0
  126. data/lib/rubocop/cop/variable_inspector/variable_table.rb +129 -0
  127. data/lib/rubocop/formatter/json_formatter.rb +8 -8
  128. data/lib/rubocop/formatter/progress_formatter.rb +4 -4
  129. data/lib/rubocop/processed_source.rb +22 -1
  130. data/lib/rubocop/version.rb +1 -1
  131. data/rubocop.gemspec +1 -1
  132. data/spec/rubocop/cli_spec.rb +32 -30
  133. data/spec/rubocop/config_spec.rb +4 -6
  134. data/spec/rubocop/cop/commissioner_spec.rb +4 -5
  135. data/spec/rubocop/cop/cop_spec.rb +8 -26
  136. data/spec/rubocop/cop/lint/assignment_in_condition_spec.rb +5 -9
  137. data/spec/rubocop/cop/lint/block_alignment_spec.rb +105 -57
  138. data/spec/rubocop/cop/lint/empty_ensure_spec.rb +1 -1
  139. data/spec/rubocop/cop/lint/end_alignment_spec.rb +1 -1
  140. data/spec/rubocop/cop/lint/end_in_method_spec.rb +1 -1
  141. data/spec/rubocop/cop/lint/ensure_return_spec.rb +1 -1
  142. data/spec/rubocop/cop/lint/eval_spec.rb +3 -3
  143. data/spec/rubocop/cop/lint/handle_exceptions_spec.rb +2 -2
  144. data/spec/rubocop/cop/lint/literal_in_condition_spec.rb +1 -1
  145. data/spec/rubocop/cop/lint/loop_spec.rb +1 -1
  146. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +1 -1
  147. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +5 -5
  148. data/spec/rubocop/cop/lint/unreachable_code_spec.rb +1 -1
  149. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +1545 -108
  150. data/spec/rubocop/cop/lint/useless_comparison_spec.rb +1 -1
  151. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +101 -0
  152. data/spec/rubocop/cop/lint/void_spec.rb +1 -1
  153. data/spec/rubocop/cop/offence_spec.rb +4 -4
  154. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +1 -1
  155. data/spec/rubocop/cop/rails/read_attribute_spec.rb +1 -1
  156. data/spec/rubocop/cop/rails/validation_spec.rb +1 -1
  157. data/spec/rubocop/cop/style/access_control_spec.rb +20 -20
  158. data/spec/rubocop/cop/style/alias_spec.rb +3 -3
  159. data/spec/rubocop/cop/style/align_array_spec.rb +62 -0
  160. data/spec/rubocop/cop/style/align_hash_spec.rb +267 -0
  161. data/spec/rubocop/cop/style/align_parameters_spec.rb +2 -2
  162. data/spec/rubocop/cop/style/and_or_spec.rb +1 -1
  163. data/spec/rubocop/cop/style/ascii_comments_spec.rb +2 -2
  164. data/spec/rubocop/cop/style/ascii_identifiers_spec.rb +2 -2
  165. data/spec/rubocop/cop/style/attr_spec.rb +1 -1
  166. data/spec/rubocop/cop/style/begin_block_spec.rb +1 -1
  167. data/spec/rubocop/cop/style/block_comments_spec.rb +1 -1
  168. data/spec/rubocop/cop/style/block_nesting_spec.rb +3 -3
  169. data/spec/rubocop/cop/style/blocks_spec.rb +25 -1
  170. data/spec/rubocop/cop/style/case_equality_spec.rb +1 -1
  171. data/spec/rubocop/cop/style/case_indentation_spec.rb +5 -5
  172. data/spec/rubocop/cop/style/character_literal_spec.rb +1 -1
  173. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +1 -1
  174. data/spec/rubocop/cop/style/class_methods_spec.rb +1 -1
  175. data/spec/rubocop/cop/style/class_vars_spec.rb +25 -0
  176. data/spec/rubocop/cop/style/collection_methods_spec.rb +5 -6
  177. data/spec/rubocop/cop/style/colon_method_call_spec.rb +0 -3
  178. data/spec/rubocop/cop/style/comment_annotation_spec.rb +20 -18
  179. data/spec/rubocop/cop/style/constant_name_spec.rb +1 -1
  180. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +1 -1
  181. data/spec/rubocop/cop/style/def_without_parentheses_spec.rb +1 -1
  182. data/spec/rubocop/cop/style/documentation_spec.rb +1 -1
  183. data/spec/rubocop/cop/style/dot_position_spec.rb +5 -5
  184. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +35 -4
  185. data/spec/rubocop/cop/style/empty_lines_spec.rb +1 -1
  186. data/spec/rubocop/cop/style/empty_literal_spec.rb +7 -7
  187. data/spec/rubocop/cop/style/encoding_spec.rb +11 -5
  188. data/spec/rubocop/cop/style/end_block_spec.rb +1 -1
  189. data/spec/rubocop/cop/style/end_of_line_spec.rb +4 -3
  190. data/spec/rubocop/cop/style/even_odd_spec.rb +1 -1
  191. data/spec/rubocop/cop/style/favor_join_spec.rb +2 -2
  192. data/spec/rubocop/cop/style/favor_modifier_spec.rb +13 -10
  193. data/spec/rubocop/cop/style/favor_sprintf_spec.rb +4 -4
  194. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
  195. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +4 -4
  196. data/spec/rubocop/cop/style/final_newline_spec.rb +25 -0
  197. data/spec/rubocop/cop/style/{avoid_for_spec.rb → for_spec.rb} +8 -12
  198. data/spec/rubocop/cop/style/{avoid_global_vars_spec.rb → global_vars_spec.rb} +13 -3
  199. data/spec/rubocop/cop/style/hash_methods_spec.rb +1 -1
  200. data/spec/rubocop/cop/style/hash_syntax_spec.rb +20 -9
  201. data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +3 -3
  202. data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -19
  203. data/spec/rubocop/cop/style/lambda_spec.rb +6 -6
  204. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +1 -1
  205. data/spec/rubocop/cop/style/line_length_spec.rb +3 -3
  206. data/spec/rubocop/cop/style/method_and_variable_snake_case_spec.rb +8 -9
  207. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +1 -1
  208. data/spec/rubocop/cop/style/method_length_spec.rb +18 -17
  209. data/spec/rubocop/cop/style/module_function_spec.rb +1 -1
  210. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +84 -0
  211. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
  212. data/spec/rubocop/cop/style/nil_comparison_spec.rb +1 -1
  213. data/spec/rubocop/cop/style/not_spec.rb +1 -1
  214. data/spec/rubocop/cop/style/numeric_literals_spec.rb +15 -25
  215. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -2
  216. data/spec/rubocop/cop/style/op_method_spec.rb +3 -3
  217. data/spec/rubocop/cop/style/parameter_lists_spec.rb +5 -5
  218. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +4 -8
  219. data/spec/rubocop/cop/style/perl_backrefs_spec.rb +23 -0
  220. data/spec/rubocop/cop/style/proc_spec.rb +1 -1
  221. data/spec/rubocop/cop/style/reduce_arguments_spec.rb +18 -11
  222. data/spec/rubocop/cop/style/redundant_begin_spec.rb +1 -1
  223. data/spec/rubocop/cop/style/redundant_return_spec.rb +16 -1
  224. data/spec/rubocop/cop/style/redundant_self_spec.rb +6 -1
  225. data/spec/rubocop/cop/style/regexp_literal_spec.rb +19 -23
  226. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +3 -3
  227. data/spec/rubocop/cop/style/semicolon_spec.rb +3 -3
  228. data/spec/rubocop/cop/style/signal_exception_spec.rb +1 -1
  229. data/spec/rubocop/cop/style/single_line_methods_spec.rb +22 -18
  230. data/spec/rubocop/cop/style/space_after_colon_spec.rb +4 -4
  231. data/spec/rubocop/cop/style/space_after_comma_spec.rb +4 -4
  232. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +1 -1
  233. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +1 -1
  234. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +3 -3
  235. data/spec/rubocop/cop/style/space_around_braces_spec.rb +13 -12
  236. data/spec/rubocop/cop/style/space_around_equals_in_default_parameter_spec.rb +3 -3
  237. data/spec/rubocop/cop/style/space_around_operators_spec.rb +25 -25
  238. data/spec/rubocop/cop/style/space_before_modifier_keyword_spec.rb +53 -0
  239. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +9 -9
  240. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +47 -61
  241. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +4 -4
  242. data/spec/rubocop/cop/style/special_global_vars_spec.rb +52 -0
  243. data/spec/rubocop/cop/style/string_literals_spec.rb +5 -5
  244. data/spec/rubocop/cop/style/symbol_array_spec.rb +1 -1
  245. data/spec/rubocop/cop/style/symbol_name_spec.rb +27 -18
  246. data/spec/rubocop/cop/style/tab_spec.rb +1 -1
  247. data/spec/rubocop/cop/style/ternary_operator_spec.rb +2 -2
  248. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +24 -0
  249. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +7 -7
  250. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +6 -14
  251. data/spec/rubocop/cop/style/unless_else_spec.rb +3 -3
  252. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +5 -5
  253. data/spec/rubocop/cop/style/when_then_spec.rb +15 -15
  254. data/spec/rubocop/cop/style/while_until_do_spec.rb +3 -3
  255. data/spec/rubocop/cop/style/word_array_spec.rb +1 -1
  256. data/spec/rubocop/cop/team_spec.rb +158 -0
  257. data/spec/rubocop/cop/variable_inspector/assignment_spec.rb +217 -0
  258. data/spec/rubocop/cop/variable_inspector/locatable_spec.rb +740 -0
  259. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +191 -0
  260. data/spec/rubocop/cop/variable_inspector/variable_spec.rb +79 -0
  261. data/spec/rubocop/cop/variable_inspector/variable_table_spec.rb +275 -0
  262. data/spec/rubocop/cop/variable_inspector_spec.rb +13 -533
  263. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +4 -4
  264. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +1 -1
  265. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +3 -3
  266. data/spec/rubocop/formatter/file_list_formatter_spec.rb +3 -3
  267. data/spec/rubocop/formatter/progress_formatter_spec.rb +1 -1
  268. data/spec/spec_helper.rb +5 -1
  269. data/spec/support/ast_helper.rb +15 -0
  270. data/spec/support/shared_context.rb +18 -0
  271. data/spec/support/shared_examples.rb +1 -1
  272. metadata +95 -32
  273. checksums.yaml +0 -7
  274. data/lib/rubocop/cop/lint/unused_local_variable.rb +0 -32
  275. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +0 -19
  276. data/spec/rubocop/cop/lint/unused_local_variable_spec.rb +0 -588
  277. data/spec/rubocop/cop/style/avoid_class_vars_spec.rb +0 -27
  278. data/spec/rubocop/cop/style/avoid_perl_backrefs_spec.rb +0 -20
  279. data/spec/rubocop/cop/style/avoid_perlisms_spec.rb +0 -47
@@ -0,0 +1,191 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module VariableInspector
8
+ describe Scope do
9
+ include ASTHelper
10
+ include AST::Sexp
11
+
12
+ describe '.new' do
13
+ context 'when non scope node is passed' do
14
+ it 'raises error' do
15
+ node = s(:lvasgn)
16
+ expect { Scope.new(node) }.to raise_error(ArgumentError)
17
+ end
18
+ end
19
+
20
+ context 'when begin node is passed' do
21
+ it 'accepts that as pseudo scope for top level scope' do
22
+ node = s(:begin)
23
+ expect { Scope.new(node) }.not_to raise_error
24
+ end
25
+ end
26
+ end
27
+
28
+ let(:ast) do
29
+ processed_source = Rubocop::SourceParser.parse(source)
30
+ processed_source.ast
31
+ end
32
+
33
+ let(:scope_node_type) { :def }
34
+
35
+ let(:scope_node) do
36
+ found_node = scan_node(ast, include_origin_node: true) do |node|
37
+ break node if node.type == scope_node_type
38
+ end
39
+ fail 'No scope node found!' unless found_node
40
+ found_node
41
+ end
42
+
43
+ subject(:scope) { Scope.new(scope_node) }
44
+
45
+ describe '#ancestors_of_node' do
46
+ let(:source) do
47
+ <<-END
48
+ puts 1
49
+
50
+ class SomeClass
51
+ def some_method
52
+ foo = 1
53
+
54
+ if foo > 0
55
+ while foo < 10
56
+ this_is_target
57
+ foo += 1
58
+ end
59
+ else
60
+ do_something
61
+ end
62
+ end
63
+ end
64
+ END
65
+ end
66
+
67
+ let(:target_node) do
68
+ found_node = scan_node(ast) do |node|
69
+ next unless node.type == :send
70
+ _receiver_node, method_name = *node
71
+ break node if method_name == :this_is_target
72
+ end
73
+ fail 'No target node found!' unless found_node
74
+ found_node
75
+ end
76
+
77
+ it 'returns nodes in between the scope node and the passed node' do
78
+ ancestor_nodes = scope.ancestors_of_node(target_node)
79
+ ancestor_types = ancestor_nodes.map(&:type)
80
+ expect(ancestor_types).to eq([:begin, :if, :while, :begin])
81
+ end
82
+ end
83
+
84
+ describe '#body_node' do
85
+ shared_examples 'returns the body node' do
86
+ it 'returns the body node' do
87
+ expect(scope.body_node.children[1]).to eq(:this_is_target)
88
+ end
89
+ end
90
+
91
+ context 'when the scope is instance method' do
92
+ let(:source) do
93
+ <<-END
94
+ def some_method
95
+ this_is_target
96
+ end
97
+ END
98
+ end
99
+
100
+ let(:scope_node_type) { :def }
101
+
102
+ include_examples 'returns the body node'
103
+ end
104
+
105
+ context 'when the scope is singleton method' do
106
+ let(:source) do
107
+ <<-END
108
+ def self.some_method
109
+ this_is_target
110
+ end
111
+ END
112
+ end
113
+
114
+ let(:scope_node_type) { :defs }
115
+
116
+ include_examples 'returns the body node'
117
+ end
118
+
119
+ context 'when the scope is module' do
120
+ let(:source) do
121
+ <<-END
122
+ module SomeModule
123
+ this_is_target
124
+ end
125
+ END
126
+ end
127
+
128
+ let(:scope_node_type) { :module }
129
+
130
+ include_examples 'returns the body node'
131
+ end
132
+
133
+ context 'when the scope is class' do
134
+ let(:source) do
135
+ <<-END
136
+ class SomeClass
137
+ this_is_target
138
+ end
139
+ END
140
+ end
141
+
142
+ let(:scope_node_type) { :class }
143
+
144
+ include_examples 'returns the body node'
145
+ end
146
+
147
+ context 'when the scope is singleton class' do
148
+ let(:source) do
149
+ <<-END
150
+ class << self
151
+ this_is_target
152
+ end
153
+ END
154
+ end
155
+
156
+ let(:scope_node_type) { :sclass }
157
+
158
+ include_examples 'returns the body node'
159
+ end
160
+
161
+ context 'when the scope is block' do
162
+ let(:source) do
163
+ <<-END
164
+ 1.times do
165
+ this_is_target
166
+ end
167
+ END
168
+ end
169
+
170
+ let(:scope_node_type) { :block }
171
+
172
+ include_examples 'returns the body node'
173
+ end
174
+
175
+ context 'when the scope is top level' do
176
+ let(:source) do
177
+ <<-END
178
+ foo = 1
179
+ this_is_target
180
+ END
181
+ end
182
+
183
+ let(:scope_node_type) { :begin }
184
+
185
+ include_examples 'returns the body node'
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module VariableInspector
8
+ describe Variable do
9
+ include AST::Sexp
10
+
11
+ describe '.new' do
12
+ context 'when non variable declaration node is passed' do
13
+ it 'raises error' do
14
+ name = :foo
15
+ declaration_node = s(:def)
16
+ scope = Scope.new(s(:class))
17
+ expect { Variable.new(name, declaration_node, scope) }
18
+ .to raise_error(ArgumentError)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe '#referenced?' do
24
+ let(:name) { :foo }
25
+ let(:declaration_node) { s(:arg, name) }
26
+ let(:scope) { double('scope') }
27
+ let(:variable) { Variable.new(name, declaration_node, scope) }
28
+
29
+ subject { variable.referenced? }
30
+
31
+ context 'when the variable is not yet assigned' do
32
+ it { should be_false }
33
+ end
34
+
35
+ context 'when the variable has an assignment' do
36
+ before do
37
+ variable.assign(s(:lvasgn, :foo))
38
+ end
39
+
40
+ context 'and the assignment is not yet referenced' do
41
+ it { should be_false }
42
+ end
43
+
44
+ context 'and the assignment is referenced' do
45
+ before do
46
+ variable.assignments.first.reference!
47
+ end
48
+
49
+ it { should be_true }
50
+ end
51
+ end
52
+
53
+ context 'when the variable has multiple assignments' do
54
+ before do
55
+ variable.assign(s(:lvasgn, :foo))
56
+ variable.assign(s(:lvasgn, :foo))
57
+ end
58
+
59
+ context 'and only once assignment is referenced' do
60
+ before do
61
+ variable.assignments[1].reference!
62
+ end
63
+
64
+ it { should be_true }
65
+ end
66
+
67
+ context 'and all assignments are referenced' do
68
+ before do
69
+ variable.assignments.each { |a| a.reference! }
70
+ end
71
+
72
+ it { should be_true }
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,275 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module VariableInspector
8
+ describe VariableTable do
9
+ include AST::Sexp
10
+
11
+ subject(:variable_table) { VariableTable.new }
12
+
13
+ describe '#push_scope' do
14
+ it 'returns pushed scope object' do
15
+ node = s(:def)
16
+ scope = variable_table.push_scope(node)
17
+ expect(scope).to equal(variable_table.current_scope)
18
+ expect(scope.node).to equal(node)
19
+ end
20
+ end
21
+
22
+ describe '#pop_scope' do
23
+ before do
24
+ node = s(:def)
25
+ variable_table.push_scope(node)
26
+ end
27
+
28
+ it 'returns popped scope object' do
29
+ last_scope = variable_table.current_scope
30
+ popped_scope = variable_table.pop_scope
31
+ expect(popped_scope).to equal(last_scope)
32
+ end
33
+ end
34
+
35
+ describe '#current_scope_level' do
36
+ before do
37
+ variable_table.push_scope(s(:def))
38
+ end
39
+
40
+ it 'increases by pushing scope' do
41
+ last_scope_level = variable_table.current_scope_level
42
+ variable_table.push_scope(s(:def))
43
+ expect(variable_table.current_scope_level)
44
+ .to eq(last_scope_level + 1)
45
+ end
46
+
47
+ it 'decreases by popping scope' do
48
+ last_scope_level = variable_table.current_scope_level
49
+ variable_table.pop_scope
50
+ expect(variable_table.current_scope_level)
51
+ .to eq(last_scope_level - 1)
52
+ end
53
+ end
54
+
55
+ describe '#declare_variable' do
56
+ before do
57
+ 2.times do
58
+ node = s(:def)
59
+ variable_table.push_scope(node)
60
+ end
61
+ end
62
+
63
+ it 'adds variable to current scope with its name as key' do
64
+ node = s(:lvasgn, :foo)
65
+ variable_table.declare_variable(:foo, node)
66
+ expect(variable_table.current_scope.variables)
67
+ .to have_key(:foo)
68
+ expect(variable_table.scope_stack[-2].variables)
69
+ .to be_empty
70
+ variable = variable_table.current_scope.variables[:foo]
71
+ expect(variable.declaration_node).to equal(node)
72
+ end
73
+
74
+ it 'returns the added variable' do
75
+ node = s(:lvasgn, :foo)
76
+ variable = variable_table.declare_variable(:foo, node)
77
+ expect(variable.declaration_node).to equal(node)
78
+ end
79
+ end
80
+
81
+ describe '#find_variable' do
82
+ before do
83
+ variable_table.push_scope(s(:class))
84
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
85
+
86
+ variable_table.push_scope(s(:def))
87
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
88
+ end
89
+
90
+ context 'when current scope is block' do
91
+ before do
92
+ variable_table.push_scope(s(:block))
93
+ end
94
+
95
+ context 'when a variable with the target name exists ' +
96
+ 'in current scope' do
97
+ before do
98
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
99
+ end
100
+
101
+ context 'and does not exist in outer scope' do
102
+ it 'returns the current scope variable' do
103
+ found_variable = variable_table.find_variable(:foo)
104
+ expect(found_variable.name).to eq(:foo)
105
+ end
106
+ end
107
+
108
+ context 'and also exists in outer scope' do
109
+ before do
110
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
111
+ end
112
+
113
+ it 'returns the current scope variable' do
114
+ found_variable = variable_table.find_variable(:bar)
115
+ expect(found_variable.name).to equal(:bar)
116
+ expect(variable_table.current_scope.variables)
117
+ .to have_value(found_variable)
118
+ expect(variable_table.scope_stack[-2].variables)
119
+ .not_to have_value(found_variable)
120
+ end
121
+ end
122
+ end
123
+
124
+ context 'when a variable with the target name does not exist ' +
125
+ 'in current scope' do
126
+ context 'but exists in the direct outer scope' do
127
+ it 'returns the direct outer scope variable' do
128
+ found_variable = variable_table.find_variable(:bar)
129
+ expect(found_variable.name).to equal(:bar)
130
+ end
131
+ end
132
+
133
+ context 'but exists in a indirect outer scope' do
134
+ context 'when the direct outer scope is block' do
135
+ before do
136
+ variable_table.pop_scope
137
+ variable_table.pop_scope
138
+
139
+ variable_table.push_scope(s(:block))
140
+ variable_table.push_scope(s(:block))
141
+ end
142
+
143
+ it 'returns the indirect outer scope variable' do
144
+ found_variable = variable_table.find_variable(:baz)
145
+ expect(found_variable.name).to equal(:baz)
146
+ end
147
+ end
148
+
149
+ context 'when the direct outer scope is not block' do
150
+ it 'returns nil' do
151
+ found_variable = variable_table.find_variable(:baz)
152
+ expect(found_variable).to be_nil
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'and does not exist in all outer scopes' do
158
+ it 'returns nil' do
159
+ found_variable = variable_table.find_variable(:non)
160
+ expect(found_variable).to be_nil
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ context 'when current scope is not block' do
167
+ before do
168
+ variable_table.push_scope(s(:def))
169
+ end
170
+
171
+ context 'when a variable with the target name exists ' +
172
+ 'in current scope' do
173
+ before do
174
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
175
+ end
176
+
177
+ context 'and does not exist in outer scope' do
178
+ it 'returns the current scope variable' do
179
+ found_variable = variable_table.find_variable(:foo)
180
+ expect(found_variable.name).to eq(:foo)
181
+ end
182
+ end
183
+
184
+ context 'and also exists in outer scope' do
185
+ it 'returns the current scope variable' do
186
+ found_variable = variable_table.find_variable(:foo)
187
+ expect(found_variable.name).to equal(:foo)
188
+ expect(variable_table.current_scope.variables)
189
+ .to have_value(found_variable)
190
+ expect(variable_table.scope_stack[-2].variables)
191
+ .not_to have_value(found_variable)
192
+ end
193
+ end
194
+ end
195
+
196
+ context 'when a variable with the target name does not exist ' +
197
+ 'in current scope' do
198
+ context 'but exists in the direct outer scope' do
199
+ it 'returns nil' do
200
+ found_variable = variable_table.find_variable(:bar)
201
+ expect(found_variable).to be_nil
202
+ end
203
+ end
204
+
205
+ context 'and does not exist in all outer scopes' do
206
+ it 'returns nil' do
207
+ found_variable = variable_table.find_variable(:non)
208
+ expect(found_variable).to be_nil
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ describe '#accessible_variables' do
216
+ let(:accessible_variable_names) do
217
+ variable_table.accessible_variables.map(&:name)
218
+ end
219
+
220
+ before do
221
+ variable_table.push_scope(s(:class))
222
+ end
223
+
224
+ context 'when there are no variables' do
225
+ it 'returns empty array' do
226
+ expect(variable_table.accessible_variables).to be_empty
227
+ end
228
+ end
229
+
230
+ context 'when the current scope has some variables' do
231
+ before do
232
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
233
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
234
+ end
235
+
236
+ it 'returns all the variables' do
237
+ expect(accessible_variable_names).to match_array([:foo, :bar])
238
+ end
239
+ end
240
+
241
+ context 'when the direct outer scope has some variables' do
242
+ before do
243
+ variable_table.declare_variable(:foo, s(:lvasgn, :foo))
244
+ end
245
+
246
+ context 'and the current scope is block' do
247
+ before do
248
+ variable_table.push_scope(s(:block))
249
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
250
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
251
+ end
252
+
253
+ it 'returns the current and direct outer scope variables' do
254
+ expect(accessible_variable_names)
255
+ .to match_array([:foo, :bar, :baz])
256
+ end
257
+ end
258
+
259
+ context 'and the current scope is not block' do
260
+ before do
261
+ variable_table.push_scope(s(:def))
262
+ variable_table.declare_variable(:bar, s(:lvasgn, :bar))
263
+ variable_table.declare_variable(:baz, s(:lvasgn, :baz))
264
+ end
265
+
266
+ it 'returns only the current scope variables' do
267
+ expect(accessible_variable_names).to match_array([:bar, :baz])
268
+ end
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end