Class: GlueGun::DSL::DependencyBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/glue_gun/dsl.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component_type, options) ⇒ DependencyBuilder

Returns a new instance of DependencyBuilder.



326
327
328
329
330
331
332
333
# File 'lib/glue_gun/dsl.rb', line 326

def initialize(component_type, options)
  @component_type = component_type
  @option_configs = {}
  @default_option_name = nil
  @single_option = nil
  @is_only = false
  @lazy = options.key?(:lazy) ? options.dig(:lazy) : true
end

Instance Attribute Details

#component_typeObject (readonly)

Returns the value of attribute component_type.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def component_type
  @component_type
end

#factory_classObject (readonly)

Returns the value of attribute factory_class.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def factory_class
  @factory_class
end

#is_onlyObject (readonly)

Returns the value of attribute is_only.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def is_only
  @is_only
end

#lazyObject (readonly)

Returns the value of attribute lazy.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def lazy
  @lazy
end

#option_configsObject (readonly)

Returns the value of attribute option_configs.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def option_configs
  @option_configs
end

#parentObject (readonly)

Returns the value of attribute parent.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def parent
  @parent
end

#when_blockObject (readonly)

Returns the value of attribute when_block.



324
325
326
# File 'lib/glue_gun/dsl.rb', line 324

def when_block
  @when_block
end

Instance Method Details

#allowed_classesObject



357
358
359
# File 'lib/glue_gun/dsl.rb', line 357

def allowed_classes
  get_option_configs.values
end

#allowed_configurationsObject



353
354
355
# File 'lib/glue_gun/dsl.rb', line 353

def allowed_configurations
  get_option_configs.keys
end

#bind_attribute(name, default: nil, required: false, source: nil, &block) ⇒ Object



506
507
508
# File 'lib/glue_gun/dsl.rb', line 506

def bind_attribute(name, default: nil, required: false, source: nil, &block)
  single_option.bind_attribute(name, default: default, required: required, source: source, &block)
end

#build_dependency_attributes(option_config, dep_attributes, parent) ⇒ Object



418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/glue_gun/dsl.rb', line 418

def build_dependency_attributes(option_config, dep_attributes, parent)
  option_config.attributes.each do |attr_name, attr_config|
    if dep_attributes.key?(attr_name)
      dep_attributes[attr_name]
    else
      value = if attr_config.source && parent.respond_to?(attr_config.source)
                parent.send(attr_config.source)
              elsif parent.respond_to?(attr_name)
                parent.send(attr_name)
              else
                attr_config.default
              end
      value = attr_config.process_value(value, self) if attr_config.respond_to?(:process_value)
      dep_attributes[attr_name] = value
    end
  end

  dep_attributes.deep_compact
end

#builderObject



339
340
341
342
343
344
345
346
347
# File 'lib/glue_gun/dsl.rb', line 339

def builder
  if factory?
    factory_instance = factory_class.new
    dep_defs = factory_instance.dependency_definitions
    dep_defs[dep_defs.keys.first]
  else
    self
  end
end

#builder?Boolean

Returns:

  • (Boolean)


365
366
367
# File 'lib/glue_gun/dsl.rb', line 365

def builder?
  !factory?
end

#default_option_nameObject



522
523
524
525
526
527
528
# File 'lib/glue_gun/dsl.rb', line 522

def default_option_name
  if factory?
    builder.default_option_name
  else
    @default_option_name || (@single_option ? :default : nil)
  end
end

#dependency_injected?(value) ⇒ Boolean

Returns:

  • (Boolean)


482
483
484
# File 'lib/glue_gun/dsl.rb', line 482

def dependency_injected?(value)
  injected_dependency(value).present?
end

#determine_option_name(init_args, instance) ⇒ Object



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/glue_gun/dsl.rb', line 438

def determine_option_name(init_args, instance)
  option_name = nil

  user_specified_option = init_args.is_a?(Hash) && init_args.keys.size == 1
  user_specified_valid_option = user_specified_option && option_configs.key?(init_args.keys.first)

  if user_specified_valid_option
    option_name = init_args.keys.first
    init_args = init_args[option_name] # Extract the inner value
  elsif when_block.present?
    result = instance.instance_exec(init_args, &when_block)
    if result.is_a?(Hash) && result[:option]
      option_name = result[:option]
      as_attr = result[:as]
      init_args = { as_attr => init_args } if as_attr && init_args
    end
  end

  option_name ||= default_option_name

  [option_name, init_args]
end

#factory?Boolean

Returns:

  • (Boolean)


361
362
363
# File 'lib/glue_gun/dsl.rb', line 361

def factory?
  @factory_class.present?
end

#get_option(name) ⇒ Object



510
511
512
# File 'lib/glue_gun/dsl.rb', line 510

def get_option(name)
  @option_configs[name]
end

#get_option_configsObject



349
350
351
# File 'lib/glue_gun/dsl.rb', line 349

def get_option_configs
  builder.option_configs
end

#initialize_builder_dependency(init_args, instance) ⇒ Object

