Class: ObjectMembersDisjunctionValidation

Inherits:
ObjectMembersValidation show all
Defined in:
lib/json_patterns.rb

Constant Summary

Constants included from Inspectable

Inspectable::INSPECTING_KEY

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ObjectMembersValidation

memoized_new_from_pattern

Methods included from HashInitialized

#initialize

Methods included from Inspectable

#inspect

Instance Attribute Details

#alternativesObject

Returns the value of attribute alternatives.



602
603
604
# File 'lib/json_patterns.rb', line 602

def alternatives
  @alternatives
end

Instance Method Details

#first_value_match?(name, value) ⇒ Boolean

Returns:



616
617
618
# File 'lib/json_patterns.rb', line 616

def first_value_match?(name, value)
  @alternatives.any? { |v| v.first_value_match?(name, value) }
end

#first_value_validations(name) ⇒ Object



608
609
610
# File 'lib/json_patterns.rb', line 608

def first_value_validations(name)
  set_union(@alternatives.map { |v| v.first_value_validations(name) })
end

#matching_first_names(data) ⇒ Object



612
613
614
# File 'lib/json_patterns.rb', line 612

def matching_first_names(data)
  set_union(@alternatives.map { |v| v.matching_first_names(data) })
end

#possible_first_namesObject



604
605
606
# File 'lib/json_patterns.rb', line 604

def possible_first_names
  set_union(@alternatives.map { |v| v.possible_first_names })
end

#to_sObject



684
685
686
# File 'lib/json_patterns.rb', line 684

def to_s
  '(' + (@alternatives.map { |v| v.to_s }).join(' | ') + ')'
end

#validate_members(path, data) ⇒ Object



620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
# File 'lib/json_patterns.rb', line 620

def validate_members(path, data)
  matching_first_names_by_validation =
    Hash[*@alternatives.flat_map { |v| [v, v.matching_first_names(data)] }]
  validations_with_matching_first_names =
    matching_first_names_by_validation.select { |k, v| v.size > 0 }.keys
  matching_names = set_union(matching_first_names_by_validation.values)

  if matching_names.size == 0
    found_names = data.empty? ?
      'end of object members' :
      "names: #{data.keys.map { |name| name.inspect }.join(', ')}"
    return ObjectMembersValidationResult.new(
      failures: [ValidationUnexpected.new(
        path: path,
        found: found_names,
        expected: Set[*possible_first_names.map { |n| "name: #{n.inspect}" }],
      )],
      remainder: data,
    )
  elsif matching_names.size > 1
    return ObjectMembersValidationResult.new(
      failures: [ValidationAmbiguity.new(
        path: path,
        found: data.keys,
        overlapping_patterns: validations_with_matching_first_names.flat_map { |v|
          v.possible_first_names.to_a
        },
      )]
    )
  else
    name = matching_names.to_a[0]
    value = data[name]
    remainder = data.dup
    remainder.delete name
    validations_matching_value =
      validations_with_matching_first_names.select { |v| v.first_value_match?(name, value) }
    if validations_matching_value.length == 0
      return ObjectMembersValidationResult.new(
        failures: [ValidationUnexpected.new(
          path: path + [name],
          found: shallow_value(data[name]),
          expected: set_union(validations_with_matching_first_names.map { |v|
            set_union(v.first_value_validations(name).map { |v| v.shallow_describe })
          }),
        )],
        remainder: remainder,
      )
    elsif validations_matching_value.length == 1
      return validations_matching_value[0].validate_members(path, data)
    else
      return ObjectMembersValidationResult.new(
        failures: [ValidationAmbiguity.new(
          path: path + [name],
          found: shallow_value(data[name]),
          overlapping_patterns: validations_matching_value.flat_map { |v|
            v.first_value_validations(name).shallow_describe.to_a
          },
        )],
        remainder: remainder,
      )
    end
  end
end