File: composable_spec.rb

package info (click to toggle)
ruby-rspec 3.5.0c3e0m0s0-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 6,312 kB
  • ctags: 4,788
  • sloc: ruby: 62,572; sh: 785; makefile: 100
file content (100 lines) | stat: -rw-r--r-- 3,403 bytes parent folder | download | duplicates (3)
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
module RSpec
  module Matchers
    RSpec.describe Composable do
      RSpec::Matchers.define :matcher_using_surface_descriptions_in do |expected|
        match { false }
        failure_message { surface_descriptions_in(expected).to_s }
      end

      it "does not blow up when surfacing descriptions from an unreadable IO object" do
        expect {
          expect(3).to matcher_using_surface_descriptions_in(STDOUT)
        }.to fail_with(STDOUT.inspect)
      end

      it "does not blow up when surfacing descriptions from an unreadable Range object" do
        infinity = (1.0/0.0)
        infinite_range = -infinity..infinity
        expect {
          expect(1).to matcher_using_surface_descriptions_in(infinite_range)
        }.to fail_with(infinite_range.inspect)
      end

      it "does not blow up when surfacing descriptions from an Enumerable object whose #each includes the object itself" do
        array = ['something']
        array << array
        expect {
          expect(1).to matcher_using_surface_descriptions_in(array)
        }.to fail_with(array.to_s)
      end

      it "does not enumerate normal ranges" do
        range = 1..3
        expect {
          expect(1).to matcher_using_surface_descriptions_in(range)
        }.to fail_with(range.inspect)
      end

      it "doesn't mangle struct descriptions" do
        model = Struct.new(:a).new(1)
        expect {
          expect(1).to matcher_using_surface_descriptions_in(model)
        }.to fail_with(model.inspect)
      end

      RSpec::Matchers.define :all_but_one do |matcher|
        match do |actual|
          match_count = actual.count { |v| values_match?(matcher, v) }
          actual.size == match_count + 1
        end
      end

      context "when using a matcher instance that memoizes state multiple times in a composed expression" do
        it "works properly in spite of the memoization" do
          expect(["foo", "bar", "a"]).to all_but_one(have_string_length(3))
        end

        context "when passing a compound expression" do
          it "works properly in spite of the memoization" do
            expect(["A", "AB", "ABC"]).to all_but_one(
                have_string_length(1).or have_string_length(2)
            )
          end
        end
      end

      describe "cloning data structures containing matchers" do
        include Composable

        it "clones only the contained matchers" do
          matcher_1   = eq(1)
          matcher_2   = eq(2)
          object      = Object.new
          uncloneable = nil

          data_structure = {
            "foo"  => matcher_1,
            "bar"  => [matcher_2, uncloneable],
            "bazz" => object
          }

          cloned = with_matchers_cloned(data_structure)
          expect(cloned).not_to equal(data_structure)

          expect(cloned["foo"]).to be_a_clone_of(matcher_1)
          expect(cloned["bar"].first).to be_a_clone_of(matcher_2)
          expect(cloned["bazz"]).to equal(object)
        end

        it "copies custom matchers properly so they can work even though they have singleton behavior" do
          expect("foo").to with_matchers_cloned(have_string_length 3)
        end

        it 'does not blow up when passed an array containing an IO object' do
          stdout = STDOUT
          expect(with_matchers_cloned([stdout]).first).to equal(stdout)
        end
      end
    end
  end
end