react_on_rails 12.0.0 → 12.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +0 -1
  3. data/.github/workflows/lint-js-and-ruby.yml +53 -0
  4. data/.github/workflows/main.yml +178 -0
  5. data/.github/workflows/package-js-tests.yml +35 -0
  6. data/.github/workflows/rspec-package-specs.yml +45 -0
  7. data/.rubocop.yml +18 -40
  8. data/.travis.yml +8 -4
  9. data/CHANGELOG.md +41 -20
  10. data/CONTRIBUTING.md +1 -1
  11. data/Gemfile +1 -33
  12. data/Gemfile.development_dependencies +54 -0
  13. data/NEWS.md +5 -0
  14. data/README.md +73 -65
  15. data/SUMMARY.md +1 -1
  16. data/docs/additional-reading/converting-from-custom-webpack-config-to-rails-webpacker-config.md +10 -0
  17. data/docs/additional-reading/react-router.md +1 -1
  18. data/docs/additional-reading/recommended-project-structure.md +69 -0
  19. data/docs/additional-reading/server-rendering-tips.md +4 -1
  20. data/docs/api/javascript-api.md +3 -3
  21. data/docs/api/redux-store-api.md +2 -2
  22. data/docs/api/view-helpers-api.md +4 -4
  23. data/docs/basics/client-vs-server-rendering.md +2 -0
  24. data/docs/basics/configuration.md +1 -1
  25. data/docs/basics/hmr-and-hot-reloading-with-the-webpack-dev-server.md +64 -9
  26. data/docs/basics/react-server-rendering.md +8 -5
  27. data/docs/basics/render-functions-and-railscontext.md +1 -1
  28. data/docs/basics/upgrading-react-on-rails.md +51 -14
  29. data/docs/basics/webpack-configuration.md +12 -18
  30. data/docs/misc/doctrine.md +0 -1
  31. data/docs/outdated/code-splitting.md +5 -5
  32. data/docs/tutorial.md +6 -0
  33. data/lib/generators/react_on_rails/base_generator.rb +8 -1
  34. data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +4 -1
  35. data/lib/generators/react_on_rails/templates/dev_tests/spec/simplecov_helper.rb +1 -1
  36. data/lib/react_on_rails/configuration.rb +2 -0
  37. data/lib/react_on_rails/git_utils.rb +3 -3
  38. data/lib/react_on_rails/helper.rb +15 -14
  39. data/lib/react_on_rails/locales/to_js.rb +0 -4
  40. data/lib/react_on_rails/locales/to_json.rb +0 -4
  41. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +6 -6
  42. data/lib/react_on_rails/test_helper.rb +2 -0
  43. data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +1 -1
  44. data/lib/react_on_rails/utils.rb +8 -2
  45. data/lib/react_on_rails/version.rb +1 -1
  46. data/lib/react_on_rails/webpacker_utils.rb +4 -4
  47. data/lib/tasks/assets.rake +21 -9
  48. data/package.json +1 -1
  49. data/rakelib/docker.rake +0 -5
  50. data/rakelib/examples.rake +1 -1
  51. data/rakelib/lint.rake +4 -10
  52. data/rakelib/release.rake +9 -13
  53. data/rakelib/run_rspec.rake +9 -10
  54. data/rakelib/task_helpers.rb +2 -3
  55. data/react_on_rails.gemspec +3 -17
  56. metadata +15 -192
  57. data/docs/additional-reading/webpack-dev-server.md +0 -15
  58. data/docs/basics/recommended-project-structure.md +0 -77
  59. data/ruby-lint.yml +0 -25
@@ -15,7 +15,10 @@ require "capybara/rspec"
15
15
  require "capybara/rails"
16
16
  Capybara.javascript_driver = :selenium_chrome
17
17
  Capybara.register_driver :selenium_chrome do |app|
18
- Capybara::Selenium::Driver.new(app, browser: :chrome)
18
+ options = Selenium::WebDriver::Chrome::Options.new
19
+ options.add_argument("--headless")
20
+ options.add_argument("--disable-gpu")
21
+ Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
19
22
  end
20
23
 
