time_spanner 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +13 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +60 -0
  8. data/Rakefile +11 -0
  9. data/lib/time_spanner.rb +8 -0
  10. data/lib/time_spanner/duration_chain.rb +55 -0
  11. data/lib/time_spanner/errors.rb +8 -0
  12. data/lib/time_spanner/time_span.rb +34 -0
  13. data/lib/time_spanner/time_unit_collector.rb +59 -0
  14. data/lib/time_spanner/time_units.rb +17 -0
  15. data/lib/time_spanner/time_units/base/calendar_unit.rb +30 -0
  16. data/lib/time_spanner/time_units/base/time_unit.rb +39 -0
  17. data/lib/time_spanner/time_units/base/unit.rb +31 -0
  18. data/lib/time_spanner/time_units/century.rb +30 -0
  19. data/lib/time_spanner/time_units/day.rb +25 -0
  20. data/lib/time_spanner/time_units/decade.rb +25 -0
  21. data/lib/time_spanner/time_units/hour.rb +15 -0
  22. data/lib/time_spanner/time_units/microsecond.rb +15 -0
  23. data/lib/time_spanner/time_units/millennium.rb +25 -0
  24. data/lib/time_spanner/time_units/millisecond.rb +15 -0
  25. data/lib/time_spanner/time_units/minute.rb +15 -0
  26. data/lib/time_spanner/time_units/month.rb +25 -0
  27. data/lib/time_spanner/time_units/nanosecond.rb +15 -0
  28. data/lib/time_spanner/time_units/second.rb +15 -0
  29. data/lib/time_spanner/time_units/week.rb +25 -0
  30. data/lib/time_spanner/time_units/year.rb +25 -0
  31. data/lib/time_spanner/version.rb +3 -0
  32. data/test/test_helper.rb +9 -0
  33. data/test/time_spanner/duration_chain_test.rb +267 -0
  34. data/test/time_spanner/time_spanner_test.rb +27 -0
  35. data/test/time_spanner/time_unit_collector_test.rb +66 -0
  36. data/test/time_spanner/time_units/base/calendar_unit_test.rb +17 -0
  37. data/test/time_spanner/time_units/base/time_unit_test.rb +18 -0
  38. data/test/time_spanner/time_units/base/unit_test.rb +37 -0
  39. data/test/time_spanner/time_units/century_test.rb +55 -0
  40. data/test/time_spanner/time_units/day_test.rb +84 -0
  41. data/test/time_spanner/time_units/decade_test.rb +67 -0
  42. data/test/time_spanner/time_units/hour_test.rb +56 -0
  43. data/test/time_spanner/time_units/microsecond_test.rb +56 -0
  44. data/test/time_spanner/time_units/millennium_test.rb +69 -0
  45. data/test/time_spanner/time_units/millisecond_test.rb +56 -0
  46. data/test/time_spanner/time_units/minute_test.rb +84 -0
  47. data/test/time_spanner/time_units/month_test.rb +68 -0
  48. data/test/time_spanner/time_units/nanosecond_test.rb +40 -0
  49. data/test/time_spanner/time_units/second_test.rb +56 -0
  50. data/test/time_spanner/time_units/week_test.rb +55 -0
  51. data/test/time_spanner/time_units/year_test.rb +91 -0
  52. data/time_spanner.gemspec +23 -0
  53. metadata +143 -0
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ class TimeSpannerTest < TestCase
5
+ include Errors
6
+
7
+ it 'creates a span instance' do
8
+ from = Time.now
9
+ to = from + 1
10
+ span = TimeSpan.new(from, to)
11
+
12
+ assert span.is_a?(TimeSpan)
13
+ assert span.kind_of?(Hash)
14
+ end
15
+
16
+ it 'ensures converting to Time' do
17
+ InvalidClass = Class.new do
18
+ def to_time; false end
19
+ end
20
+
21
+ assert_raises InvalidClassError do
22
+ TimeSpan.new(InvalidClass.new, InvalidClass.new)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,66 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+
5
+ class TimeUnitCollectorTest < TestCase
6
+ include TimeUnits
7
+ include Errors
8
+
9
+ before do
10
+ @now = Time.now
11
+ end
12
+
13
+ it 'initializes' do
14
+ collector = TimeUnitCollector.new [:hours]
15
+
16
+ assert_equal [:hours], collector.unit_names
17
+ end
18
+
19
+ it 'validates time units' do
20
+ assert_raises InvalidUnitError do
21
+ TimeUnitCollector.new [:days, :something]
22
+ end
23
+ end
24
+
25
+ describe "collecting unit names" do
26
+
27
+ it 'should use all unit names when if no units are given (no parameter given)' do
28
+ collector = TimeUnitCollector.new
29
+
30
+ assert_equal TimeUnitCollector::AVAILABLE_UNITS, collector.unit_names
31
+ end
32
+
33
+ it 'should use all unit names when if no units are given (nil given)' do
34
+ collector = TimeUnitCollector.new nil
35
+
36
+ assert_equal TimeUnitCollector::AVAILABLE_UNITS, collector.unit_names
37
+ end
38
+
39
+ it 'should use all unit names when if no units are given (empty Array given)' do
40
+ collector = TimeUnitCollector.new []
41
+
42
+ assert_equal TimeUnitCollector::AVAILABLE_UNITS, collector.unit_names
43
+ end
44
+
45
+ end
46
+
47
+ describe "mapping units" do
48
+
49
+ it 'should map all units' do
50
+ collector = TimeUnitCollector.new
51
+
52
+ expected = [Millennium, Century, Decade, Year, Month, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond]
53
+ assert_equal expected, collector.units
54
+ end
55
+
56
+ it 'should map some units' do
57
+ collector = TimeUnitCollector.new [:days, :hours, :minutes]
58
+
59
+ assert_equal [Day, Hour, Minute], collector.units
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class CalendarUnitTest < TestCase
7
+
8
+ it 'initializes' do
9
+ time_unit = CalendarUnit.new(1)
10
+
11
+ assert time_unit.is_a?(CalendarUnit)
12
+ assert_equal 1, time_unit.position
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class TimeUnitTest < TestCase
7
+
8
+ it 'initializes' do
9
+ time_unit = TimeUnit.new(1, 1)
10
+
11
+ assert time_unit.is_a?(TimeUnit)
12
+ assert_equal 1, time_unit.position
13
+ assert_equal 1, time_unit.multiplier
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class UnitTest < TestCase
7
+
8
+ it 'initializes' do
9
+ time_unit = Unit.new(1)
10
+
11
+ assert time_unit.is_a?(Unit)
12
+ assert_equal 1, time_unit.position
13
+ assert_equal 0, time_unit.amount
14
+ assert_equal 0, time_unit.rest
15
+ end
16
+
17
+ it "compares: Day should be in front of Hour" do
18
+ day = Day.new
19
+ hour = Hour.new
20
+
21
+ assert_equal -1, day.<=>(hour)
22
+ end
23
+
24
+ it "reverses!" do
25
+ second = Second.new
26
+ second.calculate 1
27
+
28
+ assert_equal 1, second.amount
29
+
30
+ second.reverse!
31
+
32
+ assert_equal -1, second.amount
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class CenturyTest < TestCase
7
+
8
+ it 'initializes' do
9
+ century = Century.new
10
+
11
+ assert century.kind_of?(CalendarUnit)
12
+ assert_equal 2, century.position
13
+ assert_equal :centuries, century.plural_name
14
+ end
15
+
16
+ it 'calculates without rest' do
17
+ from = Time.parse('2013-04-01 00:00:00')
18
+ to = Time.parse('2213-04-01 00:00:00')
19
+ duration = to.to_r - from.to_r
20
+ century = Century.new
21
+
22
+ century.calculate duration, to
23
+
24
+ assert_equal 2, century.amount
25
+ assert_equal 0, century.rest
26
+ end
27
+
28
+ it 'calculates with rest (1 day in seconds)' do
29
+ from = Time.parse('2013-01-01 00:00:00')
30
+ to = Time.parse('2213-01-02 00:00:00')
31
+ duration = to.to_r - from.to_r
32
+ century = Century.new
33
+
34
+ century.calculate duration, to
35
+
36
+ assert_equal 2, century.amount
37
+ assert_equal 86400, century.rest
38
+ end
39
+
40
+ it 'should not calculate amount of 2 although units equal' do
41
+ from = Time.parse '2012-06-12 00:00:00'
42
+ time_at_centuries = Time.parse '2212-06-12 00:00:00'
43
+ to = Time.at time_at_centuries.to_r, -0.001
44
+ duration = to.to_r - from.to_r
45
+ century = Century.new
46
+
47
+ century.calculate duration, to
48
+
49
+ assert_equal 1, century.amount
50
+ assert century.rest > 0
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,84 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class DayTest < TestCase
7
+
8
+ it 'initializes' do
9
+ day = Day.new
10
+
11
+ assert day.kind_of?(CalendarUnit)
12
+ assert_equal 7, day.position
13
+ assert_equal :days, day.plural_name
14
+ end
15
+
16
+ it 'calculates without rest' do
17
+ from = Time.parse('2013-04-03 00:00:00')
18
+ to = Time.parse('2013-04-05 00:00:00')
19
+ duration = to.to_r - from.to_r
20
+ day = Day.new
21
+
22
+ day.calculate duration, to
23
+
24
+ assert_equal 2, day.amount
25
+ assert_equal 0, day.rest
26
+ end
27
+
28
+ it 'calculates with rest' do
29
+ from = Time.parse('2013-04-03 00:00:00')
30
+ target_days = Time.parse('2013-04-05 00:00:00')
31
+ to = Time.at(target_days.to_time.to_r, 0.999)
32
+ duration = to.to_r - from.to_r
33
+ day = Day.new
34
+
35
+ day.calculate duration, to
36
+
37
+ assert_equal 2, day.amount
38
+ assert_equal Rational(8998192055486251, 9007199254740992000000), day.rest
39
+ end
40
+
41
+ it 'should not calculate amount of 2 although units equal' do
42
+ from = Time.parse '2012-06-12 23:00:00'
43
+ time_at_days = Time.parse '2012-06-14 23:00:00'
44
+ to = Time.at time_at_days.to_r, -0.001
45
+ duration = to.to_r - from.to_r
46
+ day = Day.new
47
+
48
+ day.calculate duration, to
49
+
50
+ assert_equal 1, day.amount
51
+ assert day.rest > 0
52
+ end
53
+
54
+ describe 'leap days' do
55
+
56
+ it 'calculates correctly without leap day' do
57
+ from = Time.parse('2013-01-01 00:00:00')
58
+ to = Time.parse('2014-01-01 00:00:00')
59
+ duration = to.to_r - from.to_r
60
+ day = Day.new
61
+
62
+ day.calculate duration, to
63
+
64
+ assert_equal 365, day.amount
65
+ assert_equal 0, day.rest
66
+ end
67
+
68
+ it 'calculates correctly on leap day' do
69
+ from = Time.parse('2012-01-01 00:00:00') # leap year
70
+ to = Time.parse('2013-01-01 00:00:00')
71
+ duration = to.to_r - from.to_r
72
+ day = Day.new
73
+
74
+ day.calculate duration, to
75
+
76
+ assert_equal 366, day.amount
77
+ assert_equal 0, day.rest
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class DecadeTest < TestCase
7
+
8
+ it 'initializes' do
9
+ decade = Decade.new
10
+
11
+ assert decade.kind_of?(CalendarUnit)
12
+ assert_equal 3, decade.position
13
+ assert_equal :decades, decade.plural_name
14
+ end
15
+
16
+ it 'calculates without rest' do
17
+ from = Time.parse('2023-04-01 00:00:00')
18
+ to = Time.parse('2043-04-01 00:00:00')
19
+ duration = to.to_r - from.to_r
20
+ decade = Decade.new
21
+
22
+ decade.calculate duration, to
23
+
24
+ assert_equal 2, decade.amount
25
+ assert_equal 0, decade.rest
26
+ end
27
+
28
+ it 'calculates with rest (1 second)' do
29
+ from = Time.parse('2013-01-01 00:00:00')
30
+ to = Time.parse('2033-01-01 00:00:01')
31
+ duration = to.to_r - from.to_r
32
+ decade = Decade.new
33
+
34
+ decade.calculate duration, to
35
+
36
+ assert_equal 2, decade.amount
37
+ assert_equal 1, decade.rest
38
+ end
39
+
40
+ it 'should not calculate amount of 2 although units equal' do
41
+ from = Time.parse '2012-06-12 00:00:00'
42
+ time_at_decades = Time.parse '2032-06-12 00:00:00'
43
+ to = Time.at time_at_decades.to_r, -0.001
44
+ duration = to.to_r - from.to_r
45
+ decade = Decade.new
46
+
47
+ decade.calculate duration, to
48
+
49
+ assert_equal 1, decade.amount
50
+ assert decade.rest > 0
51
+ end
52
+
53
+ it 'calculates correctly on exact leap day' do
54
+ from = Time.parse('2012-02-29 00:00:00') # leap year
55
+ to = Time.parse('2022-02-28 00:00:00')
56
+ duration = to.to_r - from.to_r
57
+ decade = Decade.new
58
+
59
+ decade.calculate duration, to
60
+
61
+ assert_equal 1, decade.amount
62
+ assert_equal 0, decade.rest
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class HourTest < TestCase
7
+
8
+ it 'initializes' do
9
+ hour = Hour.new
10
+
11
+ assert hour.kind_of?(TimeUnit)
12
+ assert_equal 8, hour.position
13
+ assert_equal :hours, hour.plural_name
14
+ end
15
+
16
+ it 'calculates without rest' do
17
+ from = Time.parse('2013-04-03 00:00:00')
18
+ to = Time.parse('2013-04-03 02:00:00')
19
+ duration = to.to_r - from.to_r
20
+ hour = Hour.new
21
+
22
+ hour.calculate duration
23
+
24
+ assert_equal 2, hour.amount
25
+ assert_equal 0, hour.rest
26
+ end
27
+
28
+ it 'calculates with rest (999 Nanoseconds in seconds)' do
29
+ from = Time.parse('2013-04-03 00:00:00')
30
+ target_hours = Time.parse('2013-04-03 02:00:00')
31
+ to = Time.at(target_hours.to_r, 0.999)
32
+ duration = to.to_r - from.to_r
33
+ hour = Hour.new
34
+
35
+ hour.calculate duration
36
+
37
+ assert_equal 2, hour.amount
38
+ assert_equal Rational(8998192055486251, 9007199254740992000000), hour.rest
39
+ end
40
+
41
+ it 'should not calculate amount of 2 although units equal' do
42
+ from = Time.parse '2012-06-12 02:22:00'
43
+ time_at_hours = Time.parse '2012-06-12 04:22:00'
44
+ to = Time.at time_at_hours.to_r, -0.001
45
+ duration = to.to_r - from.to_r
46
+ hour = Hour.new
47
+
48
+ hour.calculate duration, to
49
+
50
+ assert_equal 1, hour.amount
51
+ assert hour.rest > 0
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+ module TimeUnits
5
+
6
+ class MicrosecondTest < TestCase
7
+
8
+ it 'initializes' do
9
+ microsecond = Microsecond.new
10
+
11
+ assert microsecond.kind_of?(TimeUnit)
12
+ assert_equal 12, microsecond.position
13
+ assert_equal :microseconds, microsecond.plural_name
14
+ end
15
+
16
+ it 'calculates' do
17
+ from = Time.now
18
+ to = Time.at(from.to_r, 2.0)
19
+ duration = to.to_r - from.to_r
20
+ microsecond = Microsecond.new
21
+
22
+ microsecond.calculate duration
23
+
24
+ assert_equal 2, microsecond.amount
25
+ assert_equal 0, microsecond.rest
26
+ end
27
+
28
+ it 'calculates with rest (999 nanoseconds in seconds)' do
29
+ from = Time.now
30
+ target_micros = Time.at(from.to_r, 2.0)
31
+ to = Time.at(target_micros.to_r, 0.999)
32
+ duration = to.to_r - from.to_r
33
+ microsecond = Microsecond.new
34
+
35
+ microsecond.calculate duration
36
+
37
+ assert_equal 2, microsecond.amount
38
+ assert_equal Rational(8998192055486251, 9007199254740992000000), microsecond.rest
39
+ end
40
+
41
+ it 'should not calculate amount of 2 although units equal' do
42
+ from = Time.parse '2012-06-12 02:22:00'
43
+ time_at_microseconds = Time.at(from.to_r, 2.0)
44
+ to = Time.at time_at_microseconds.to_r, -0.001
45
+ duration = to.to_r - from.to_r
46
+ microsecond = Microsecond.new
47
+
48
+ microsecond.calculate duration, to
49
+
50
+ assert_equal 1, microsecond.amount
51
+ assert microsecond.rest > 0
52
+ end
53
+
54
+ end
55
+ end
56
+ end