Module: Saharspec::Its::Map

Defined in:
lib/saharspec/its/map.rb

Instance Method Summary collapse

Instance Method Details

#its_map(attribute, *options, &block) ⇒ Object

Creates nested example which has current subject mapped by specified attribute as its subject.

Examples:


# with attribute
subject { %w[test me please] }
its_map(:length) { is_expected.to eq [4, 2, 6] }

# with attribute chain
its_map(:'reverse.upcase') { is_expected.to eq %w[TSET EM ESAELP] }

# with Hash (or any other object re sponding to `#[]`)
subject {
  [
    {title: 'Slaughterhouse Five', author: {first: 'Kurt', last: 'Vonnegut'}},
    {title: 'Hitchhickers Guide To The Galaxy', author: {first: 'Duglas', last: 'Adams'}}
  ]
}
its_map([:title]) { are_expected.to eq ['Slaughterhouse Five', 'Hitchhickers Guide To The Galaxy'] }
# multiple attributes for nested hashes
its_map([:author, :last]) { are_expected.to eq ['Vonnegut', 'Adams'] }


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
# File 'lib/saharspec/its/map.rb', line 33

def its_map(attribute, *options, &block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  # rubocop:disable Lint/NestedMethodDefinition
  describe("map(&:#{attribute})") do
    let(:__its_map_subject) do
      if Array === attribute # rubocop:disable Style/CaseEquality
        if subject.all? { |s| Hash === s } # rubocop:disable Style/CaseEquality
          subject.map do |s|
            attribute.inject(s) { |inner, attr| inner[attr] }
          end
        else
          subject.map { |inner| inner[*attribute] }
        end
      else
        attribute_chain = attribute.to_s.split('.').map(&:to_sym)
        attribute_chain.inject(subject) do |inner_subject, attr|
          inner_subject.map(&attr)
        end
      end
    end

    def is_expected
      expect(__its_map_subject)
    end

    alias_method :are_expected, :is_expected

    options << {} unless options.last.is_a?(Hash)

    example(nil, *options, &block)
  end
  # rubocop:enable Lint/NestedMethodDefinition
end