Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions lib/mindee/parsing/v2/field/base_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
115 changes: 76 additions & 39 deletions lib/mindee/parsing/v2/field/field_confidence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 9 additions & 6 deletions sig/mindee/parsing/v2/field/field_confidence.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 15 additions & 14 deletions spec/parsing/v2/inference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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