21
24
  # Requires supporting ruby files with custom matchers and macros, etc, in
@@ -17,7 +17,7 @@ if ENV["COVERAGE"] == "true"
17
17
 
18
18
  # Don't report anything that has "spec" in the path
19
19
  add_filter do |src|
20
- src.filename =~ %r{\/spec\/}
20
+ src.filename =~ %r{/spec/}
21
21
  end
22
22
  end
23
23
  end
@@ -53,6 +53,7 @@ module ReactOnRails
53
53
  :server_render_method, :random_dom_id,
54
54
  :same_bundle_for_client_and_server
55
55
 
56
+ # rubocop:disable Metrics/AbcSize
56
57
  def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
57
58
  replay_console: nil,
58
59
  trace: nil, development_mode: nil,
@@ -98,6 +99,7 @@ module ReactOnRails
98
99
 
99
100
  self.server_render_method = server_render_method
100
101
  end
102
+ # rubocop:enable Metrics/AbcSize
101
103
 
102
104
  # on ReactOnRails
103
105
  def setup_config_values
@@ -10,10 +10,10 @@ module ReactOnRails
10
10
  status = `git status --porcelain`
11
11
  return false if $CHILD_STATUS.success? && status.empty?
12
12
 
13
- error = if !$CHILD_STATUS.success?
14
- "You do not have Git installed. Please install Git, and commit your changes before continuing"
15
- else
13
+ error = if $CHILD_STATUS.success?
16
14
  "You have uncommitted code. Please commit or stash your changes before continuing"
15
+ else
16
+ "You do not have Git installed. Please install Git, and commit your changes before continuing"
17
17
  end
18
18
  message_handler.add_error(error)
19
19
  true
@@ -17,13 +17,13 @@ module ReactOnRails
17
17
 
18
18
  COMPONENT_HTML_KEY = "componentHtml"
19
19
 
20
- # react_component_name: can be a React function or class component or a "render function".
21
- # "render functions" differ from a React function in that they take two parameters, the
20
+ # react_component_name: can be a React function or class component or a "Render-Function".
21
+ # "Render-Functions" differ from a React function in that they take two parameters, the
22
22
  # props and the railsContext, like this:
23
23
  #
24
24
  # let MyReactComponentApp = (props, railsContext) => <MyReactComponent {...props}/>;
25
25
  #
26
- # Alternately, you can define the render function with an additional property
26
+ # Alternately, you can define the Render-Function with an additional property
27
27
  # `.renderFunction = true`:
28
28
  #
29
29
  # let MyReactComponentApp = (props) => <MyReactComponent {...props}/>;
@@ -32,8 +32,8 @@ module ReactOnRails
32
32
  # Exposing the react_component_name is necessary to both a plain ReactComponent as well as
33
33
  # a generator:
34
34
  # See README.md for how to "register" your react components.
35
- # See spec/dummy/client/app/startup/serverRegistration.jsx and
36
- # spec/dummy/client/app/startup/ClientRegistration.jsx for examples of this
35
+ # See spec/dummy/client/app/packs/server-bundle.js and
36
+ # spec/dummy/client/app/packs/client-bundle.js for examples of this.
37
37
  #
38
38
  # options:
39
39
  # props: Ruby Hash or JSON string which contains the properties to pass to the react object. Do
@@ -57,14 +57,15 @@ module ReactOnRails
57
57
  server_rendered_html = internal_result[:result]["html"]
58
58
  console_script = internal_result[:result]["consoleReplayScript"]
59
59
 
60
- if server_rendered_html.is_a?(String)
60
+ case server_rendered_html
61
+ when String
61
62
  build_react_component_result_for_server_rendered_string(
62
63
  server_rendered_html: server_rendered_html,
63
64
  component_specification_tag: internal_result[:tag],
64
65
  console_script: console_script,
65
66
  render_options: internal_result[:render_options]
66
67
  )
67
- elsif server_rendered_html.is_a?(Hash)
68
+ when Hash
68
69
  msg = <<~MSG
69
70
  Use react_component_hash (not react_component) to return a Hash to your ruby view code. See
70
71
  https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
