-
-
Notifications
You must be signed in to change notification settings - Fork 289
Let RSpec/SpecFilePathFormat leverage ActiveSupport inflections when configured
#2090
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,12 @@ module RSpec | |
| # # good | ||
| # whatever_spec.rb # describe MyClass, type: :routing do; end | ||
| # | ||
| # @example `EnforcedInflector: active_support` | ||
| # # Enable to use ActiveSupport's inflector for custom acronyms | ||
| # # like HTTP, etc. Set to "default" by default. | ||
| # # Configure `InflectorPath` with the path to the inflector file. | ||
| # # The default is ./config/initializers/inflections.rb. | ||
| # | ||
| class SpecFilePathFormat < Base | ||
| include TopLevelGroup | ||
| include Namespace | ||
|
|
@@ -59,6 +65,53 @@ def on_top_level_example_group(node) | |
|
|
||
| private | ||
|
|
||
| # Inflector module that uses ActiveSupport for advanced inflection rules | ||
| module ActiveSupportInflector | ||
| def self.call(string) | ||
| ActiveSupport::Inflector.underscore(string) | ||
| end | ||
|
|
||
| def self.prepare_availability(config) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cop_config may differ across directories.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Corson and I talked about this a couple of times earlier. The main problem is that loaded inflections are stored globally, in I think that for most use cases, people will only have one inflection configuration, so it’s not a problem. But perhaps we should document the issue for those who may run into the issue in the future?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally reasonable. Even though the anxiety of having config race conditions never left me, we haven’t seen any real reports for … five tears? |
||
| return if @prepared | ||
|
|
||
| @prepared = true | ||
|
|
||
| inflector_path = config.fetch('InflectorPath') | ||
|
|
||
| unless File.exist?(inflector_path) | ||
| raise "The configured `InflectorPath` #{inflector_path} does " \ | ||
| 'not exist.' | ||
| end | ||
|
|
||
| require 'active_support/inflector' | ||
| require inflector_path | ||
corsonknowles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| end | ||
| end | ||
|
|
||
| # Inflector module that uses basic regex-based conversion | ||
| module DefaultInflector | ||
| def self.call(string) | ||
| string | ||
| .gsub(/([^A-Z])([A-Z]+)/, '\1_\2') | ||
| .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2') | ||
| .downcase | ||
| end | ||
| end | ||
|
|
||
| def inflector | ||
| case cop_config.fetch('EnforcedInflector') | ||
| when 'active_support' | ||
| ActiveSupportInflector.prepare_availability(cop_config) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to the excessive caching across directories, there can be another problem - multiple threads. RuboCop can run in threads? Or are those processes? In any case, can we init the inflector once per inspection? Or this would be too expensive if the inflection file is large? I can think of a monorepo with many engines each with its own set of inflections |
||
| ActiveSupportInflector | ||
| when 'default' | ||
| DefaultInflector | ||
| else | ||
| # :nocov: | ||
| :noop | ||
| # :nocov: | ||
| end | ||
| end | ||
|
|
||
| def ensure_correct_file_path(send_node, class_name, arguments) | ||
| pattern = correct_path_pattern(class_name, arguments) | ||
| return if filename_ends_with?(pattern) | ||
|
|
@@ -106,10 +159,7 @@ def expected_path(constant) | |
| end | ||
|
|
||
| def camel_to_snake_case(string) | ||
| string | ||
| .gsub(/([^A-Z])([A-Z]+)/, '\1_\2') | ||
| .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2') | ||
| .downcase | ||
| inflector.call(string) | ||
| end | ||
|
|
||
| def custom_transform | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.