diff --git a/lib/mindee/parsing/v2/field/base_field.rb b/lib/mindee/parsing/v2/field/base_field.rb index 6a5966a2..1256c642 100644 --- a/lib/mindee/parsing/v2/field/base_field.rb +++ b/lib/mindee/parsing/v2/field/base_field.rb @@ -20,13 +20,16 @@ class BaseField # @param indent_level [Integer] Level of indentation for rst display. def initialize(raw_prediction, indent_level = 0) @indent_level = indent_level - @confidence = raw_prediction.key?('confidence') ? raw_prediction['confidence'] : nil - @locations = if raw_prediction.key?('locations') - raw_prediction['locations'].map do |location| + confidence = raw_prediction['confidence'] + @confidence = FieldConfidence.new(confidence) unless confidence.nil? || confidence.empty? + + locations = raw_prediction['locations'] + @locations = if locations.nil? || locations.empty? + [] + else + locations.map do |location| FieldLocation.new(location) end - else - [] end end diff --git a/lib/mindee/parsing/v2/field/field_confidence.rb b/lib/mindee/parsing/v2/field/field_confidence.rb index 66834de7..0570b7a9 100644 --- a/lib/mindee/parsing/v2/field/field_confidence.rb +++ b/lib/mindee/parsing/v2/field/field_confidence.rb @@ -19,70 +19,107 @@ class FieldConfidence LOW = 'Low' # List of valid values, as frozen strings. - VALID_VALUES = [CERTAIN, HIGH, MEDIUM, LOW].freeze + VALID_VALUES = ['Certain', 'High', 'Medium', 'Low'].freeze # @param value [String] The confidence level value. # @raise [ArgumentError] If the value is not a valid confidence level. def initialize(value) - unless VALID_VALUES.include?(value) + case value + when 'Certain' then @value = CERTAIN + when 'High' then @value = HIGH + when 'Medium' then @value = MEDIUM + when 'Low' then @value = LOW + else raise ArgumentError, - "Invalid confidence level: #{value}. Must be one of: #{VALID_VALUES.join(', ')}" + "Invalid confidence level: '#{value}'. Must be one of: #{VALID_VALUES.join(', ')}" end @value = value end - # Create a FieldConfidence from a string value. - # @param value [String] The confidence level string. - # @return [FieldConfidence] The confidence instance. - def self.from_string(value) - new(value) + # String representation of the confidence level. + # @return [String] The confidence level value. + def to_s + @value end - # Check if this is a certain confidence level. - # @return [Boolean] `true` if confidence is certain. - def certain? - @value == CERTAIN + # String representation of the confidence level. + # @return [Integer] The confidence level value as an integer: 1 is LOW, 4 is HIGH. + def to_i + val_to_i(@value) end - # Check if this is a high confidence level. - # @return [Boolean] `true` if confidence is high. - def high? - @value == HIGH + # Inspect method for debugging. + # @return [String] Debug representation. + def inspect + "#<#{self.class.name}:#{@value}>" end - # Check if this is a medium confidence level. - # @return [Boolean] `true` if confidence is medium. - def medium? - @value == MEDIUM - end + # Using 'case' breaks steep ... + # rubocop:disable Style/CaseLikeIf - # Check if this is a low confidence level. - # @return [Boolean] `true` if confidence is low. - def low? - @value == LOW + # Equality of two FieldConfidence instances. + # @param other [String, Integer, FieldConfidence] The other confidence to compare. + # @return [Boolean] `true` if they have the same value. + def ==(other) + if other.is_a?(FieldConfidence) + @value == other.value + elsif other.is_a?(String) + @value == other + elsif other.is_a?(Integer) + to_i == other + else + raise ArgumentError, "Invalid type: #{other.class}" + end end - # String representation of the confidence level. - # @return [String] The confidence level value. - def to_s - @value + # Greater than or equality of two FieldConfidence instances. + # @param other [String, Integer, FieldConfidence] The other confidence to compare. + def >=(other) + if other.is_a?(FieldConfidence) + to_i >= val_to_i(other.value) + elsif other.is_a?(String) + to_i >= val_to_i(other) + elsif other.is_a?(Integer) + to_i >= other + else + raise ArgumentError, "Invalid type: #{other.class}" + end end - # Compare two FieldConfidence instances. - # @param other [FieldConfidence] The other confidence to compare. - # @return [Boolean] `true` if they have the same value. - def ==(other) - other.is_a?(FieldConfidence) && @value == other.value + # less than or equality of two FieldConfidence instances. + # # @param other [String, Integer, FieldConfidence] The other confidence to compare. + def <=(other) + if other.is_a?(FieldConfidence) + to_i <= val_to_i(other.value) + elsif other.is_a?(String) + to_i <= val_to_i(other) + elsif other.is_a?(Integer) + to_i <= other + else + raise ArgumentError, "Invalid type: #{other.class}" + end end - # Make instances comparable and hashable + # rubocop:enable Style/CaseLikeIf + + # Aliases for the comparison operators. alias eql? == + alias gteql? >= + alias lteql? <= - # Inspect method for debugging. - # @return [String] Debug representation. - def inspect - "#<#{self.class.name}:#{@value}>" + protected + + def val_to_i(value) + case value + when CERTAIN then 4 + when HIGH then 3 + when MEDIUM then 2 + when LOW then 1 + else + raise ArgumentError, + "Invalid confidence level: '#{value}'. Must be one of: #{VALID_VALUES.join(', ')}" + end end end end diff --git a/sig/mindee/parsing/v2/field/field_confidence.rbs b/sig/mindee/parsing/v2/field/field_confidence.rbs index 16ee1eef..77ca6b68 100644 --- a/sig/mindee/parsing/v2/field/field_confidence.rbs +++ b/sig/mindee/parsing/v2/field/field_confidence.rbs @@ -12,14 +12,17 @@ module Mindee VALID_VALUES: Array[String] def initialize: (String) -> void def self.from_string: (String) -> FieldConfidence - def certain?: -> bool - def high?: -> bool - def medium?: -> bool - def low?: -> bool + def to_i: -> Integer def to_s: -> String - def ==: (FieldConfidence) -> bool - def eql?: (FieldConfidence) -> bool + def ==: (String | Integer | FieldConfidence) -> bool + def eql?: (String | Integer | FieldConfidence) -> bool + def <=: (String | Integer | FieldConfidence) -> bool + def lteql? : (String | Integer | FieldConfidence) -> bool + def >=: (String | Integer | FieldConfidence) -> bool + def gteql?: (String | Integer | FieldConfidence) -> bool def inspect: -> String + + def val_to_i: (String) -> Integer end end end diff --git a/spec/parsing/v2/inference_spec.rb b/spec/parsing/v2/inference_spec.rb index d8695f0a..826ee301 100644 --- a/spec/parsing/v2/inference_spec.rb +++ b/spec/parsing/v2/inference_spec.rb @@ -22,7 +22,7 @@ def load_v2_inference(resource_path) simple_field = Mindee::Parsing::V2::Field::SimpleField object_field = Mindee::Parsing::V2::Field::ObjectField list_field = Mindee::Parsing::V2::Field::ListField - field_conf = Mindee::Parsing::V2::Field::FieldConfidence + field_confidence = Mindee::Parsing::V2::Field::FieldConfidence describe 'simple' do it 'loads a blank inference with valid properties' do @@ -264,19 +264,20 @@ def load_v2_inference(resource_path) expect(polygon[3][0]).to be_within(1e-12).of(0.948849) expect(polygon[3][1]).to be_within(1e-12).of(0.244565) - # Confidence can be a FieldConfidence instance or a String depending on implementation. - conf_value = - if date_field.confidence.respond_to?(:to_s) - date_field.confidence.to_s - else - date_field.confidence - end - expect(conf_value).to eq('Medium') - - # Optional strict check if equality supports comparing with FieldConfidence constants: - if defined?(field_conf) && field_conf.respond_to?(:from_string) - expect(conf_value).to eq(field_conf.from_string('Medium').to_s) - end + confidence = date_field.confidence + expect(confidence).to be_a(field_confidence) + # equality + expect(confidence).to eq(field_confidence::MEDIUM) + expect(confidence).to eq('Medium') + expect(confidence).to eq(2) + # less than or equal + expect(confidence).to be_lteql(field_confidence::HIGH) + expect(confidence).to be_lteql('High') + expect(confidence).to be_lteql(3) + # greater than or equal + expect(confidence).to be_gteql(field_confidence::LOW) + expect(confidence).to be_gteql('Low') + expect(confidence).to be_gteql(1) end end end