# frozen_string_literal: truemoduleRuboCopmoduleCopmoduleRSpec# Use consistent metadata style.## This cop does not support autocorrection in the case of# `EnforcedStyle: hash` where the trailing metadata type is ambiguous.# (e.g. `describe 'Something', :a, b`)## @example EnforcedStyle: symbol (default)# # bad# describe 'Something', a: true## # good# describe 'Something', :a## @example EnforcedStyle: hash# # bad# describe 'Something', :a## # good# describe 'Something', a: trueclassMetadataStyle<Base# rubocop:disable Metrics/ClassLengthextendAutoCorrectorincludeConfigurableEnforcedStyleincludeMetadataincludeRangeHelp# @!method extract_metadata_hash(node)def_node_matcher:extract_metadata_hash,<<~PATTERN
(send _ _ _ ... $hash)
PATTERN# @!method match_boolean_metadata_pair?(node)def_node_matcher:match_boolean_metadata_pair?,<<~PATTERN
(pair sym true)
PATTERN# @!method match_ambiguous_trailing_metadata?(node)def_node_matcher:match_ambiguous_trailing_metadata?,<<~PATTERN
(send _ _ _ ... !{hash sym})
PATTERNdefon_metadata(symbols,hash)# RSpec example groups accept two string arguments. In such a case,# the rspec_metadata matcher will interpret the second string# argument as a metadata symbol.symbols.shiftifsymbols.first&.str_type?symbols.eachdo|symbol|on_metadata_symbol(symbol)endreturnunlesshashhash.pairs.eachdo|pair|on_metadata_pair(pair)endendprivatedefautocorrect_pair(corrector,node)remove_pair(corrector,node)insert_symbol(corrector,node)enddefautocorrect_symbol(corrector,node)returnifmatch_ambiguous_trailing_metadata?(node.parent)remove_symbol(corrector,node)insert_pair(corrector,node)enddefbad_metadata_pair?(node)style==:symbol&&match_boolean_metadata_pair?(node)enddefbad_metadata_symbol?(_node)style==:hashenddefformat_symbol_to_pair_source(node)"#{node.value}: true"enddefinsert_pair(corrector,node)hash_node=extract_metadata_hash(node.parent)ifhash_node.nil?insert_pair_as_last_argument(corrector,node)elsifhash_node.pairs.any?insert_pair_to_non_empty_hash_metadata(corrector,node,hash_node)elseinsert_pair_to_empty_hash_metadata(corrector,node,hash_node)endenddefinsert_pair_as_last_argument(corrector,node)corrector.insert_before(node.parent.location.end||node.parent.source_range.with(begin_pos: node.parent.source_range.end_pos),", #{format_symbol_to_pair_source(node)}")enddefinsert_pair_to_empty_hash_metadata(corrector,node,hash_node)corrector.insert_after(hash_node.location.begin," #{format_symbol_to_pair_source(node)} ")enddefinsert_pair_to_non_empty_hash_metadata(corrector,node,hash_node)corrector.insert_after(hash_node.children.last,", #{format_symbol_to_pair_source(node)}")enddefinsert_symbol(corrector,node)corrector.insert_after(node.parent.left_sibling,", #{node.key.value.inspect}")enddefmessage_for_styleformat('Use %<style>s style for metadata.',style: style)enddefon_metadata_pair(node)returnunlessbad_metadata_pair?(node)add_offense(node,message: message_for_style)do|corrector|autocorrect_pair(corrector,node)endenddefon_metadata_symbol(node)returnunlessbad_metadata_symbol?(node)add_offense(node,message: message_for_style)do|corrector|autocorrect_symbol(corrector,node)endenddefremove_pair(corrector,node)if!node.parent.braces?||node.left_siblings.any?remove_pair_following(corrector,node)elsifnode.right_siblings.any?remove_pair_preceding(corrector,node)elsecorrector.remove(node)endenddefremove_pair_following(corrector,node)corrector.remove(range_with_surrounding_comma(range_with_surrounding_space(node.source_range,side: :left),:left))enddefremove_pair_preceding(corrector,node)corrector.remove(range_with_surrounding_space(range_with_surrounding_comma(node.source_range,:right),side: :right))enddefremove_symbol(corrector,node)corrector.remove(range_with_surrounding_comma(range_with_surrounding_space(node.source_range,side: :left),:left))endendendendend