|
| 1 | += Upgrade to Version 2.x |
| 2 | +:doctype: book |
| 3 | + |
| 4 | +== Configuration File Update |
| 5 | + |
| 6 | +In version 2.x: |
| 7 | + |
| 8 | + - `RSpec/InvalidPredicateMatcher` cop is removed |
| 9 | + - `RSpec/EmptyExampleGroup`'s `CustomIncludeMethods` configuration option is removed |
| 10 | + |
| 11 | +[discrete] |
| 12 | +=== Adjust the configuration of `RSpec/EmptyExampleGroup` |
| 13 | + |
| 14 | +[source,yaml] |
| 15 | +---- |
| 16 | +# .rubocop.yml |
| 17 | +
|
| 18 | +# Before |
| 19 | +RSpec/EmptyExampleGroup: |
| 20 | + CustomIncludeMethods: |
| 21 | + - include_tests |
| 22 | +
|
| 23 | +# After |
| 24 | +AllCops: |
| 25 | + RSpec: |
| 26 | + Language: |
| 27 | + Includes: |
| 28 | + Example: |
| 29 | + - include_tests |
| 30 | +---- |
| 31 | + |
| 32 | +== Custom Cop Update Guide |
| 33 | + |
| 34 | +Due to significant API changes custom cops will break. |
| 35 | +Here is the summary of the changes: |
| 36 | + |
| 37 | +1) The base class for cops is now `RuboCop::Cop::RSpec::Base` instead of `RuboCop::Cop::RSpec::Cop`. |
| 38 | + |
| 39 | +2) `TopLevelDescribe` is replaced with a more generic `TopLevelGroup`. |
| 40 | + |
| 41 | +3) `RuboCop::RSpec::Language` has been completely rewritten to support dynamic RSpec DSL aliases and negated matchers to fully support third-party libraries e.g. RSpec Rails, Pundit, Action Policy and many others. |
| 42 | + |
| 43 | +4) RuboCop RSpec updated the dependency of RuboCop to 1.0+. |
| 44 | + |
| 45 | +Below are the necessary steps to update custom cops to work with `rubocop-rspec` version 2.x. |
| 46 | + |
| 47 | + |
| 48 | +=== Change the Parent Class |
| 49 | + |
| 50 | +Change the parent class of the custom cops from `RuboCop::Cop::RSpec::Cop` to` RuboCop::Cop::RSpec::Base`. |
| 51 | + |
| 52 | +[source,ruby] |
| 53 | +---- |
| 54 | +# Before |
| 55 | +module RuboCop |
| 56 | + module Cop |
| 57 | + module RSpec |
| 58 | + class FightPowerty < Cop |
| 59 | +
|
| 60 | +# After |
| 61 | +module RuboCop |
| 62 | + module Cop |
| 63 | + module RSpec |
| 64 | + class FightPowerty < Base |
| 65 | +---- |
| 66 | + |
| 67 | +https://github.com/rubocop-hq/rubocop-rspec/pull/962[Example pull request]. |
| 68 | + |
| 69 | + |
| 70 | +=== Replace `TopLevelDescribe` |
| 71 | + |
| 72 | +`TopLevelDescribe` was incomplete, had poor performance and did not distinguish between example groups and shared example groups. |
| 73 | + |
| 74 | +`TopLevelGroup` provides a similar interface, but instead of a single `on_top_level_describe` hook there are two, `on_top_level_example_group` and `on_top_level_group`. |
| 75 | +There's no need yet for `on_top_level_shared_group` for RuboCop core cops, but if your custom cop needs such a hook, please feel free to send a pull request. |
| 76 | + |
| 77 | +Additionally, `single_top_level_describe?` is removed with no direct replacement. |
| 78 | +You may use `top_level_groups` query method instead, e.g. `top_level_groups.one?`. |
| 79 | + |
| 80 | +Example pull requests to replace `TopLevelDescribe` with `TopLevelGroup` [https://github.com/rubocop-hq/rubocop-rspec/pull/978[1], https://github.com/rubocop-hq/rubocop-rspec/pull/932[2], https://github.com/rubocop-hq/rubocop-rspec/pull/977[3]]. |
| 81 | + |
| 82 | + |
| 83 | +=== Change the `Language` Module Usages |
| 84 | + |
| 85 | +The `RuboCop::RSpec::Language` is completely different now. |
| 86 | +`Hooks::ALL` and alike, and their accompanying helpers work differently. |
| 87 | +To allow for lazy initialization, and for loading of the language configuration after the class are loaded, a https://docs.rubocop.org/rubocop-ast/node_pattern.html#to-call-functions[function call feature of RuboCop AST] is used. |
| 88 | + |
| 89 | +[source,ruby] |
| 90 | +---- |
| 91 | +# Before |
| 92 | +def_node_matcher :shared_context, |
| 93 | + SharedGroups::CONTEXT.block_pattern |
| 94 | +
|
| 95 | +# After |
| 96 | +def_node_matcher :shared_context, |
| 97 | + block_pattern('#rspec(:SharedGroups, :Context)') |
| 98 | +---- |
| 99 | + |
| 100 | +[source,ruby] |
| 101 | +---- |
| 102 | +# Before |
| 103 | +def_node_search :examples?, |
| 104 | + (Includes::EXAMPLES + Examples::ALL).send_pattern |
| 105 | +
|
| 106 | +# After |
| 107 | +def_node_search :examples?, |
| 108 | + send_pattern( |
| 109 | + '{#rspec(:Includes, :Example) #rspec(:Examples)}') |
| 110 | +---- |
| 111 | + |
| 112 | +[source,ruby] |
| 113 | +---- |
| 114 | +# Before |
| 115 | +def_node_search :find_rspec_blocks, |
| 116 | + ExampleGroups::ALL.block_pattern |
| 117 | +
|
| 118 | +# After |
| 119 | +def_node_search :find_rspec_blocks, |
| 120 | + block_pattern('#rspec(:ExampleGroups)') |
| 121 | +---- |
| 122 | + |
| 123 | +https://github.com/rubocop-hq/rubocop-rspec/pull/956[Pull request with more examples]. |
| 124 | + |
| 125 | +=== Conform with RuboCop API Changes |
| 126 | + |
| 127 | +The parent project, RuboCop, have API changes. |
| 128 | +They won't result in cop breakages, however, it's recommended to update cops to use new APIs. |
| 129 | +Follow the https://docs.rubocop.org/rubocop/v1_upgrade_notes[RuboCop's core v1 update guide] to adjust custom cops' RuboCop Autocorrect API usage. |
0 commit comments