Skip to content

Instantly share code, notes, and snippets.

@fernandes
Created November 17, 2021 19:36
Show Gist options
  • Save fernandes/631a9c3997870de7e0730111058a5b63 to your computer and use it in GitHub Desktop.
Save fernandes/631a9c3997870de7e0730111058a5b63 to your computer and use it in GitHub Desktop.
require "test_helper"
class Splasher
attr_reader :total, :range, :per, :mod, :unit, :unit_total, :start_at
def initialize(total:, range:, unit: :hour, per: :hour, start_at: DateTime.now)
@total = total
@range = range
@unit = unit
@per = per
@start_at = start_at
@mod = total % range_steps
@unit_total = (total / range_steps).floor
end
def sequence
seq = {}
1.upto(range_steps) do |n|
seq_total = (n <= mod) ? unit_total + 1 : unit_total
seq[start_at.send(:-, (n - 1).send(per))] = seq_total
end
seq
end
private
def seconds_timerange
@seconds_timerange ||= start_at.to_time.utc - range.send(unit).ago
end
def range_steps
@range_steps ||= (seconds_timerange / 1.send(per)).round
end
end
class DistributeTimeRangeTest < ActiveSupport::TestCase
setup do
travel_to Time.zone.local(2021, 11, 17, 12, 0, 0)
end
teardown do
travel_back
end
test "distribute over last 24 hours" do
sequence = Splasher.new(total: 100, range: 24, per: :hour).sequence
assert_equal expected_total_100_per_hour, sequence
end
test "distrbute over last 3 days, per hour" do
sequence = Splasher.new(total: 100, range: 3, unit: :day, per: :hour).sequence
assert_equal expected_total_100_last_3_days_per_hour, sequence
end
def expected_total_100_per_hour
d = DateTime.now
e = {}
e[d] = 5
e[d-1.hour] = 5
e[d-2.hours] = 5
e[d-3.hours] = 5
e[d-4.hours] = 4
e[d-5.hours] = 4
e[d-6.hours] = 4
e[d-7.hours] = 4
e[d-8.hours] = 4
e[d-9.hours] = 4
e[d-10.hours] = 4
e[d-11.hours] = 4
e[d-12.hours] = 4
e[d-13.hours] = 4
e[d-14.hours] = 4
e[d-15.hours] = 4
e[d-16.hours] = 4
e[d-17.hours] = 4
e[d-18.hours] = 4
e[d-19.hours] = 4
e[d-20.hours] = 4
e[d-21.hours] = 4
e[d-22.hours] = 4
e[d-23.hours] = 4
e
end
def expected_total_100_last_3_days_per_hour
d = DateTime.now
e = {}
e[d] = 2
e[d-1.hour] = 2
e[d-2.hours] = 2
e[d-3.hours] = 2
e[d-4.hours] = 2
e[d-5.hours] = 2
e[d-6.hours] = 2
e[d-7.hours] = 2
e[d-8.hours] = 2
e[d-9.hours] = 2
e[d-10.hours] = 2
e[d-11.hours] = 2
e[d-12.hours] = 2
e[d-13.hours] = 2
e[d-14.hours] = 2
e[d-15.hours] = 2
e[d-16.hours] = 2
e[d-17.hours] = 2
e[d-18.hours] = 2
e[d-19.hours] = 2
e[d-20.hours] = 2
e[d-21.hours] = 2
e[d-22.hours] = 2
e[d-23.hours] = 2
e[d-24.hours] = 2
e[d-25.hours] = 2
e[d-26.hours] = 2
e[d-27.hours] = 2
e[d-28.hours] = 1
e[d-29.hours] = 1
e[d-30.hours] = 1
e[d-31.hours] = 1
e[d-32.hours] = 1
e[d-33.hours] = 1
e[d-34.hours] = 1
e[d-35.hours] = 1
e[d-36.hours] = 1
e[d-37.hours] = 1
e[d-38.hours] = 1
e[d-39.hours] = 1
e[d-40.hours] = 1
e[d-41.hours] = 1
e[d-42.hours] = 1
e[d-43.hours] = 1
e[d-44.hours] = 1
e[d-45.hours] = 1
e[d-46.hours] = 1
e[d-47.hours] = 1
e[d-48.hours] = 1
e[d-49.hours] = 1
e[d-50.hours] = 1
e[d-51.hours] = 1
e[d-52.hours] = 1
e[d-53.hours] = 1
e[d-54.hours] = 1
e[d-55.hours] = 1
e[d-56.hours] = 1
e[d-57.hours] = 1
e[d-58.hours] = 1
e[d-59.hours] = 1
e[d-60.hours] = 1
e[d-61.hours] = 1
e[d-62.hours] = 1
e[d-63.hours] = 1
e[d-64.hours] = 1
e[d-65.hours] = 1
e[d-66.hours] = 1
e[d-67.hours] = 1
e[d-68.hours] = 1
e[d-69.hours] = 1
e[d-70.hours] = 1
e[d-71.hours] = 1
e
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment