From 33a9ae9967e5a205a51d099464d044806f9fb41b Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 30 May 2012 00:44:40 +0300 Subject: [PATCH] added date series --- data/test.kch | Bin 6299224 -> 6299424 bytes timespans/dateseries.go | 145 +++++++++++++++++++++++++++++++ timespans/dateseries_test.go | 64 ++++++++++++++ timespans/interval.go | 4 +- timespans/minute_buckets_test.go | 8 +- 5 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 timespans/dateseries.go create mode 100644 timespans/dateseries_test.go diff --git a/data/test.kch b/data/test.kch index 41b96c6bc793a96d8a119cee773e9f6f5b366fa0..5b6c3786c5f1aff6ee39a50ed28423265d8caee9 100644 GIT binary patch delta 573 zcmZ9}NlQXe7{>AR7GaY?i)ggW=4;-gmDO#y&7(~=m!*NwDxspaF2Y3wT{o?=zCsI; zBHBwWqE*m$2>J&7o5(tc-^+pbJTC{%^KDqVybDXG^`_#CkL9;iMZ}RXB!qEWkH&N( zq-0FbJU^E5q{rW0L`!G}-$nGzV?qvck%xQ~B;P#d8#9rY^vIEBNN7f{9?|}vicX@b zcnL~ThH_M(5*AdUI+==FZBId}BkG@%(X>}Y`l3Iv>Rp%rat zhZ`N}L>E+aqX)g{gNA+#U=TwX#t267@vd=9U=maCU>Y-+#T@40#R3+wgk`K?6>C_> z27K5|IYHh6Y(G8xc_!MN}BaefJkdK*a@I5O9f!wYR_&WC|=CdeB>-m`q5F zJuQ{D;T`x=Y2ueW$tliBzW2|n^7TyW0vydTo)+ z7-}bs2qrLzD5em@G-fc1I1*4X2MzOBz#^8gj1{b64eQvzCbqDR9SH0qi9PHig#)C~ o|0|0_9N`!_oZu8^I7c1@T;LK{xJD5-D4~oBZgFR;o%`6+4^IfLA^-pY diff --git a/timespans/dateseries.go b/timespans/dateseries.go new file mode 100644 index 000000000..29540bfd2 --- /dev/null +++ b/timespans/dateseries.go @@ -0,0 +1,145 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2012 Radu Ioan Fericean + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package timespans + +import ( + "time" + "strings" + "strconv" +) + +// Defines months series +type Months struct { + Id string + Series []time.Month +} + +// Return true if the specified date is inside the series +func (m *Months) Contains(month time.Month) (result bool) { + result = false + for _, ms := range m.Series { + if ms == month { + result = true + break + } + } + return +} + +/* +Serializes the month for the storage. Used for key-value storages. +*/ +func (m *Months) store() (result string) { + for _, ms := range m.Series { + result += strconv.Itoa(int(ms)) + "|" + } + return +} + +/* +De-serializes the month for the storage. Used for key-value storages. +*/ +func (m *Months) restore(input string) { + elements := strings.Split(input, "|") + for _, ms := range elements { + if month, err := strconv.Atoi(ms); err == nil { + m.Series = append(m.Series, time.Month(month)) + } + } +} + +// Defines month days series +type MonthDays struct { + Id string + Series []int +} + +// Return true if the specified date is inside the series +func (md *MonthDays) Contains(monthDay int) (result bool) { + result = false + for _, mds := range md.Series { + if mds == monthDay { + result = true + break + } + } + return +} + +/* +Serializes the month days for the storage. Used for key-value storages. +*/ +func (md *MonthDays) store() (result string) { + for _, mds := range md.Series { + result += strconv.Itoa(mds) + "|" + } + return +} + +/* +De-serializes the month days for the storage. Used for key-value storages. +*/ +func (md *MonthDays) restore(input string) { + elements := strings.Split(input, "|") + for _, mds := range elements { + if day, err := strconv.Atoi(mds); err == nil { + md.Series = append(md.Series, day) + } + } +} + +// Defines week days series +type WeekDays struct { + Id string + Series []time.Weekday +} + +// Return true if the specified date is inside the series +func (wd *WeekDays) Contains(weekDay time.Weekday) (result bool) { + result = false + for _, wds := range wd.Series { + if wds == weekDay { + result = true + break + } + } + return +} + +/* +Serializes the week days for the storage. Used for key-value storages. +*/ +func (wd *WeekDays) store() (result string) { + for _, wds := range wd.Series { + result += strconv.Itoa(int(wds)) + "|" + } + return +} + +/* +De-serializes the week days for the storage. Used for key-value storages. +*/ +func (wd *WeekDays) restore(input string) { + elements := strings.Split(input, "|") + for _, wds := range elements { + if day, err := strconv.Atoi(wds); err == nil { + wd.Series = append(wd.Series, time.Weekday(day)) + } + } +} diff --git a/timespans/dateseries_test.go b/timespans/dateseries_test.go new file mode 100644 index 000000000..ad7a25ad1 --- /dev/null +++ b/timespans/dateseries_test.go @@ -0,0 +1,64 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2012 Radu Ioan Fericean + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package timespans + +import ( + "testing" + "reflect" + "time" +) + +func TestMonthStoreRestore(t *testing.T) { + m := &Months{Id: "SUMMER", Series: []time.Month{5, 6, 7, 8}} + r := m.store() + if r != "5|6|7|8|" { + t.Errorf("Error serializing months: %v", r) + } + o := &Months{Id: "SUMMER"} + o.restore(r) + if !reflect.DeepEqual(o, m) { + t.Errorf("Expected %v was %v", m, o) + } +} + +func TestMonthDayStoreRestore(t *testing.T) { + md := &MonthDays{Id: "CHRISTMAS", Series: []int{24, 25, 26}} + r := md.store() + if r != "24|25|26|" { + t.Errorf("Error serializing month days: %v", r) + } + o := &MonthDays{Id: "CHRISTMAS"} + o.restore(r) + if !reflect.DeepEqual(o, md) { + t.Errorf("Expected %v was %v", md, o) + } +} + +func TestWeekDayStoreRestore(t *testing.T) { + wd := &WeekDays{Id: "WEEKEND", Series: []time.Weekday{6, 7}} + r := wd.store() + if r != "6|7|" { + t.Errorf("Error serializing week days: %v", r) + } + o := &WeekDays{Id: "WEEKEND"} + o.restore(r) + if !reflect.DeepEqual(o, wd) { + t.Errorf("Expected %v was %v", wd, o) + } +} diff --git a/timespans/interval.go b/timespans/interval.go index a3164cf3d..07dc764c0 100644 --- a/timespans/interval.go +++ b/timespans/interval.go @@ -25,8 +25,6 @@ import ( //"log" ) -type Months []time.Month - /* Defines a time interval for which a certain set of prices will apply */ @@ -42,7 +40,7 @@ type Interval struct { Returns true if the received time is inside the interval */ func (i *Interval) Contains(t time.Time) bool { - // chec for month + // check for month if i.Month > 0 && t.Month() != i.Month { return false } diff --git a/timespans/minute_buckets_test.go b/timespans/minute_buckets_test.go index 59fbf6a9b..5cac7bf69 100644 --- a/timespans/minute_buckets_test.go +++ b/timespans/minute_buckets_test.go @@ -27,7 +27,7 @@ func TestGetDestination(t *testing.T) { defer getter.Close() mb := &MinuteBucket{DestinationId: "nationale"} d := mb.getDestination(getter) - if d.Id != "nationale" || len(d.Prefixes) != 4 { + if d == nil || d.Id != "nationale" || len(d.Prefixes) != 4 { t.Error("Got wrong destination: ", d) } } @@ -39,21 +39,21 @@ func TestMultipleGetDestination(t *testing.T) { d := mb.getDestination(getter) d = mb.getDestination(getter) d = mb.getDestination(getter) - if d.Id != "nationale" || len(d.Prefixes) != 4 { + if d == nil || d.Id != "nationale" || len(d.Prefixes) != 4 { t.Error("Got wrong destination: ", d) } mb = &MinuteBucket{DestinationId: "retea"} d = mb.getDestination(getter) d = mb.getDestination(getter) d = mb.getDestination(getter) - if d.Id != "retea" || len(d.Prefixes) != 2 { + if d == nil || d.Id != "retea" || len(d.Prefixes) != 2 { t.Error("Got wrong destination: ", d) } mb = &MinuteBucket{DestinationId: "mobil"} d = mb.getDestination(getter) d = mb.getDestination(getter) d = mb.getDestination(getter) - if d.Id != "mobil" || len(d.Prefixes) != 2 { + if d == nil || d.Id != "mobil" || len(d.Prefixes) != 2 { t.Error("Got wrong destination: ", d) } }