@@ -79,7 +80,7 @@ module ReactOnRails
79
80
  Value:
80
81
  #{server_rendered_html}
81
82
 
82
- If you're trying to use a render function to return a Hash to your ruby view code, then use
83
+ If you're trying to use a Render-Function to return a Hash to your ruby view code, then use
83
84
  react_component_hash instead of react_component and see
84
85
  https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
85
86
  for an example of the JavaScript code.
@@ -93,7 +94,7 @@ module ReactOnRails
93
94
  # It is exactly like react_component except for the following:
94
95
  # 1. prerender: true is automatically added, as this method doesn't make sense for client only
95
96
  # rendering.
96
- # 2. Your JavaScript render function for server rendering must return an Object rather than a React component.
97
+ # 2. Your JavaScript Render-Function for server rendering must return an Object rather than a React component.
97
98
  # 3. Your view code must expect an object and not a string.
98
99
  #
99
100
  # Here is an example of the view code:
@@ -124,10 +125,10 @@ module ReactOnRails
124
125
  )
125
126
  else
126
127
  msg = <<~MSG
127
- render function used by react_component_hash for #{component_name} is expected to return
128
+ Render-Function used by react_component_hash for #{component_name} is expected to return
128
129
  an Object. See https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/client/app/startup/ReactHelmetServerApp.jsx
129
130
  for an example of the JavaScript code.
130
- Note, your render function must either take 2 params or have the property
131
+ Note, your Render-Function must either take 2 params or have the property
131
132
  `.renderFunction = true` added to it to distinguish it from a React Function Component.
132
133
  MSG
133
134
  raise ReactOnRails::Error, msg
@@ -240,10 +241,10 @@ module ReactOnRails
240
241
  end
241
242
 
242
243
  # This is the definitive list of the default values used for the rails_context, which is the
243
- # second parameter passed to both component and store render functions.
244
+ # second parameter passed to both component and store Render-Functions.
244
245
  # This method can be called from views and from the controller, as `helpers.rails_context`
245
246
  #
246
- # rubocop:disable Metrics/AbcSize
247
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
247
248
  def rails_context(server_side: true)
248
249
  # ALERT: Keep in sync with node_package/src/types/index.ts for the properties of RailsContext
249
250
  @rails_context ||= begin
@@ -291,7 +292,7 @@ module ReactOnRails
291
292
 
292
293
  @rails_context.merge(serverSide: server_side)
293
294
  end
294
- # rubocop:enable Metrics/AbcSize
295
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
295
296
 
296
297
  private
297
298
 
@@ -5,10 +5,6 @@ require "erb"
5
5
  module ReactOnRails
6
6
  module Locales
7
7
  class ToJs < Base
8
- def initialize
9
- super
10
- end
11
-
12
8
  private
13
9
 
14
10
  def file_format
@@ -5,10 +5,6 @@ require "erb"
5
5
  module ReactOnRails
6
6
  module Locales
7
7
  class ToJson < Base
8
- def initialize
9
- super
10
- end
11
-
12
8
  private
13
9
 
14
10
  def file_format
@@ -47,6 +47,7 @@ module ReactOnRails
47
47
  # Note, js_code does not have to be based on React.
48
48
  # js_code MUST RETURN json stringify Object
49
49
  # Calling code will probably call 'html_safe' on return value before rendering to the view.
50
+ # rubocop:disable Metrics/CyclomaticComplexity
50
51
  def exec_server_render_js(js_code, render_options, js_evaluator = nil)
51
52
  js_evaluator ||= self
52
53
  if render_options.trace
@@ -67,16 +68,15 @@ module ReactOnRails
67
68
  console_script = result["consoleReplayScript"]
68
69
  console_script_lines = console_script.split("\n")
69
70
  console_script_lines = console_script_lines[2..-2]
