Add memory storage

This commit is contained in:
Anton Vakhrushev 2019-11-04 19:50:20 +03:00
parent afa8ebdd2e
commit a8eba4de31
4 changed files with 143 additions and 39 deletions

View File

@ -1,14 +0,0 @@
[
{
"date": "2019-01-01",
"hours": 10
},
{
"date": "2019-01-02",
"hours": 6
},
{
"date": "2019-01-03",
"hours": 4
}
]

View File

@ -1,6 +0,0 @@
[
{
"start": "2019-01-01 10:00:00",
"finish": "2019-01-01 20:00:00"
}
]

View File

@ -1,15 +1,48 @@
require "./spec_helper" require "./spec_helper"
describe Dayoff do module Dayoff::Test
it "can calc work hours" do extend self
app = Dayoff::App.new
prof = app.profile("./spec/data") def t(day, hour, min = 0)
prof.get_planned_hours.should eq 20 location = Time::Location.load("Europe/Moscow")
Time.local(2019, 1, day, hour, min, location: location)
end end
describe Dayoff do
it "can calc work hours" do it "can calc work hours" do
app = Dayoff::App.new storage = MemoryStorage.new
prof = app.profile("./spec/data") storage.set_work_records [
WorkRecord.new(t(1, 10), t(1, 20)),
]
prof = Profile.new(storage)
prof.get_work_hours.should eq 10 prof.get_work_hours.should eq 10
end end
it "can write new record" do
storage = MemoryStorage.new
storage.set_work_records [
WorkRecord.new(t(1, 10), t(1, 20)),
]
prof = Profile.new(storage)
start_time = t(2, 10)
prof.start start_time
records = storage.get_work_records
records.size.should eq 2
records.last.finish.should be_nil
end
it "can finish started record" do
storage = MemoryStorage.new
storage.set_work_records [
WorkRecord.new(t(1, 10), t(1, 20)),
WorkRecord.new(t(2, 10), nil),
]
prof = Profile.new(storage)
finish_time = t(2, 20)
prof.finish finish_time
records = storage.get_work_records
records.size.should eq 2
records.last.finish_time.should eq finish_time
end
end
end end

View File

@ -13,8 +13,64 @@ module Dayoff
class WorkRecord class WorkRecord
JSON.mapping( JSON.mapping(
start: String, start: String,
finish: String, finish: String | Nil,
) )
FORMAT = "%Y-%m-%d %H:%M:%S"
def initialize(start : Time, finish : Time | Nil = nil)
@start = start.to_s FORMAT
@finish = nil
if finish
@finish = finish.to_s FORMAT
end
end
def start_time : Time
location = Time::Location.load("Europe/Moscow")
Time.parse(start, FORMAT, location)
end
def finish_time : Time
location = Time::Location.load("Europe/Moscow")
Time.parse(finish.as(String), FORMAT, location)
end
def finish_time=(v : Time)
@finish = v.to_s FORMAT
end
def started? : Bool
@finish.nil?
end
end
abstract class Storage
abstract def get_planned_dates : Array(PlannedDate)
abstract def set_planned_dates(items : Array(PlannedDate))
abstract def get_work_records : Array(WorkRecord)
abstract def set_work_records(items : Array(WorkRecord))
end
class MemoryStorage < Storage
@planned_dates = [] of PlannedDate
@work_records = [] of WorkRecord
def get_planned_dates : Array(PlannedDate)
@planned_dates
end
def set_planned_dates(items : Array(PlannedDate))
@planned_dates = items
end
def get_work_records : Array(WorkRecord)
@work_records
end
def set_work_records(items : Array(WorkRecord))
@work_records = items
end
end end
class Collection(T) class Collection(T)
@ -31,11 +87,28 @@ module Dayoff
end end
def write(items : Array(T)) def write(items : Array(T))
content = items.to_json content = items.to_pretty_json indent: " "
File.write @path, content File.write @path, content
end end
end end
class CrossedTimeSpan < Exception
end
class StartedRecordNotFound < Exception
end
struct ProfileId
def initialize(@id : String)
end
getter id
def to_s : String
@id
end
end
class Profile class Profile
PLANNED_DATES = "planned-dates.json" PLANNED_DATES = "planned-dates.json"
WORK_RECORDS = "work-records.json" WORK_RECORDS = "work-records.json"
@ -43,9 +116,9 @@ module Dayoff
@pdates = [] of PlannedDate @pdates = [] of PlannedDate
@wrecords = [] of WorkRecord @wrecords = [] of WorkRecord
def initialize(@path : String) def initialize(@storage : Storage)
@pdates = Collection(PlannedDate).new(File.join(@path, PLANNED_DATES)).get_all @pdates = @storage.get_planned_dates
@wrecords = Collection(WorkRecord).new(File.join(@path, WORK_RECORDS)).get_all @wrecords = @storage.get_work_records
end end
def get_planned_hours def get_planned_hours
@ -60,18 +133,36 @@ module Dayoff
sum = 0 sum = 0
location = Time::Location.load("Europe/Moscow") location = Time::Location.load("Europe/Moscow")
@wrecords.each do |wr| @wrecords.each do |wr|
s = Time.parse(wr.start, "%Y-%m-%d %H:%M:%S", location) diff = wr.finish_time - wr.start_time
f = Time.parse(wr.finish, "%Y-%m-%d %H:%M:%S", location)
diff = f - s
sum += diff.total_hours.to_i32 sum += diff.total_hours.to_i32
end end
sum sum
end end
def start(time : Time)
@wrecords.each do |wr|
if time <= wr.start_time || time <= wr.finish_time
raise CrossedTimeSpan.new
end
end
new_record = WorkRecord.new time
@wrecords.push(new_record)
@storage.set_work_records @wrecords
end
def finish(time : Time)
started = @wrecords.find { |x| x.started? }
if started.nil?
raise StartedRecordNotFound.new
end
started.finish_time = time
@storage.set_work_records @wrecords
end
end end
class App class App
def profile(path) def profile(profile_id : ProfileId)
Profile.new(path) Profile.new(profile_id.to_s)
end end
end end
end end