Class: RuboCop::Cop::Airbnb::RspecDescribeOrContextUnderNamespace
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Airbnb::RspecDescribeOrContextUnderNamespace
- Defined in:
- lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb
Overview
This cop checks for Rspec describe or context method calls under a namespace. It can potentially cause autoloading to occur in a different order than it would have in development or production. This could cause flaky tests.
Constant Summary collapse
- DESCRIBE_OR_CONTEXT_UNDER_NAMESPACE_MSG =
'Declaring a `module` in a spec can break autoloading because subsequent references ' \ 'to it will not cause it to be loaded from the app. This could cause flaky tests.'.freeze
- FIX_DESCRIBE_OR_CONTEXT_HELP_MSG =
'Change `%{describe} %{klass} do` to `%{describe} %{module_name}::%{klass} do`.'.freeze
- FIX_CODE_HELP_MSG =
'Remove `module %{module_name}` and fix `%{module_name}::CONST` and ' \ '`%{module_name}.method` calls accordingly.'.freeze
Instance Method Summary collapse
- #get_described_class(node) ⇒ Object
- #get_method_parent(node) ⇒ Object
- #get_module_name(node) ⇒ Object
- #is_block?(node) ⇒ Boolean
- #is_spec_file?(path) ⇒ Boolean
- #on_module(node) ⇒ Object
- #search_children_for_describe_or_context(nodes) ⇒ Object
Instance Method Details
#get_described_class(node) ⇒ Object
96 97 98 99 100 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 96 def get_described_class(node) const_node = node.children[2] return unless const_node const_node.const_name end |
#get_method_parent(node) ⇒ Object
102 103 104 105 106 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 102 def get_method_parent(node) const_node = node.children[0] return unless const_node const_node.const_name end |
#get_module_name(node) ⇒ Object
90 91 92 93 94 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 90 def get_module_name(node) const_node = node.children[0] return unless const_node const_node.const_name end |
#is_block?(node) ⇒ Boolean
108 109 110 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 108 def is_block?(node) node && [:block, :begin].include?(node.type) end |
#is_spec_file?(path) ⇒ Boolean
86 87 88 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 86 def is_spec_file?(path) path.end_with?('_spec.rb') end |
#on_module(node) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 38 def on_module(node) path = node.source_range.source_buffer.name return unless is_spec_file?(path) matched_node = search_children_for_describe_or_context(node.children) return unless matched_node method_name = matched_node.method_name module_name = get_module_name(node) = [DESCRIBE_OR_CONTEXT_UNDER_NAMESPACE_MSG] described_class = get_described_class(matched_node) method_parent = get_method_parent(matched_node) parent_dot_method = method_parent ? "#{method_parent}.#{method_name}" : method_name if described_class << FIX_DESCRIBE_OR_CONTEXT_HELP_MSG % { describe: parent_dot_method, klass: described_class, module_name: module_name, } end << FIX_CODE_HELP_MSG % { module_name: module_name } add_offense(node, message: .join(' ')) end |
#search_children_for_describe_or_context(nodes) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb', line 64 def search_children_for_describe_or_context(nodes) blocks = [] # match nodes for send describe or context nodes.detect do |node| next unless node if is_block?(node) blocks << node next end return node if describe_or_context?(node) end # Process child nodes of block blocks.each do |node| matched_node = search_children_for_describe_or_context(node.children) return matched_node if matched_node end nil end |