70
- re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
71
- if console_script_lines
72
- console_script_lines.each do |line|
73
- match = re.match(line)
74
- Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
75
- end
71
+ re = /console\.(?:log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
72
+ console_script_lines&.each do |line|
73
+ match = re.match(line)
74
+ Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
76
75
  end
77
76
  end
78
77
  result
79
78
  end
79
+ # rubocop:enable Metrics/CyclomaticComplexity
80
80
 
81
81
  def trace_js_code_used(msg, js_code, file_name = "tmp/server-generated.js", force: false)
82
82
  return unless ReactOnRails.configuration.trace || force
@@ -52,6 +52,7 @@ module ReactOnRails
52
52
  # don't provide one.
53
53
  # webpack_generated_files List of files to check for up-to-date-status, defaulting to
54
54
  # webpack_generated_files in your configuration
55
+ # rubocop:disable Metrics/CyclomaticComplexity
55
56
  def self.ensure_assets_compiled(webpack_assets_status_checker: nil,
56
57
  webpack_assets_compiler: nil,
57
58
  source_path: nil,
@@ -96,4 +97,5 @@ module ReactOnRails
96
97
  ).call
97
98
  end
98
99
  end
100
+ # rubocop:enable Metrics/CyclomaticComplexity
99
101
  end
@@ -8,7 +8,7 @@ module ReactOnRails
8
8
  def compile_assets
9
9
  if ReactOnRails.configuration.build_test_command.blank?
10
10
  msg = <<~MSG
11
- You are using the React on Rails test helper.
11
+ You are using the React on Rails test helper.
12
12
  Either you used:
13
13
  ReactOnRails::TestHelper.configure_rspec_to_compile_assets or
14
14
  ReactOnRails::TestHelper.ensure_assets_compiled
@@ -34,7 +34,7 @@ module ReactOnRails
34
34
  end
35
35
 
36
36
  def self.object_to_boolean(value)
37
- [true, "true", "yes", 1, "1", "t"].include?(value.class == String ? value.downcase : value)
37
+ [true, "true", "yes", 1, "1", "t"].include?(value.instance_of?(String) ? value.downcase : value)
38
38
  end
39
39
 
40
40
  def self.server_rendering_is_enabled?
@@ -71,7 +71,11 @@ module ReactOnRails
71
71
  # 1. Using same bundle for both server and client, so server bundle will be hashed in manifest
72
72
  # 2. Using a different bundle (different Webpack config), so file is not hashed, and
73
73
  # bundle_js_path will throw so the default path is used without a hash.
74
- # 3. Not using webpacker, and this method returns the bundle_js_file_path
74
+ # 3. The third option of having the server bundle hashed and a different configuration than
75
+ # the client bundle is not supported for 2 reasons:
76
+ # a. The webpack manifest plugin would have a race condition where the same manifest.json
77
+ # is edited by both the webpack-dev-server
78
+ # b. There is no good reason to hash the server bundle name.
75
79
  return @server_bundle_path if @server_bundle_path && !Rails.env.development?
76
80
 
77
81
  bundle_name = ReactOnRails.configuration.server_bundle_js_file
@@ -114,9 +118,11 @@ module ReactOnRails
114
118
  end
115
119
  end
116
120
 
121
+ # rubocop:disable Naming/VariableNumber
117
122
  def self.rails_version_less_than_4_1_1
118
123
  rails_version_less_than("4.1.1")
119
124
  end
125
+ # rubocop:enable Naming/VariableNumber
120
126
 
121
127
  module Required
122
128
  def required(arg_name)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "12.0.0"
4
+ VERSION = "12.0.4"
5
5
  end
@@ -28,10 +28,10 @@ module ReactOnRails
28
28
  # Next line will throw if the file or manifest does not exist
29
29
  hashed_bundle_name = Webpacker.manifest.lookup!(bundle_name)
30
30
 
31
- # support for hashing the server-bundle and having that built
32
- # by a webpack watch process and not served by the webpack-dev-server, then we
33
- # need an extra config value "same_bundle_for_client_and_server" where a value of false
34
- # would mean that the bundle is created by a separate webpack watch process.
31
+ # Support for hashing the server-bundle and having that built
32
+ # the webpack-dev-server is provided by the config value
33
+ # "same_bundle_for_client_and_server" where a value of true
34
+ # would mean that the bundle is created by the webpack-dev-server
35
35
  is_server_bundle = bundle_name == ReactOnRails.configuration.server_bundle_js_file
36
36
 
37
37
  if Webpacker.dev_server.running? && (!is_server_bundle ||
@@ -13,26 +13,37 @@ unless ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
13
13
  # the build command.
14
14
  ENV["WEBPACKER_PRECOMPILE"] = "false"
15
15
 
16
+ precompile_tasks = lambda {
17
+ Rake::Task["react_on_rails:assets:webpack"].invoke
18
+ puts "Invoking task webpacker:clean from React on Rails"
19
+
20
+ # VERSIONS is per the rails/webpacker clean method definition.
21
+ # We set it very big so that it is not used, and then clean just
22
+ # removes files older than 1 hour.
23
+ versions = 100_000
24
+ Rake::Task["webpacker:clean"].invoke(versions)
25
+ }
26
+
16
27
  if Rake::Task.task_defined?("assets:precompile")
17
28
  Rake::Task["assets:precompile"].enhance do
18
- Rake::Task["react_on_rails:assets:webpack"].invoke
19
- puts "Invoking task webpacker:clean from React on Rails"
20
- Rake::Task["webpacker:clean"].invoke
29
+ precompile_tasks.call
21
30
  end
22
31
  else
23
- Rake::Task.define_task("assets:precompile" => ["react_on_rails:assets:webpack",
24
- "webpacker:clean"])
32
+ Rake::Task.define_task("assets:precompile") do
33
+ precompile_tasks.call
34
+ end
25
35
  end
26
36
  end
27
37
 
28
38
  # Sprockets independent tasks
39
+ # rubocop:disable Metrics/BlockLength
29
40
  namespace :react_on_rails do
30
41
  namespace :assets do
31
42
  desc <<-DESC.strip_heredoc
32
- Compile assets with webpack
33
- Uses command defined with ReactOnRails.configuration.build_production_command
34
- sh "#{ReactOnRails::Utils.prepend_cd_node_modules_directory('<ReactOnRails.configuration.build_production_command>')}"
35
- Note: This command is not automatically added to assets:precompile if the rails/webpacker
43
+ Compile assets with webpack
44
+ Uses command defined with ReactOnRails.configuration.build_production_command
45
+ sh "#{ReactOnRails::Utils.prepend_cd_node_modules_directory('<ReactOnRails.configuration.build_production_command>')}"
46
+ Note: This command is not automatically added to assets:precompile if the rails/webpacker
36
47
  configuration file config/webpack/production.js exists.
37
48
  DESC
38
49
  task webpack: :locale do
@@ -55,3 +66,4 @@ namespace :react_on_rails do
55
66
  end
56
67
  end
57
68
  end
69
+ # rubocop:enable Metrics/BlockLength
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-on-rails",
3
- "version": "12.0.0",
3
+ "version": "12.0.4",
4
4
  "description": "react-on-rails JavaScript for react_on_rails Ruby gem",
5
5
  "main": "node_package/lib/ReactOnRails.js",
6
6
  "directories": {
@@ -6,11 +6,6 @@ namespace :docker do
6
6
  sh "docker-compose run lint rake lint:rubocop"
7
7
  end
8
8
 
9
- desc "Run ruby-lint linter from docker"
10
- task :ruby do
11
- sh "docker-compose run lint rake lint:ruby"
12
- end
13
-
14
9
  desc "Run scss-lint linter from docker"
15
10
  task :scss do
16
11
  sh "docker-compose run lint rake lint:scss"
@@ -6,7 +6,7 @@
6
6
  # Also see example_type.rb
7
7
 
8
8
  require "yaml"
9
- require 'rails/version'
9
+ require "rails/version"
10
10
 
11
11
  require_relative "example_type"
12
12
  require_relative "task_helpers"
@@ -2,18 +2,12 @@
2
2
 
3
3
  require_relative "task_helpers"
4
4
 
5
- namespace :lint do # rubocop:disable Metrics/BlockLength
5
+ namespace :lint do
6
6
  include ReactOnRails::TaskHelpers
7
7
 
8
8
  desc "Run Rubocop as shell"
9
9
  task :rubocop do
10
- sh_in_dir(gem_root, "bundle exec rubocop .")
11
- end
12
-
13
- desc "Run ruby-lint as shell"
14
- task :ruby do
15
- puts "See /ruby-lint.yml for what directories are included."
16
- sh_in_dir(gem_root, "bundle exec ruby-lint .")
10
+ sh_in_dir(gem_root, "bundle exec rubocop --version", "bundle exec rubocop .")
17
11
  end
18
12
 
19
13
  desc "Run scss-lint as shell"
@@ -23,10 +17,10 @@ namespace :lint do # rubocop:disable Metrics/BlockLength
23
17
 
24
18
  desc "Run eslint as shell"
25
19
  task :eslint do
26
- sh_in_dir(gem_root, "yarn run eslint")
20
+ sh_in_dir(gem_root, "yarn run eslint --version", "yarn run eslint .")
27
21
  end
28
22
 
29
- desc "Run all eslint & rubocop linters. Skip ruby-lint and scss"
23
+ desc "Run all eslint & rubocop linters. Skip scss"
30
24
  task lint: %i[eslint rubocop] do
31
25
  puts "Completed all linting"
32
26
  end
@@ -4,6 +4,13 @@ require_relative "task_helpers"
4
4
  require_relative File.join(gem_root, "lib", "react_on_rails", "version_syntax_converter")
5
5
  require_relative File.join(gem_root, "lib", "react_on_rails", "git_utils")
6
6
  require_relative File.join(gem_root, "lib", "react_on_rails", "utils")
7
+
8
+ class RaisingMessageHandler
9
+ def add_error(error)
10
+ raise error
11
+ end
12
+ end
13
+
7
14
  desc("Releases both the gem and node package using the given version.
8
15
 
9
16
  IMPORTANT: the gem version must be in valid rubygem format (no dashes).
@@ -19,19 +26,11 @@ which are installed via `bundle install` and `yarn`
19
26
  2nd argument: Perform a dry run by passing 'true' as a second argument.
20
27
 
21
28
  Example: `rake release[2.1.0,false]`")
22
-
23
- # rubocop:disable Metrics/BlockLength
24
29
  task :release, %i[gem_version dry_run tools_install] do |_t, args|
25
30
  include ReactOnRails::TaskHelpers
26
31
 
27
- class MessageHandler
28
- def add_error(error)
29
- raise error
30
- end
31
- end
32
-
33
32
  # Check if there are uncommited changes
34
- ReactOnRails::GitUtils.uncommitted_changes?(MessageHandler.new)
33
+ ReactOnRails::GitUtils.uncommitted_changes?(RaisingMessageHandler.new)
35
34
  args_hash = args.to_hash
36
35
 
37
36
  is_dry_run = ReactOnRails::Utils.object_to_boolean(args_hash[:dry_run])
@@ -67,8 +66,5 @@ task :release, %i[gem_version dry_run tools_install] do |_t, args|
67
66
  sh_in_dir(gem_root, release_it_command)
68
67
 
69
68
  # Release the new gem version
70
- unless is_dry_run
71
- sh_in_dir(gem_root, "gem release")
72
- end
69
+ sh_in_dir(gem_root, "gem release") unless is_dry_run
73
70
  end
74
- # rubocop:enable Metrics/BlockLength
@@ -86,16 +86,15 @@ task run_rspec: ["run_rspec:run_rspec"]
86
86
  private
87
87
 
88
88
  def calc_path(dir)
89
- path = if dir.is_a?(String)
90
- if dir.start_with?(File::SEPARATOR)
91
- Pathname.new(dir)
92
- else
93
- Pathname.new(File.join(gem_root, dir))
94
- end
95
- else
96
- dir
97
- end
98
- path
89
+ if dir.is_a?(String)
90
+ if dir.start_with?(File::SEPARATOR)
91
+ Pathname.new(dir)
92
+ else
93
+ Pathname.new(File.join(gem_root, dir))
94
+ end
95
+ else
96
+ dir
97
+ end
99
98
  end
100
99
 
101
100
  # Runs rspec in the given directory.