rspec / rspec-expectations

Provides a readable API to express expected outcomes of a code example
https://rspec.info
MIT License
1.26k stars 397 forks source link

Namespace code block to work around name collisions #820

Open maxmeyer opened 9 years ago

maxmeyer commented 9 years ago

@myronmarston @JonRowe Does it make sense to have some like this:

Then /^the following files should (not )?exist:$/ do |negated, files|
  files = files.rows.flatten

  RSpec::Matchers.scope do
    if negated
      expect(files).not_to include an_existing_file
    else
      expect(files).to all be_an_existing_file
    end
  end
end

to make a method resolved to RSpec''s one instead some other conflicting method, e.g. from Capybara?

Referencing jnicklas/capybara#1396, jnicklas/capybara#1547, jnicklas/capybara#1526 here.

myronmarston commented 9 years ago

That looks like a pretty reasonable solution, although I'm not particularly happy with scope as the method name. Can't think of a better one, though.

Want to take a stab at implementing it?

maxmeyer commented 9 years ago

Want to take a stab at implementing it?

No. The last time I did such "a job" it took me too much time and I must admit I would like work more on aruba and help others like you to get started with the new version. Would you mind to hack down that thing?

Can't think of a better one, though.

I can think of .domain or .realm

maxmeyer commented 9 years ago

Can it be that simple?

require 'rspec/expectations'

module RSpec
  class Scope
    include RSpec::Matchers
  end

  def self.scope(&block)
    Scope.new.instance_eval(&block)
  end
end
JonRowe commented 9 years ago

That's approximately what I'd try, write some tests, and only then if that failed would I start mucking with bindings.

ghost commented 9 years ago

@JonRowe @myronmarston

I played around with some code more or less similar to the one above in aruba. If I'm not totally wrong I cannot re-use the outer context with it, so using code like this all over aruba would mean our users need to change all steps defined to use our "new" aruba_scope-method. Nothing I'm happy about.

Some time ago I got in touch with Go. They use a Module-name before each "external" method. Would you guy support/implement such a pattern making all matchers available as module-methods of RSpec::Matchers? I know I can do this for aruba with a single module, but maybe this can be a way for others as well to work around name collisions.

Something like this:

it { expect([true, true]).to RSpec::Matchers.all be true }

This would mean no problem with bindings etc.

JonRowe commented 9 years ago

Makes for pretty ugly reading though... I prefer the original solution for RSpec really

ghost commented 9 years ago

Makes for pretty ugly reading though... I prefer the original solution for RSpec really

Ok. I can understand that. For aruba I chose the module "version", because otherwise this would "break" our cucumber API.