Raises:

  • (ArgumentError)


390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/glue_gun/dsl.rb', line 390

def initialize_builder_dependency(init_args, instance)
  if init_args && init_args.is_a?(Hash) && init_args.key?(:option_name)
    option_name = init_args[:option_name]
    init_args = init_args[:value]
  else
    option_name, init_args = determine_option_name(init_args, instance)
  end

  option_config = option_configs[option_name.to_sym]

  raise ArgumentError, "Unknown #{component_type} option '#{option_name}'" unless option_config

  [instantiate_dependency(option_config, init_args, instance), option_config]
end

#initialize_factory_dependency(init_args, instance) ⇒ Object



386
387
388
# File 'lib/glue_gun/dsl.rb', line 386

def initialize_factory_dependency(init_args, instance)
  builder.initialize_single_dependency(init_args, instance)
end

#initialize_single_dependency(init_args, instance) ⇒ Object



405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/glue_gun/dsl.rb', line 405

def initialize_single_dependency(init_args, instance)
  if dependency_injected?(init_args)
    dep = init_args
    option_config = injected_dependency(init_args)
  elsif factory?
    dep, option_config = initialize_factory_dependency(init_args, instance)
  else
    dep, option_config = initialize_builder_dependency(init_args, instance)
  end

  [dep, option_config]
end

#injected_dependency(value) ⇒ Object



475
476
477
478
479
480
# File 'lib/glue_gun/dsl.rb', line 475

def injected_dependency(value)
  allowed_classes.detect do |option|
    option_class = option.class_name
    value.is_a?(option_class)
  end
end

#instantiate_dependency(option_config, init_args, parent) ⇒ Object



461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'lib/glue_gun/dsl.rb', line 461

def instantiate_dependency(option_config, init_args, parent)
  dep_attributes = init_args.is_a?(Hash) ? init_args : {}

  # Build dependency attributes, including sourcing from parent
  dep_attributes = build_dependency_attributes(option_config, dep_attributes, parent)

  if dep_attributes.key?(:id)
    raise ArgumentError,
          "cannot bind attribute 'id' between #{parent.class.name} and #{option_config.class_name}. ID is reserved for primary keys in Ruby on Rails"
  end
  dependency_class = option_config.class_name
  dependency_class.new(dep_attributes)
end

#is_hash?(init_args) ⇒ Boolean

Returns:

  • (Boolean)


373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/glue_gun/dsl.rb', line 373

def is_hash?(init_args)
  return false unless init_args.is_a?(Hash)

  allowed_configs = allowed_configurations
  return false if allowed_configs.count == 1 && allowed_configs == [:default]

  if init_args.key?(:option_name)
    allowed_configs.exclude?(init_args[:option_name])
  else
    init_args.keys.none? { |k| allowed_configs.include?(k) }
  end
end

#lazy?Boolean

Returns:

  • (Boolean)


369
370
371
# File 'lib/glue_gun/dsl.rb', line 369

def lazy?
  @lazy == true
end

#only?Boolean

Returns:

  • (Boolean)


544
545
546
# File 'lib/glue_gun/dsl.rb', line 544

def only?
  @is_only == true
end

#option(name, &block) ⇒ Object

For multi-option dependencies



515
516
517
518
519
520
# File 'lib/glue_gun/dsl.rb', line 515

def option(name, &block)
  option_builder = OptionBuilder.new(name)
  option_builder.instance_eval(&block)
  @option_configs[name] = option_builder
  set_default_option_name(name) if option_builder.is_default
end

#set_class(class_name) ⇒ Object

Support set_class and attribute for single-option dependencies



501
502
503
504
# File 'lib/glue_gun/dsl.rb', line 501

def set_class(class_name)
  single_option.set_class(class_name)
  set_default_option_name(:default)
end

#set_factory_class(factory_class) ⇒ Object



335
336
337
# File 'lib/glue_gun/dsl.rb', line 335

def set_factory_class(factory_class)
  @factory_class = factory_class
end

#single_optionObject



534
535
536
537
538
539
540
541
542
# File 'lib/glue_gun/dsl.rb', line 534

def single_option
  @single_option ||= begin
    option_builder = OptionBuilder.new(:default)
    option_builder.only
    @option_configs[:default] = option_builder
    set_default_option_name(:default)
    option_builder
  end
end

#validate_hash_dependencies(init_args) ⇒ Object



486
487
488
489
490
491
492
493
494
495
496
497
498
# File 'lib/glue_gun/dsl.rb', line 486

def validate_hash_dependencies(init_args)
  allowed_configs = allowed_configurations

  init_args.each do |_named_key, configuration|
    next unless configuration.is_a?(Hash)

    key = configuration.keys.first
    if key.nil? || allowed_configs.exclude?(key.to_sym)
      raise ArgumentError,
            "Unknown #{component_type} option: #{init_args.keys.first}."
    end
  end
end

#when(&block) ⇒ Object



530
531
532
# File 'lib/glue_gun/dsl.rb', line 530

def when(&block)
  @when_block = block
end