Add memory storage
This commit is contained in:
parent
afa8ebdd2e
commit
a8eba4de31
@ -1,14 +0,0 @@
|
||||
[
|
||||
{
|
||||
"date": "2019-01-01",
|
||||
"hours": 10
|
||||
},
|
||||
{
|
||||
"date": "2019-01-02",
|
||||
"hours": 6
|
||||
},
|
||||
{
|
||||
"date": "2019-01-03",
|
||||
"hours": 4
|
||||
}
|
||||
]
|
@ -1,6 +0,0 @@
|
||||
[
|
||||
{
|
||||
"start": "2019-01-01 10:00:00",
|
||||
"finish": "2019-01-01 20:00:00"
|
||||
}
|
||||
]
|
@ -1,15 +1,48 @@
|
||||
require "./spec_helper"
|
||||
|
||||
describe Dayoff do
|
||||
it "can calc work hours" do
|
||||
app = Dayoff::App.new
|
||||
prof = app.profile("./spec/data")
|
||||
prof.get_planned_hours.should eq 20
|
||||
module Dayoff::Test
|
||||
extend self
|
||||
|
||||
def t(day, hour, min = 0)
|
||||
location = Time::Location.load("Europe/Moscow")
|
||||
Time.local(2019, 1, day, hour, min, location: location)
|
||||
end
|
||||
|
||||
describe Dayoff do
|
||||
it "can calc work hours" do
|
||||
app = Dayoff::App.new
|
||||
prof = app.profile("./spec/data")
|
||||
storage = MemoryStorage.new
|
||||
storage.set_work_records [
|
||||
WorkRecord.new(t(1, 10), t(1, 20)),
|
||||
]
|
||||
prof = Profile.new(storage)
|
||||
prof.get_work_hours.should eq 10
|
||||
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
|
||||
|
111
src/dayoff.cr
111
src/dayoff.cr
@ -13,8 +13,64 @@ module Dayoff
|
||||
class WorkRecord
|
||||
JSON.mapping(
|
||||
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
|
||||
|
||||
class Collection(T)
|
||||
@ -31,11 +87,28 @@ module Dayoff
|
||||
end
|
||||
|
||||
def write(items : Array(T))
|
||||
content = items.to_json
|
||||
content = items.to_pretty_json indent: " "
|
||||
File.write @path, content
|
||||
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
|
||||
PLANNED_DATES = "planned-dates.json"
|
||||
WORK_RECORDS = "work-records.json"
|
||||
@ -43,9 +116,9 @@ module Dayoff
|
||||
@pdates = [] of PlannedDate
|
||||
@wrecords = [] of WorkRecord
|
||||
|
||||
def initialize(@path : String)
|
||||
@pdates = Collection(PlannedDate).new(File.join(@path, PLANNED_DATES)).get_all
|
||||
@wrecords = Collection(WorkRecord).new(File.join(@path, WORK_RECORDS)).get_all
|
||||
def initialize(@storage : Storage)
|
||||
@pdates = @storage.get_planned_dates
|
||||
@wrecords = @storage.get_work_records
|
||||
end
|
||||
|
||||
def get_planned_hours
|
||||
@ -60,18 +133,36 @@ module Dayoff
|
||||
sum = 0
|
||||
location = Time::Location.load("Europe/Moscow")
|
||||
@wrecords.each do |wr|
|
||||
s = Time.parse(wr.start, "%Y-%m-%d %H:%M:%S", location)
|
||||
f = Time.parse(wr.finish, "%Y-%m-%d %H:%M:%S", location)
|
||||
diff = f - s
|
||||
diff = wr.finish_time - wr.start_time
|
||||
sum += diff.total_hours.to_i32
|
||||
end
|
||||
sum
|
||||
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
|
||||
|
||||
class App
|
||||
def profile(path)
|
||||
Profile.new(path)
|
||||
def profile(profile_id : ProfileId)
|
||||
Profile.new(profile_id.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user