Class: FilterTable::Factory

Inherits:
Object
  • Object
show all
Defined in:
lib/utils/filter.rb

Defined Under Namespace

Classes: Connector

Instance Method Summary collapse

Constructor Details

#initializeFactory

Returns a new instance of Factory.



180
181
182
183
184
# File 'lib/utils/filter.rb', line 180

def initialize
  @accessors = []
  @connectors = {}
  @resource = nil
end

Instance Method Details

#add(method_name, opts = {}, &block) ⇒ Object



243
244
245
246
247
248
249
250
251
# File 'lib/utils/filter.rb', line 243

def add(method_name, opts = {}, &block)
  if method_name.nil?
    throw RuntimeError, "Called filter.add for resource #{@resource} with method name nil!"
  end

  @connectors[method_name.to_sym] =
    Connector.new(opts[:field] || method_name, block, opts)
  self
end

#add_accessor(method_name) ⇒ Object



235
236
237
238
239
240
241
# File 'lib/utils/filter.rb', line 235

def add_accessor(method_name)
  if method_name.nil?
    throw RuntimeError, "Called filter.add_delegator for resource #{@resource} with method name nil!"
  end
  @accessors.push(method_name)
  self
end

#connect(resource, table_accessor) ⇒ Object

rubocop:disable Metrics/AbcSize



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/utils/filter.rb', line 186

def connect(resource, table_accessor) # rubocop:disable Metrics/AbcSize
  # create the table structure
  connectors = @connectors
  struct_fields = connectors.values.map(&:field_name)
  connector_blocks = connectors.map do |method, c|
    [method.to_sym, create_connector(c)]
  end

  # the struct to hold single items from the #entries method
  entry_struct = Struct.new(*struct_fields.map(&:to_sym)) do
    attr_accessor :__filter
    def to_s
      @__filter || super
    end
  end unless struct_fields.empty?

  # the main filter table
  table = Class.new(Table) {
    connector_blocks.each do |x|
      define_method x[0], &x[1]
    end

    define_method :new_entry do |hashmap, filter = ''|
      return entry_struct.new if hashmap.nil?
      res = entry_struct.new(*struct_fields.map { |x| hashmap[x] })
      res.__filter = filter
      res
    end
  }

  # Define all access methods with the parent resource
  # These methods will be configured to return an `ExceptionCatcher` object
  # that will always return the original exception, but only when called
  # upon. This will allow method chains in `describe` statements to pass the
  # `instance_eval` when loaded and only throw-and-catch the exception when
  # the tests are run.
  accessors = @accessors + @connectors.keys
  accessors.each do |method_name|
    resource.send(:define_method, method_name.to_sym) do |*args, &block|
      begin
        filter = table.new(self, method(table_accessor).call, ' with')
        filter.method(method_name.to_sym).call(*args, &block)
      rescue Inspec::Exceptions::ResourceFailed, Inspec::Exceptions::ResourceSkipped => e
        FilterTable::ExceptionCatcher.new(resource, e)
      end
    end
  end
end