升级到 2.x 版本
配置文件更新
在 2.x 版本中
-
RSpec/InvalidPredicateMatcher
cop 已被移除 -
RSpec/EmptyExampleGroup
的CustomIncludeMethods
配置选项已移除 -
cop 部门嵌套,用于部门与扩展名不匹配的 cop (
Capybara
、FactoryBot
、Rails
) -
AllCops/RSpec/Patterns
/AllCops/FactoryBot/Patterns
选项已移除 -
现在,在 cop 中定义的
#on_new_investigation
中调用super
是强制性的。 -
在规范中,不要定义
cop
。
调整 RSpec/EmptyExampleGroup
的配置。
# .rubocop.yml
# Before
RSpec/EmptyExampleGroup:
CustomIncludeMethods:
- include_tests
# After
RSpec:
Language:
Includes:
Examples:
- include_tests
添加一个顶级 RSpec
部门。
RuboCop 扩展包含了具有冲突名称和部门的 cop,例如,rspec-rails
和 rubocop-rspec
都有 Rails::HttpStatus
cop。为了避免问题,例如无法仅禁用其中一个 cop,每个扩展现在都有自己的顶级部门。预期地,RuboCop RSpec 的顶级部门名称为 RSpec
。更改仅应用于尚未将部门设置为 RSpec
的 cop,即 Capybara
、FactoryBot
和 Rails
。
# .rubocop.yml
# Before
Capybara/CurrentPathExpectation:
Enabled: false
FactoryBot/AttributeDefinedStatically:
Enabled: false
# remains the same
RSpec/EmptyExampleGroup:
Enabled: false
# After
RSpec/Capybara/CurrentPathExpectation:
Enabled: false
RSpec/FactoryBot/AttributeDefinedStatically:
Enabled: false
# remains the same
RSpec/EmptyExampleGroup:
Enabled: false
使用 RuboCop 标准 Include
选项来过滤检查的文件。
Patterns
是 RuboCop RSpec 特定的选项,RuboCop 有一个标准的替代方案。
# .rubocop.yml
# Before
AllCops:
RSpec/FactoryBot:
Patterns:
- spec/factories/**/*.rb
- property/factories/**/*.rb
# After
RSpec/FactoryBot:
Include:
- spec/factories/**/*.rb
- property/factories/**/*.rb
请记住,Include 的合并模式设置为覆盖默认设置,因此,如果您打算在保留默认路径的同时添加路径,则应在配置中包含默认的 Include 路径。
|
自定义 Cop 更新指南
由于 API 发生了重大变化,自定义 cop 可能会中断。以下是更改的摘要。
-
cop 的基类现在是
RuboCop::Cop::RSpec::Base
,而不是RuboCop::Cop::RSpec::Cop
。 -
模块
RuboCop::Cop::RSpec::TopLevelDescribe
被更通用的RuboCop::Cop::RSpec::TopLevelGroup
替换。 -
RuboCop::RSpec::Language
已完全重写,以支持动态 RSpec DSL 别名和否定匹配器,以完全支持第三方库,例如 RSpec Rails、Pundit、Action Policy 等等。 -
RuboCop RSpec 将 RuboCop 的依赖项更新到 1.0+。
以下是将自定义 cop 更新为与 rubocop-rspec
版本 2.x 兼容的必要步骤。
更改父类
将自定义 cop 的父类从 RuboCop::Cop::RSpec::Cop
更改为 RuboCop::Cop::RSpec::Base
。
# Before
module RuboCop
module Cop
module RSpec
class FightPowerty < Cop
# After
module RuboCop
module Cop
module RSpec
class FightPowerty < Base
替换 TopLevelDescribe
TopLevelDescribe
不完整,性能很差,并且没有区分示例组和共享示例组。
TopLevelGroup
提供了类似的接口,但它不是单个 on_top_level_describe
钩子,而是两个钩子,on_top_level_example_group
和 on_top_level_group
。目前,RuboCop 核心 cop 不需要 on_top_level_shared_group
,但如果您的自定义 cop 需要这样的钩子,请随时发送拉取请求。
此外,single_top_level_describe?
已被删除,没有直接的替代方案。您可以使用 top_level_groups
查询方法,例如 top_level_groups.one?
。
更改 Language
模块的使用方式
为了允许延迟初始化,并在类加载后加载语言配置,使用了 RuboCop AST 的函数调用功能。
RuboCop::RSpec::Language
现在完全不同了。
Hooks::ALL
及其类似项,以及它们附带的助手的工作方式不同。
# Before
def_node_matcher :shared_context,
SharedGroups::CONTEXT.block_pattern
# After
def_node_matcher :shared_context,
'(block (send #rspec? #SharedGroups.context ...) ...)'
# Before
def_node_search :examples?,
(Includes::EXAMPLES + Examples::ALL).send_pattern
# After
def_node_search :examples?,
'(send nil? {#Includes.examples #Examples.all} ...)'
# Before
def_node_search :find_rspec_blocks,
ExampleGroups::ALL.block_pattern
# After
def_node_search :find_rspec_blocks,
'(block (send #rspec? #ExampleGroups.all ...) ...)'
如果您之前直接调用 Language 元素,则需要进行相同的调整。
# Before
node&.sym_type? && Hooks::Scopes::ALL.include?(node.value)
# After
node&.sym_type? && Language::HookScopes.all(node.value)
您可能会在更改中看到一个常见的模式。不过,有一个小例外。
# Before
ExampleGroups::GROUPS
# After
ExampleGroups.regular
# Before
Examples::EXAMPLES
# After
Examples.regular
在您的 cop 中始终从 on_new_investigation
调用 super
on_new_investigation
现在用于内部目的,如果您的 cop 没有从 super
调用,则存在配置未正确加载的风险,并且动态 RSpec DSL 匹配器将无法正常工作。
除非您需要,否则您不必在您的 cop 中定义 on_new_investigation 。
|
module RuboCop
module Cop
module RSpec
class MultipleMemoizedHelpers < Base
def on_new_investigation
super # Always call `super`
@example_group_memoized_helpers = {}
end
end
end
end
end
在 cop 规范中使用 :config
RSpec 元数据
:config
元数据应添加到 cop 规范的顶级示例组中。否则,配置将不会传递给 cop,并且动态 RSpec DSL 匹配器可能无法正常工作。
# Before
RSpec.describe 'MyMightyCop' do
let(:cop) { described_class.new }
# ...
end
# After
RSpec.describe 'MyMightyCop', :config do
# `cop` is defined for you by RuboCop's shared context that is included
# to example groups with :config metadata
# ...
end
符合 RuboCop API 更改
父项目 RuboCop 进行了 API 更改。虽然这些更改不会导致 cop 出现故障,但建议更新 cop 以使用新的 API。请按照 RuboCop v1 更新指南 调整自定义 cop 对 RuboCop 的自动更正 API 的使用。