Astery
Astery

Reputation: 1256

How to require file from `gem` which are not under `lib` directory?

I want to write spec for my rubocop custom cop. This gem has handy helpers defined here. I want to require it. How to achieve what?

I've tried to use Gem.find_files, and this gives me ability to require any file in that gem, but only under lib directory.

For example:

# this requires ...gems/rubocop-0.29.1/lib/rubocop/formatter/formatter_set.rb
require Gem.find_files('rubocop/formatter/formatter_set.rb').first
# but I need ...gems/rubocop-0.29.1/spec/support/cop_helper.rb

The following describes why I need it. I have spec/rubocop/my_custom_cop_spec.rb

require 'spec_helper'
require ? # What I should I write?

RSpec.describe RuboCop::Cop::Style::MyCustomCop do
  it 'some test' do
    inspect_source(cop, 'method(arg1, arg2)') # This helper I want to use from rubocop spec helpers
  end
end

When I try plain require:

require 'rubocop/spec/support/cop_helper'

I receive error:

/home/user/.gem/ruby/2.0.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274
:in `require': cannot load such file -- rubocop/spec/support/cop_helper

Upvotes: 11

Views: 6243

Answers (3)

Artur INTECH
Artur INTECH

Reputation: 7396

gem_root_dir = Gem.loaded_specs['gem_name'].full_gem_path
require File.join(gem_root_dir, 'spec')

Note that there is no hardcoded path separator unlike the example in the accepted answer, which is better for portability and readability.

Upvotes: 0

ledhed2222
ledhed2222

Reputation: 715

I found a solution that I think is a little more syntactically elegant:

gem_dir = Gem::Specification.find_by_name("my_gem").gem_dir
require "#{gem_dir}/spec"

Upvotes: 27

Astery
Astery

Reputation: 1256

I was so blinded, I already have path to file and able to get relative from it.

require 'pathname'
rubocop_path = Pathname.new(Gem.find_files('rubocop.rb').first).dirname
rubocop_path # => ...gems/rubocop-0.29.1/lib
require "#{rubocop_path}/../spec/support/cop_helper.rb"

Upvotes: 5

Related Questions