Class: NoBrainer::Matchers::HaveIndexFor

Inherits:
Object
  • Object
show all
Defined in:
lib/matchers/have_index_for.rb

Overview

The ‘have_index_for` matcher tests that the table that backs your model has a specific index.

class User
  include NoBrainer::Document

  field :name, index: true
  field :lastname

  index :lastname
end

# RSpec
RSpec.describe User, type: :model do
  it { is_expected.to have_index_for(:name) }
  it { is_expected.to have_index_for(:lastname) }
end

#### Qualifiers

##### with_multi

Use ‘with_multi` to assert that an index is defined as multi for a certain field.

class User
  include NoBrainer::Document

  field :name, index: :multi
  field :lastname

  index :lastname, multi: true
end

# RSpec
RSpec.describe User, type: :model do
  it do
    it { is_expected.to have_index_for(:name).with_multi }
    it { is_expected.to have_index_for(:lastname).with_multi }
  end
end

##### named

Use ‘named` to assert that an index has a certain name.

class User
  include NoBrainer::Document

  field :firstname
  field :lastname

  index :full_name_compound, %i[firstname lastname]
end

# RSpec
RSpec.describe User, type: :model do
  it do
    is_expected.to have_index_for(%i[firstname lastname])
      .named(:full_name_compound)
  end
end

Instance Method Summary collapse

Constructor Details

#initialize(*attrs) ⇒ HaveIndexFor

:nodoc:



69
70
71
72
73
74
75
76
77
# File 'lib/matchers/have_index_for.rb', line 69

def initialize(*attrs)
  @attributes = attrs.collect do |attributes|
    if attributes.is_a?(Enumerable)
      attributes.collect(&:to_sym)
    else
      attributes.to_sym
    end
  end
end

Instance Method Details

#descriptionObject



152
153
154
155
156
157
# File 'lib/matchers/have_index_for.rb', line 152

def description
  desc = "have index for #{@attributes.collect(&:inspect).to_sentence}"
  desc += ' to be multi' if @multi
  desc += " named #{@index_name}" if @index_name
  desc
end

#failure_message_for_shouldObject Also known as: failure_message



141
142
143
# File 'lib/matchers/have_index_for.rb', line 141

def failure_message_for_should
  "Expected #{@klass.inspect} to #{description}, got #{@errors.to_sentence}"
end

#failure_message_for_should_notObject Also known as: failure_message_when_negated



145
146
147
# File 'lib/matchers/have_index_for.rb', line 145

def failure_message_for_should_not
  "Expected #{@klass.inspect} to not #{description}, got #{@klass.inspect} to #{description}"
end

#matches?(klass) ⇒ Boolean

Returns:

  • (Boolean)


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
# File 'lib/matchers/have_index_for.rb', line 89

def matches?(klass)
  @klass = klass.is_a?(Class) ? klass : klass.class
  @errors = []
  @attributes.each do |attr|
    if attr.is_a?(Enumerable)
      missing_fields = attr - @klass.fields.keys
      if missing_fields.empty?
        index_key = @index_name || attr.join('_').to_sym
        if @klass.indexes.include?(index_key)
          error = ''

          # Checking multi
          if @multi && (@klass.indexes[index_key][:multi] != @multi)
            error += " with multi #{@klass.indexes[index_key][:multi].inspect}"
          end

          @errors.push("field #{attr.inspect}" + error) unless error.blank?
        else
          if @index_name
            @errors.push "no compound index named #{@index_name}"
          else
            @errors.push "no compound index for fields #{attr.to_sentence}"
          end
        end
      else
        @errors.push "the field#{'s' if missing_fields.size > 1} " \
                     "#{missing_fields.to_sentence} " \
                     "#{missing_fields.size > 1 ? 'are' : 'is'} missing"
      end
    else
      if @klass.fields.include?(attr)
        if @klass.indexes.include?(attr)
          error = ''

          # Checking multi
          if @multi && (@klass.indexes[attr][:multi] != @multi)
            error += " with multi #{@klass.indexes[attr][:multi].inspect}"
          end

          @errors.push("field #{attr.inspect}" + error) unless error.blank?

        else
          @errors.push "no index for field #{attr.inspect}"
        end
      else
        @errors.push "no field named #{attr.inspect}"
      end
    end
  end
  @errors.empty?
end

#named(index_name) ⇒ Object



84
85
86
87
# File 'lib/matchers/have_index_for.rb', line 84

def named(index_name)
  @index_name = index_name
  self
end

#with_multi(multi = true) ⇒ Object



79
80
81
82
# File 'lib/matchers/have_index_for.rb', line 79

def with_multi(multi = true)
  @multi = multi
  self
end