summaryrefslogtreecommitdiff
path: root/spec/hashie/extensions/deep_locate_spec.rb
blob: e104e76289edf00e758789267d29d3e0a6416be6 (plain)
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
require 'spec_helper'

describe Hashie::Extensions::DeepLocate do
  let(:hash) do
    {
      from: 0,
      size: 25,
      query: {
        bool: {
          must: [
            {
              query_string: {
                query: 'foobar',
                default_operator: 'AND',
                fields: [
                  'title^2',
                  '_all'
                ]
              }
            },
            {
              match: {
                field_1: 'value_1'
              }
            },
            {
              range: {
                lsr09: {
                  gte: 2014
                }
              }
            }
          ],
          should: [
            {
              match: {
                field_2: 'value_2'
              }
            }
          ],
          must_not: [
            {
              range: {
                lsr10: {
                  gte: 2014
                }
              }
            }
          ]
        }
      }
    }
  end

  describe '.deep_locate' do
    context 'if called with a non-callable comparator' do
      it 'creates a key comparator on-th-fly' do
        expect(described_class.deep_locate(:lsr10, hash))
          .to eq([hash[:query][:bool][:must_not][0][:range]])
      end
    end

    it 'locates enumerables for which the given comparator returns true for at least one element' do
      examples = [
        [
          ->(key, _value, _object) { key == :fields },
          [
            hash[:query][:bool][:must].first[:query_string]
          ]
        ],
        [
          ->(_key, value, _object) { value.is_a?(String) && value.include?('value') },
          [
            hash[:query][:bool][:must][1][:match],
            hash[:query][:bool][:should][0][:match]
          ]
        ],
        [
          lambda do |_key, _value, object|
            object.is_a?(Array) &&
              !object.extend(described_class).deep_locate(:match).empty?
          end,
          [
            hash[:query][:bool][:must],
            hash[:query][:bool][:should]
          ]
        ]
      ]

      examples.each do |comparator, expected_result|
        expect(described_class.deep_locate(comparator, hash)).to eq(expected_result)
      end
    end

    it 'returns an empty array if nothing was found' do
      expect(described_class.deep_locate(:muff, foo: 'bar')).to eq([])
    end
  end

  context 'if extending an existing object' do
    let(:extended_hash) do
      hash.extend(described_class)
    end

    it 'adds #deep_locate' do
      expect(extended_hash.deep_locate(:bool)).to eq([hash[:query]])
    end
  end

  context 'if included in a hash' do
    let(:derived_hash_with_extension_included) do
      Class.new(Hash) do
        include Hashie::Extensions::DeepLocate
      end
    end

    let(:instance) do
      derived_hash_with_extension_included.new.update(hash)
    end

    it 'adds #deep_locate' do
      expect(instance.deep_locate(:bool)).to eq([hash[:query]])
    end
  end
end