1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
RSpec.describe "exist matcher" do
it_behaves_like "an RSpec value matcher", :valid_value => Class.new { def exist?; true; end }.new,
:invalid_value => Class.new { def exist?; false; end }.new do
let(:matcher) { exist }
end
context "when the object does not respond to #exist? or #exists?" do
subject { double }
[:to, :not_to].each do |expect_method|
describe "expect(...).#{expect_method} exist" do
it "fails" do
expect {
expect(subject).send(expect_method, exist)
}.to fail_including("it does not respond to either `exist?` or `exists?`")
end
end
end
end
it 'composes gracefully' do
expect([
double,
double(:exists? => false),
double(:exists? => true),
]).to include existing
end
[:exist?, :exists?].each do |predicate|
context "when the object responds to ##{predicate}" do
describe "expect(...).to exist" do
it "passes if #{predicate}" do
expect(double(predicate => true)).to exist
end
it "fails if not #{predicate}" do
expect {
expect(double(predicate => false)).to exist
}.to fail_with(/expected .* to exist/)
end
it 'works when the object overrides `send`' do
klass = Struct.new(:message) do
def send
:message_sent
end
define_method predicate do
true
end
end
expect(klass.new("msg")).to exist
end
end
describe "expect(...).not_to exist" do
it "passes if not #{predicate}" do
expect(double(predicate => false)).not_to exist
end
it "fails if #{predicate}" do
expect {
expect(double(predicate => true)).not_to exist
}.to fail_with(/expected .* not to exist/)
end
end
end
end
context "when the object responds to #exist? and #exists?" do
context "when they both return falsey values" do
subject { double(:exist? => false, :exists? => nil) }
describe "expect(...).not_to exist" do
it "passes" do
expect(subject).not_to exist
end
end
describe "expect(...).to exist" do
it "fails" do
expect {
expect(subject).to exist
}.to fail_with(/expected .* to exist/)
end
end
end
context "when they both return truthy values" do
subject { double(:exist? => true, :exists? => "something true") }
describe "expect(...).not_to exist" do
it "fails" do
expect {
expect(subject).not_to exist
}.to fail_with(/expected .* not to exist/)
end
end
describe "expect(...).to exist" do
it "passes" do
expect(subject).to exist
end
end
end
context "when they return values with different truthiness" do
subject { double(:exist? => true, :exists? => false) }
[:to, :not_to].each do |expect_method|
describe "expect(...).#{expect_method} exist" do
it "fails" do
expect {
expect(subject).send(expect_method, exist)
}.to fail_including("`exist?` and `exists?` returned different values")
end
end
end
end
context "when one predicate is deprecated" do
context 'File has deprecated exists?' do
it 'will not call exists? triggering the warning' do
expect(File).to exist __FILE__
end
end
context 'FileTest has deprecated exists?' do
it 'will not call exists? triggering the warning' do
expect(FileTest).to exist __FILE__
end
end
if RUBY_VERSION > "1.9"
context 'Dir has deprecated exists?' do
it 'will not call exists? triggering the warning' do
expect(Dir).to exist Dir.pwd
end
end
end
end
end
it 'passes any provided arguments to the call to #exist?' do
object = double
expect(object).to receive(:exist?).with(:foo, :bar) { true }.at_least(:once)
expect(object).to exist(:foo, :bar)
end
it 'memoizes the call to `exist?` because it can be expensive (such as doing a DB query)' do
object = double
allow(object).to receive(:exist?) { false }
expect { expect(object).to exist }.to fail
expect(object).to have_received(:exist?).once
end
end
|