File: exist_spec.rb

package info (click to toggle)
ruby-rspec 3.13.0c0e0m0s1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,856 kB
  • sloc: ruby: 70,868; sh: 1,423; makefile: 99
file content (159 lines) | stat: -rw-r--r-- 4,499 bytes parent folder | download
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