mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-05 05:25:24 +02:00
Refactor TimeSeries
artifacts (#651)
* Reindent TimeSeries classes * Fix spacing in time series tests * Remove trend tests where current is nil I think if we've gotten this far with a nil value for current, there's a data integrity problem. If we allow this, we'll have to be very defensive in our code. Best to raise and fix early. * Reindent Money class * Refactor TimeSeries artifacts * Use as_json in TimeSeries * Bring back tests for trends where current is nil * Bring back trend test * Correctly enumerate trend test * Use favorable_direction for trend_styles helper * Make trend public in TimeSeries::Value * Allow nil current values in trends I think I might've gotten it wrong before, nils might appear in trends if values are unavailable for snapshots * Clean up TimeSeries::Trend * Skip trend values same class validations if any values are nil * Refactor Money * Remove object parsing in TimeSeries::Value We're only every passing hashes
This commit is contained in:
parent
fe2a2ac3f9
commit
fc3ade392a
9 changed files with 258 additions and 206 deletions
|
@ -1,32 +1,46 @@
|
|||
class TimeSeries::Value
|
||||
include Comparable
|
||||
include Comparable
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :trend
|
||||
attr_reader :value, :date, :original
|
||||
attr_reader :value, :date, :original, :trend
|
||||
|
||||
def initialize(obj)
|
||||
@original = obj.fetch(:original, obj)
|
||||
validates :date, presence: true
|
||||
validate :value_must_be_of_known_type
|
||||
|
||||
if obj.is_a?(Hash)
|
||||
@date = obj[:date]
|
||||
@value = obj[:value]
|
||||
else
|
||||
@date = obj.date
|
||||
@value = obj.value
|
||||
end
|
||||
def initialize(date:, value:, original: nil, series: nil, previous_value: nil)
|
||||
@date, @value, @original, @series = date, value, original, series
|
||||
@trend = create_trend previous_value
|
||||
|
||||
validate_input
|
||||
validate!
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
result = date <=> other.date
|
||||
result = value <=> other.value if result == 0
|
||||
result
|
||||
end
|
||||
|
||||
def as_json
|
||||
{
|
||||
date: date,
|
||||
value: value.as_json,
|
||||
trend: trend.as_json
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :series
|
||||
|
||||
def create_trend(previous_value)
|
||||
TimeSeries::Trend.new \
|
||||
current: value,
|
||||
previous: previous_value,
|
||||
series: series
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
result = date <=> other.date
|
||||
result = value <=> other.value if result == 0
|
||||
result
|
||||
def value_must_be_of_known_type
|
||||
unless value.is_a?(Money) || value.is_a?(Numeric)
|
||||
errors.add :value, "must be a Money or Numeric"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def validate_input
|
||||
raise ArgumentError, "Date is required" unless @date.is_a?(Date)
|
||||
raise ArgumentError, "Money or Numeric value is required" unless @value.is_a?(Money) || @value.is_a?(Numeric)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue