From d6238ba5f763182f1a35ee65fd1d85d531d5d5b1 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 14 Nov 2013 09:31:28 +0200 Subject: [PATCH] moved dataseries to utils --- utils/dateseries.go | 272 +++++++++++++++++++++++++++++++++++++++ utils/dateseries_test.go | 149 +++++++++++++++++++++ 2 files changed, 421 insertions(+) create mode 100644 utils/dateseries.go create mode 100644 utils/dateseries_test.go diff --git a/utils/dateseries.go b/utils/dateseries.go new file mode 100644 index 000000000..e98994d9b --- /dev/null +++ b/utils/dateseries.go @@ -0,0 +1,272 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +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 utils + +import ( + "fmt" + "sort" + "strconv" + "strings" + "time" +) + +// Defines years days series +type Years []int + +func (ys Years) Sort() { + sort.Sort(ys) +} + +func (ys Years) Len() int { + return len(ys) +} + +func (ys Years) Swap(i, j int) { + ys[i], ys[j] = ys[j], ys[i] +} + +func (ys Years) Less(j, i int) bool { + return ys[j] < ys[i] +} + +// Return true if the specified date is inside the series +func (ys Years) Contains(year int) (result bool) { + result = false + for _, yss := range ys { + if yss == year { + result = true + break + } + } + return +} + +// Parse Years elements from string separated by sep. +func (ys *Years) Parse(input, sep string) { + switch input { + case "*any", "": + *ys = []int{} + default: + elements := strings.Split(input, sep) + for _, yss := range elements { + if year, err := strconv.Atoi(yss); err == nil { + *ys = append(*ys, year) + } + } + } +} + +func (ys Years) Serialize(sep string) string { + if len(ys) == 0 { + return "*any" + } + var yStr string + for idx, yr := range ys { + if idx != 0 { + yStr = fmt.Sprintf("%s%s%d", yStr, sep, yr) + } else { + yStr = strconv.Itoa(yr) + } + } + return yStr +} + +// Defines months series +type Months []time.Month + +func (m Months) Sort() { + sort.Sort(m) +} + +func (m Months) Len() int { + return len(m) +} + +func (m Months) Swap(i, j int) { + m[i], m[j] = m[j], m[i] +} + +func (m Months) Less(j, i int) bool { + return m[j] < m[i] +} + +// Return true if the specified date is inside the series +func (m Months) Contains(month time.Month) (result bool) { + for _, ms := range m { + if ms == month { + result = true + break + } + } + return +} + +// Loades Month elemnents from a string separated by sep. +func (m *Months) Parse(input, sep string) { + switch input { + case "*any", "": // Apier cannot receive empty string, hence using meta-tag + *m = []time.Month{} + default: + elements := strings.Split(input, sep) + for _, ms := range elements { + if month, err := strconv.Atoi(ms); err == nil { + *m = append(*m, time.Month(month)) + } + } + } +} + +// Dumps the months in a serialized string, similar to the one parsed +func (m Months) Serialize(sep string) string { + if len(m) == 0 { + return "*any" + } + var mStr string + for idx, mt := range m { + if idx != 0 { + mStr = fmt.Sprintf("%s%s%d", mStr, sep, mt) + } else { + mStr = strconv.Itoa(int(mt)) + } + } + return mStr +} + +// Defines month days series +type MonthDays []int + +func (md MonthDays) Sort() { + sort.Sort(md) +} + +func (md MonthDays) Len() int { + return len(md) +} + +func (md MonthDays) Swap(i, j int) { + md[i], md[j] = md[j], md[i] +} + +func (md MonthDays) Less(j, i int) bool { + return md[j] < md[i] +} + +// Return true if the specified date is inside the series +func (md MonthDays) Contains(monthDay int) (result bool) { + result = false + for _, mds := range md { + if mds == monthDay { + result = true + break + } + } + return +} + +// Parse MonthDay elements from string separated by sep. +func (md *MonthDays) Parse(input, sep string) { + switch input { + case "*any", "": + *md = []int{} + default: + elements := strings.Split(input, sep) + for _, mds := range elements { + if day, err := strconv.Atoi(mds); err == nil { + *md = append(*md, day) + } + } + } +} + +// Dumps the month days in a serialized string, similar to the one parsed +func (md MonthDays) Serialize(sep string) string { + if len(md) == 0 { + return "*any" + } + var mdsStr string + for idx, mDay := range md { + if idx != 0 { + mdsStr = fmt.Sprintf("%s%s%d", mdsStr, sep, mDay) + } else { + mdsStr = strconv.Itoa(mDay) + } + } + return mdsStr +} + +// Defines week days series +type WeekDays []time.Weekday + +func (wd WeekDays) Sort() { + sort.Sort(wd) +} + +func (wd WeekDays) Len() int { + return len(wd) +} + +func (wd WeekDays) Swap(i, j int) { + wd[i], wd[j] = wd[j], wd[i] +} + +func (wd WeekDays) Less(j, i int) bool { + return wd[j] < wd[i] +} + +// 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 { + if wds == weekDay { + result = true + break + } + } + return +} + +func (wd *WeekDays) Parse(input, sep string) { + switch input { + case "*any", "": + *wd = []time.Weekday{} + default: + elements := strings.Split(input, sep) + for _, wds := range elements { + if day, err := strconv.Atoi(wds); err == nil { + *wd = append(*wd, time.Weekday(day%7)) // %7 for sunday = 7 normalization + } + } + } +} + +// Dumps the week days in a serialized string, similar to the one parsed +func (wd WeekDays) Serialize(sep string) string { + if len(wd) == 0 { + return "*any" + } + var wdStr string + for idx, d := range wd { + if idx != 0 { + wdStr = fmt.Sprintf("%s%s%d", wdStr, sep, d) + } else { + wdStr = strconv.Itoa(int(d)) + } + } + return wdStr +} diff --git a/utils/dateseries_test.go b/utils/dateseries_test.go new file mode 100644 index 000000000..dec14866a --- /dev/null +++ b/utils/dateseries_test.go @@ -0,0 +1,149 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +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 utils + +import ( + "encoding/json" + "reflect" + "testing" + "time" +) + +func TestMonthStoreRestoreJson(t *testing.T) { + m := Months{5, 6, 7, 8} + r, _ := json.Marshal(m) + if string(r) != "[5,6,7,8]" { + t.Errorf("Error serializing months: %v", string(r)) + } + o := Months{} + json.Unmarshal(r, &o) + if !reflect.DeepEqual(o, m) { + t.Errorf("Expected %v was %v", m, o) + } +} + +func TestMonthDayStoreRestoreJson(t *testing.T) { + md := MonthDays{24, 25, 26} + r, _ := json.Marshal(md) + if string(r) != "[24,25,26]" { + t.Errorf("Error serializing month days: %v", string(r)) + } + o := MonthDays{} + json.Unmarshal(r, &o) + if !reflect.DeepEqual(o, md) { + t.Errorf("Expected %v was %v", md, o) + } +} + +func TestWeekDayStoreRestoreJson(t *testing.T) { + wd := WeekDays{time.Saturday, time.Sunday} + r, _ := json.Marshal(wd) + if string(r) != "[6,0]" { + t.Errorf("Error serializing week days: %v", string(r)) + } + o := WeekDays{} + json.Unmarshal(r, &o) + if !reflect.DeepEqual(o, wd) { + t.Errorf("Expected %v was %v", wd, o) + } +} + +func TestYearsSerialize(t *testing.T) { + ys := &Years{} + yString := ys.Serialize(";") + expectString := "*any" + if expectString != yString { + t.Errorf("Expected: %s, got: %s", expectString, yString) + } + ys2 := &Years{2012} + yString2 := ys2.Serialize(";") + expectString2 := "2012" + if expectString2 != yString2 { + t.Errorf("Expected: %s, got: %s", expectString2, yString2) + } + ys3 := &Years{2013, 2014, 2015} + yString3 := ys3.Serialize(";") + expectString3 := "2013;2014;2015" + if expectString3 != yString3 { + t.Errorf("Expected: %s, got: %s", expectString3, yString3) + } +} + +func TestMonthsSerialize(t *testing.T) { + mths := &Months{} + mString := mths.Serialize(";") + expectString := "*any" + if expectString != mString { + t.Errorf("Expected: %s, got: %s", expectString, mString) + } + mths2 := &Months{time.January} + mString2 := mths2.Serialize(";") + expectString2 := "1" + if expectString2 != mString2 { + t.Errorf("Expected: %s, got: %s", expectString2, mString2) + } + mths3 := &Months{time.January, time.December} + mString3 := mths3.Serialize(";") + expectString3 := "1;12" + if expectString3 != mString3 { + t.Errorf("Expected: %s, got: %s", expectString3, mString3) + } +} + +func TestMonthDaysSerialize(t *testing.T) { + mds := &MonthDays{} + mdsString := mds.Serialize(";") + expectString := "*any" + if expectString != mdsString { + t.Errorf("Expected: %s, got: %s", expectString, mdsString) + } + mds2 := &MonthDays{1} + mdsString2 := mds2.Serialize(";") + expectString2 := "1" + if expectString2 != mdsString2 { + t.Errorf("Expected: %s, got: %s", expectString2, mdsString2) + } + mds3 := &MonthDays{1, 2, 3, 4, 5} + mdsString3 := mds3.Serialize(";") + expectString3 := "1;2;3;4;5" + if expectString3 != mdsString3 { + t.Errorf("Expected: %s, got: %s", expectString3, mdsString3) + } +} + +func TestWeekDaysSerialize(t *testing.T) { + wds := &WeekDays{} + wdsString := wds.Serialize(";") + expectString := "*any" + if expectString != wdsString { + t.Errorf("Expected: %s, got: %s", expectString, wdsString) + } + wds2 := &WeekDays{time.Monday} + wdsString2 := wds2.Serialize(";") + expectString2 := "1" + if expectString2 != wdsString2 { + t.Errorf("Expected: %s, got: %s", expectString2, wdsString2) + } + wds3 := &WeekDays{time.Monday, time.Saturday, time.Sunday} + wdsString3 := wds3.Serialize(";") + expectString3 := "1;6;0" + if expectString3 != wdsString3 { + t.Errorf("Expected: %s, got: %s", expectString3, wdsString3) + } +}