rspec / rspec-its Goto Github PK
View Code? Open in Web Editor NEW`its` for RSpec 3 extracted from rspec-core 2.x
License: MIT License
`its` for RSpec 3 extracted from rspec-core 2.x
License: MIT License
Judging by a few hints, I am unsure if using the its
syntax is still recommended or not.
I wonder if its
is in the same bucket as shoulda matchers - existing for backwards compatibility, and for older code bases.
The hints I am seeing:
Would love to have some "official" word on this from people in the inner rspec circle, or to be referred to an existing up to date rspec page that clearly states either way.
I'm currently trying to switch from RSpec 2.99.0 to 3.0.0. I really like its
and therefore want to continue using it and included this gem as a consequence. This unfortunately doesn't work for me though. The project is open source, so you can see the results on Travis.
With RSpec 2.99.0 everything runs without any deprecation warnings, see the logs here. As soon as I switch to 3.0.0, the build will break with the following errors for its
blocks:
Failure/Error: Unable to find matching line from backtrace
The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
See the build log here.
According to rspec 3.x documentation, **described_class ** will be the class of the describe parameter, as long as it is no string. Hence subject will provide an instance of this class.
When using its, however, described_class and subject change to the parameter provided as the parameter to its. So any initialization in a before block on the subject causes a failure as the subject is not the described class anymore which I would expect.
Here an example:
require 'rspec/its'
describe Array do
describe '#empty' do
it { expect(subject).to eq([]) }
it { should be_empty}
its(:empty?) { should be true }
end
end
I would expect to get all the specs passed. However, its(:empty?) fails with:
1) Array#empty empty? should equal true
Failure/Error: its(:empty?) { should be true }
expected true
got false
The reason becomes clear with this block:
before { p subject.class }
This will show that subject is a Symbol, not an Array.
To fix this, the describe block defined in method its should not take the attribute itself, but it should rather call to_s or inspect on it.
I plan to release RSpec 3 tomorrow. I noticed there are unreleased commits here but they don't appear to touch any of the actual lib code so I don't think a release is necessarily needed. Wanted to let you know, though @palfvin. (Feel free to close this).
This gem depends on rspec-core but doesn't advertise as such in the gemspec. This should be fixed.
@palfvin, can you cut a new release in the next day or two? We're aiming for sunday night for a rspec 3.0.0.beta2 release, and it would be great to have this out first.
As of the current RSpec 3, execution_result no longer returns a hash. An rspec test is failing as a result. []
is still supported, but is deprecated in favor of accessor methods.
`require 'rails_helper'
RSpec.describe Session, type: :model do
subject { create :session } # or subject! no dif
its(:expire) { should eq(1) } # value nil
its([:expire]) { should eq(1) } # proper value
end`
If it is not a bug, my apologies, maybe it's my lack of knowledge
11: its(:label) { should eq 'Creator' }
rspec spec/my_spec.rb:11
All examples were filtered out
Finished in 0.00029 seconds (files took 4.64 seconds to load)
0 examples, 0 failures
When I run the rails console in my development environment, I get a warning saying irb: warn: can't alias context from irb_context.
I've isolated it to this gem (currently running 1.3.0). I'm guessing this is related to this previously resolved issue from rspec-rails:
The wrapper class here is a quick example of the behavior. While the example does not use the timeout
library methods it is present in a larger project I am currently working on.
Given this yaml file:
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
And a test file:
require 'ostruct'
require 'yaml'
require 'timeout'
require 'rspec/its'
class DatabaseConfg
def development
hash = YAML.load(File.read('database.yml'))
struct = OpenStruct.new(hash['development'])
end
end
describe DatabaseConfg do
its('development.database') { should eq 'db/development.sqlite3' }
its('development.timeout') { should eq 5000 }
end
When I execute the tests I see an error that is the same error if you ran timeout
without any parameters
$ rspec example_spec.rb
./usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rspec-its-1.2.0/lib/rspec/its.rb:115:in `block (3 levels) in its': Object#timeout is deprecated, use Timeout.timeout instead.
F
Failures:
1) DatabaseConfg development.timeout
Failure/Error: its('development.timeout') { should eq 5000 }
ArgumentError:
wrong number of arguments (given 0, expected 1..3)
# ./rspec_example_spec.rb:15:in `block (2 levels) in <top (required)>'
Finished in 0.00413 seconds (files took 0.13378 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./rspec_example_spec.rb:15 # DatabaseConfg development.timeout
When the subject is a BasicObject
(which of course doesn't have respond_to?
, is_a?
and others) then RSpec (or rspec/its) cannot generate the test description.
Example code:
class Foo <BasicObject
def name; 'hello'; end
end
RSpec.describe Foo do
its(:name) { is_expected.to eq 'hello' }
end
This generates output similar to:
example at .<spec file>:10 (Got an error when generating description from matcher: NoMethodError: undefined method `is_a?' for #<Foo:0x007fcd4c3bd938> -- /.../ruby-2.4.1/gems/activesupport-5.1.4/lib/active_support/core_ext/time/calculations.rb:16:in `===')
I'm not sure of there's the "right" way to fix this as it is not even possible to use respond_to?
on the BasicObject.
But worth raising this.
I've deprecated should
and should_not
in a fork (ennova@61f5950) for use by our company. If anyone would like me to make this configurable and add it to the main gem I'd be happy too. If not feel free to close this issue.
Before I implement this, I should ask - would you accept a patch that passes arguments to the method?
subject { MathExample.new }
describe '#root' do
its(:root, 9) { should == 3 }
its(:root, 16) { should == 4 }
end
What do you think? Is this against the philosophy of the simplicity and readability of its
? This is a short example, but I find myself wanting to do this where I have lots of short examples with different fixed inputs to a method. This is a lot more concise than the alternative:
subject(:math) { MathExample.new }
describe '#root' do
it 'finds the square root of 9' do
expect(math).root(9).to eq 3
end
it 'finds the square root of 16' do
expect(math).root(16).to eq 4
end
end
is_expected
is new in rspec-core:
It doesn't work with rspec-its right now. @palfvin, can you work on fixing that?
I was trying to use 'its' syntax for expecting exceptions:
4: class Subject
5: def some_method
6: raise Exception
7: end
8: end
9:
10: describe Subject do
11: it { expect { subject.some_method }.to raise_error Exception }
12: its(:some_method) { is_expected.to raise_error Exception }
13: its(:some_method) { should raise_error Exception }
14: end
I expected all three tests to succeed, however:
.FF
Failures:
1) Subject some_method
Failure/Error: raise Exception
Exception:
Exception
# ./exception.rb:6:in `some_method'
# ./exception.rb:12:in `block (2 levels) in <top (required)>'
2) Subject some_method
Failure/Error: raise Exception
Exception:
Exception
# ./exception.rb:6:in `some_method'
# ./exception.rb:13:in `block (2 levels) in <top (required)>'
Finished in 0.0014 seconds (files took 0.07659 seconds to load)
3 examples, 2 failures
Failed examples:
rspec ./exception.rb:12 # Subject some_method
rspec ./exception.rb:13 # Subject some_method
Rails 5.2
Using rspec-support 3.12.1
Using rspec-core 3.12.2
Using rspec-expectations 3.12.3
Using rspec-mocks 3.12.6
Using rspec 3.12.0
Using rspec-html-matchers 0.10.0
Using rspec-its 1.3.0
Using rspec-rails 4.0.1
When using []
for accessing hash-subject attributes
Failure/Error: its([:amount]) { is_expected.to eq(1)}
ArgumentError:
wrong number of arguments (given 2, expected 3..5)
https://github.com/rspec/rspec-its/blob/main/lib/rspec/its.rb#L169
I just found that rspec-its
is able to call private getters on subject, this is probably not intentional and a side effect from using Object#send
instead of Object#public_send
.
Line 115 in 38fdc24
The documentation implies that I should be able to do something like this:
subject { true }
its(:nil?, pending: 'forever') { should be_truthy }
…and have the example marked as pending. But the :pending
seems to be silently ignored in every its
I have written.
In Gemfile:
rspec-rails (>= 3.2.0) ruby depends on
rspec-core (~> 3.2.0) ruby
rspec-its (>= 1.2.0) ruby depends on
rspec-core (3.1.7)
See rspec/rspec-collection_matchers#12 for some prior art here.
/cc @palfvin
This block will fail:
describe 'first driver' do
subject { driver_commissions.first }
its(:keys) { are_expected.to eq([:driver_id,
:backhauls,
:freight_revenue,
:customer_id,
:delivery_date,
:driver_rate,
:freight_bill_number,
:fuel_surcharge])}
end
Rspec
1) DriverCommissionHistoryAdapter#all first driver keys
Failure/Error: its(:keys) { are_expected.to eq([:driver_id,
NameError:
undefined local variable or method `are_expected' for #<RSpec::ExampleGroups::DriverCommissionHistoryAdapter::All::FirstDriver::Keys:0x3fbc5ebf>
# ./spec/models/driver_commission_history_adapter_spec.rb:20:in `(root)'
This block will succeed:
describe 'first driver' do
subject { driver_commissions.first }
its(:keys) { is_expected.to eq([:driver_id,
:backhauls,
:freight_revenue,
:customer_id,
:delivery_date,
:driver_rate,
:freight_bill_number,
:fuel_surcharge])}
end
Rspec
....................
Finished in 9.47 seconds (files took 4.72 seconds to load)
20 examples, 0 failures
How about support for nested hashes like:
its([:key, :deep, :down, :below]) { … }
for hashes like
{key: {deep: {down: {below: "value"}}}}
The link is: https://relishapp.com/palfvin/rspec-its/docs/attribute-of-subject
Not sure where it's supposed to point to.
Regards,
iain
Hi,
When I use InSpec's parse_config_file
resource to verify the content of an ini-like config file structured like so:
[beaver]
foo: baz
[/var/log/apache2/access.log]
bar: baz
And I have the following spec:
describe parse_config_file('/etc/beaver/beaver.conf', {
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
comment_character: '#'
}) do
its('beaver') {
should include('foo' => 'baz')
}
its('/var/log/apache2/access.log') {
should include('bar' => 'baz')
}
end
The following error occurs:
∅ undefined method `log' for nil:NilClass
I believe this is being caused by this line of code which is splitting the value by dot (.
):
https://github.com/rspec/rspec-its/blob/master/lib/rspec/its.rb#L113
This is effectively causing InSpec (and any other rspec
"wrapper" feeding that code path something which includes a dot) to break. Not being a core rspec
developer I'm not sure how I could contribute to solving this problem via Pull Requests etc.
Any advice would be much appreciated.
Thank you.
See rspec/rspec-core#1240, rspec/rspec-core#1403 and rspec/rspec-core#1405.
You'll probably have to apply a change similar to what was done to its
in 1405.
/cc @palfvin
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.