Skip to content

Instantly share code, notes, and snippets.

@basial
Last active January 28, 2021 22:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basial/ca28ed3d4b6ea9b4ee33d3aba78f00f5 to your computer and use it in GitHub Desktop.
Save basial/ca28ed3d4b6ea9b4ee33d3aba78f00f5 to your computer and use it in GitHub Desktop.
class Stats
class << self
def weekly_progress(issue_ids)
relation = Issue.where(id: issue_ids)
.order('year asc, week asc')
.group('year, week')
all = <<-SQL
date_part('week', created_at) as week,
date_part('year', created_at) as year,
count(*) as total
SQL
all_sql = relation.select(all).to_sql
weekly_progress_output(issues_report(all_sql))
end
private
def issues_report(request)
{}.tap do |hash|
ActiveRecord::Base.connection.select_all(request).each do |row|
week = [row['year'].to_i, row['week'].to_i].join('-')
hash[week] = row['total'].to_i
end
end
end
def extract_date(data, type)
week_parts = data.keys.first.split("-") if type == 'first'
week_parts = data.keys.last.split("-") if type == 'last'
year, week = week_parts[0].to_i, week_parts[1].to_i
n = 0
begin
Date.commercial(year, week, 1)
rescue ArgumentError
raise if (n+=1) > 3
year -= 1 if week > 50
retry
end
end
def weekly_progress_output(all)
first_date = extract_date(all, 'first')
last_date = extract_date(all, 'last')
(first_date..last_date).step(7).map do |date|
week = [date.strftime("%G"), date.strftime("%V").to_i].join('-')
[
week,
all[week] || 0
]
end
end
end
end
require 'spec_helper'
describe Stats do
describe '#weekly_progress' do
subject { Stats.weekly_progress(issue_ids) }
let(:issue) do
create(:issue).tap do |_issue|
# Make spec pass on a sunday evening.
_issue.update_column :created_at,
(_issue.created_at.beginning_of_week + 1.day)
end
end
let(:issue_ids) { [issue.id] }
let(:stats) { subject[0] }
let(:formatted_date) { stats.first }
let(:issue_count) { stats.second }
let(:created_at) { issue.created_at }
it 'returns correct weekly stats' do
expect(subject.length).to eq(1)
expect(issue_count).to eql(1)
expect(formatted_date).to eql([created_at.strftime("%Y"), created_at.strftime("%V").to_i].join("-"))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment