carbon_date 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15ca7832b179451649cfe8cbf847532875ba167b
4
- data.tar.gz: 8131707b3b7d297ead922c9cde6ef1caf0186d17
3
+ metadata.gz: c60c02d57fde03497403333831fb9c699374bd78
4
+ data.tar.gz: 1a65132b4dff055a69503b2c58138482872d11f7
5
5
  SHA512:
6
- metadata.gz: 3fef630e9f37ff2d13d51f97d84e6cfe07d8d841ce645f22adc6686650d4250ab377f7eccddae5d5ad5e66b1e19db6aa858a0048944331eac0ceef372b408b96
7
- data.tar.gz: 3117e099d4ae329636dfe80f9d7c0f203657be0112bd4584d30993076d8f870855ad9744267e7f8b1c3d476e4c5b75dca8d8d30fac3d041c5a1846f68bc2fa83
6
+ metadata.gz: ea46f3105ebf35dbf78b2dc9bfc66ec6e94e35a07fbe28f29db8b65a46e8e186efe02fc0a6d8855424b37dc279605181c2091c8c5ffbb984f4247f510fa55b3f
7
+ data.tar.gz: 02b78be58c703446b079467a916ab7d7f5d154805708e22cdde7ff17c66cd53e2dd853df87017f91db7499690614139278d6f193b2f331145dda9d13a0d719cd
data/.gitignore CHANGED
@@ -8,4 +8,5 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  /test/html_reports/
11
- /*.gem
11
+ /*.gem
12
+ /.coveralls.yml
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
1
  [![Gem Version](http://img.shields.io/gem/v/carbon_date.svg?style=flat-square)](https://rubygems.org/gems/carbon_date)
2
+ [![Coverage Status](https://coveralls.io/repos/github/bradleymarques/carbon_date/badge.svg?branch=master)](https://coveralls.io/github/bradleymarques/carbon_date?branch=master)
3
+ [![Inline docs](http://inch-ci.org/github/bradleymarques/carbon_date.svg?branch=master)](http://inch-ci.org/github/bradleymarques/carbon_date)
2
4
  [![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://bradleymarques.mit-license.org)
3
5
 
4
6
  # CarbonDate
data/carbon_date.gemspec CHANGED
@@ -36,6 +36,8 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency 'pry', '~> 0.10.3', '>= 0.10.3'
37
37
  spec.add_development_dependency 'rdoc', '~> 4.2.2', '>= 4.2.2'
38
38
  spec.add_development_dependency 'mocha', '~> 1.1.0', '>= 1.1.0'
39
+ spec.add_development_dependency 'coveralls', '~> 0.8.13', '>= 0.8.13'
40
+
39
41
 
40
42
  spec.add_dependency 'activesupport', '~> 4.2.6', '>= 4.2.6'
41
43
  end
data/lib/carbon_date.rb CHANGED
@@ -3,6 +3,13 @@ require 'carbon_date/formatter'
3
3
  require 'carbon_date/standard_formatter'
4
4
  require 'carbon_date/version'
5
5
 
6
+ ##
7
+ # Provides a custom implmentation of +Date+ with precision.
8
+ #
9
+ # Classes:
10
+ # - +Date+
11
+ # - +Formatter+
12
+ # - +StandardFormatter+ < +Formatter+
6
13
  module CarbonDate
7
14
 
8
15
 
@@ -4,39 +4,68 @@ require 'carbon_date/standard_formatter'
4
4
  module CarbonDate
5
5
 
6
6
  ##
7
- # A date with a precision
7
+ # Models a date with a precision.
8
+ # The conventions of the Gregorian Calendar are used to model dates.
8
9
  class Date
9
10
 
11
+ # The class-wide Formatter to use to turn CarbonDate::Dates into human-readable strings
10
12
  @formatter = CarbonDate::StandardFormatter.new
11
13
 
12
14
  class << self
15
+ # Used to get and set the CarbonDate::Date.formatter
13
16
  attr_accessor :formatter
14
17
  end
15
18
 
16
19
  ##
17
20
  # The precisions available
18
- #
19
- # TODO: Consider refactoring into a simple array of symbols, since level could be replaced by the index in the array
20
- PRECISION = [
21
- {symbol: :second, level: 14},
22
- {symbol: :minute, level: 13},
23
- {symbol: :hour, level: 12},
24
- {symbol: :day, level: 11},
25
- {symbol: :month, level: 10},
26
- {symbol: :year, level: 9,},
27
- {symbol: :decade, level: 8,},
28
- {symbol: :century, level: 7,},
29
- {symbol: :millennium, level: 6,},
30
- {symbol: :ten_thousand_years, level: 5,},
31
- {symbol: :hundred_thousand_years, level: 4},
32
- {symbol: :million_years, level: 3},
33
- {symbol: :ten_million_years, level: 2},
34
- {symbol: :hundred_million_years, level: 1},
35
- {symbol: :billion_years, level: 0}
21
+ PRECISION =
22
+ [
23
+ :billion_years,
24
+ :hundred_million_years,
25
+ :ten_million_years,
26
+ :million_years,
27
+ :hundred_thousand_years,
28
+ :ten_thousand_years,
29
+ :millennium,
30
+ :century,
31
+ :decade,
32
+ :year,
33
+ :month,
34
+ :day,
35
+ :hour,
36
+ :minute,
37
+ :second
36
38
  ]
37
39
 
38
- attr_reader :precision, :year, :month, :day, :hour, :minute, :second
39
-
40
+ # The date's precision
41
+ attr_reader :precision
42
+ # The date's year. Cannot be 0 as there is no 0 year in the Gregorian Calendar.
43
+ attr_reader :year
44
+ # The date's month in range (1..12)
45
+ attr_reader :month
46
+ # The date's day counting from 1
47
+ attr_reader :day
48
+ # The date's hour in range (0..23)
49
+ attr_reader :hour
50
+ # The date's minute in range (0..59)
51
+ attr_reader :minute
52
+ # The date's second in range (0..59)
53
+ attr_reader :second
54
+
55
+ # Creates a new CarbonDate::Date
56
+ #
57
+ # Params:
58
+ # +year+ - The date's year, as an integer
59
+ # +month+ - The date's month, as an integer
60
+ # +day+ - The date's day, as an integer
61
+ # +hour+ - The date's hour, as an integer
62
+ # +minute+ - The date's minute, as an integer
63
+ # +second+ - The date's second, as an integer
64
+ # +:precision+ - The date's precision, as a symbol. For avaiable options, see CarbonDate::Date::PRECISION
65
+ # Raises:
66
+ # +ArgumentError+ if validations fail
67
+ # Returns:
68
+ # +CarbonDate::Date+ object
40
69
  def initialize(year = 1970, month = 1, day = 1, hour = 0, minute = 0, second = 0, precision: :second)
41
70
  month = 1 if month == 0
42
71
  day = 1 if day == 0
@@ -47,97 +76,76 @@ module CarbonDate
47
76
  self.second = second
48
77
  end
49
78
 
50
- ##
51
79
  # Sets the precision
52
- #
53
- # Raises ArgumentError if invalid symbol
80
+ # Raises +ArgumentError+ if invalid symbol
54
81
  def precision=(value)
55
- p = PRECISION.find { |x| x[:symbol] == value }
56
- raise ArgumentError.new "Invalid precision #{value}" unless p
57
- @precision = p
82
+ raise ArgumentError.new "Invalid precision #{value}" unless PRECISION.include? value
83
+ @precision = value
58
84
  end
59
85
 
60
- ##
61
- # An atomic function to set the date component.
62
- #
63
- # Raises ArgumentError if invalid date
86
+ # An atomic function to set the date component (year, month and day)
87
+ # Raises +ArgumentError+ if invalid date
64
88
  def set_date(year, month, day)
65
-
66
- raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") unless (1..12).include? month
67
- raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") if (year.nil? || year == 0)
68
-
89
+ raise invalid_date if (year.nil? || year == 0 || !((1..12).include? month))
69
90
  begin
70
91
  ::Date.new(year, month, day)
71
92
  rescue ArgumentError
72
- raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}")
93
+ raise invalid_date
73
94
  end
74
-
75
95
  @year = year.to_i
76
96
  @month = month
77
97
  @day = day
78
-
79
98
  end
80
99
 
81
- ##
82
100
  # Sets the year. Calls set_date() to ensure atomicity.
83
101
  def year=(value)
84
102
  set_date(value, @month, @day)
85
103
  end
86
104
 
87
- ##
88
105
  # Sets the month. Calls set_date() to ensure atomicity.
89
- #
90
- # Raises ArgumentError if:
106
+ # Raises +ArgumentError+ if:
91
107
  # - value is not in (1..12)
92
108
  def month=(value)
93
109
  set_date(@year, value, @day)
94
110
  end
95
111
 
96
- ##
97
- # Sets the month. Calls set_date() to ensure atomicity.
98
- #
99
- # Raises ArgumentError if:
112
+ # Sets the day. Calls set_date() to ensure atomicity.
113
+ # Raises +ArgumentError+ if:
100
114
  # - value is not in (1..12)
101
115
  def day=(value)
102
116
  set_date(@year, @month, value)
103
117
  end
104
118
 
105
- ##
106
119
  # Sets the hour with validation
107
- #
108
- # Raises ArgumentError unless in the range (0..23)
120
+ # Raises +ArgumentError+ unless in the range (0..23)
109
121
  def hour=(value)
110
122
  raise ArgumentError.new "Invalid hour #{value}" unless (0..23).include? value
111
123
  @hour = value
112
124
  end
113
125
 
114
- ##
115
126
  # Sets the minute with validation
116
- #
117
- # Raises ArgumentError unless in the range (0..59)
127
+ # Raises +ArgumentError+ unless in the range (0..59)
118
128
  def minute=(value)
119
129
  raise ArgumentError.new "Invalid minute #{value}" unless (0..59).include? value
120
130
  @minute = value
121
131
  end
122
132
 
123
- ##
124
133
  # Sets the second with validation
125
- #
126
- # Raises ArgumentError unless in the range (0..59)
134
+ # Raises +ArgumentError+ unless in the range (0..59)
127
135
  def second=(value)
128
136
  raise ArgumentError.new "Invalid second #{value}" unless (0..59).include? value
129
137
  @second = value
130
138
  end
131
139
 
132
- ##
133
140
  # Converts from an iso8601 datetime format, with precision
134
- #
135
141
  # Dates like these are found on Wikidata (https://www.wikidata.org)
136
- #
142
+ # Params:
137
143
  # +string+ -> the iso8601 datetime in the form +1989-03-23T23:11:08Z
138
144
  # +precision_level+ -> an integer between 0 and 14 (see CarbonDate::Date::PRECISION)
145
+ # Returns:
146
+ # +CarbonDate::Date+ object
139
147
  def self.iso8601(string, precision_level)
140
- p = PRECISION.find { |x| x[:level] == precision_level}
148
+ p = PRECISION[precision_level]
141
149
  raise ArgumentError.new("Invalid precision level #{precision_level}") unless p
142
150
  # If there is an initial '-' symbol on the year, it needs to be treateded differenty than the other '-'.
143
151
  # Example: -0500-01-01 is the 1st January 500 BCE
@@ -149,39 +157,57 @@ module CarbonDate
149
157
  end
150
158
  d = string.split('T').map { |x| x.split(/[-:]/) }.flatten.map(&:to_i)
151
159
  year = bce ? -d[0] : d[0]
152
- CarbonDate::Date.new(year, d[1], d[2], d[3], d[4], d[5], precision: p[:symbol])
160
+ CarbonDate::Date.new(year, d[1], d[2], d[3], d[4], d[5], precision: p)
153
161
  end
154
162
 
155
- ##
156
- # Prints a human-readable version of the date, using a Formatter
163
+ # Prints a human-readable version of the date, using CarbonDate::Date.formatter
157
164
  def to_s
158
165
  CarbonDate::Date.formatter.date_to_string(self)
159
166
  end
160
167
 
161
- ##
162
168
  # Convert to a standard Ruby Date object
169
+ # Returns:
170
+ # +::Date+ object
163
171
  def to_date
164
172
  ::Date.new(@year, @month, @day)
165
173
  end
166
174
 
167
- ##
168
175
  # Convert into a standard Ruby DateTime object
176
+ # Returns:
177
+ # +::DateTime+ object
169
178
  def to_datetime
170
179
  ::DateTime.new(@year, @month, @day, @hour, @minute, @second)
171
180
  end
172
181
 
182
+ # Test equality of two CarbonDate::Dates
183
+ # For equality, the two dates have to have the same:
184
+ # - precision
185
+ # - year
186
+ # - month
187
+ # - day
188
+ # - hour
189
+ # - minute
190
+ # - second
173
191
  def ==(another_date)
174
192
  return false if self.precision != another_date.precision
175
193
  self.to_datetime == another_date.to_datetime
176
194
  end
177
195
 
196
+ # Tests if this CarbonDate::Date is in the past relative to the other CarbonDate::Date
197
+ # Defers to DateTime#<=
178
198
  def <=(another_date)
179
199
  self.to_datetime <= another_date.to_datetime
180
200
  end
181
201
 
202
+ # Tests if this CarbonDate::Date is in the future relative to the other CarbonDate::Date
203
+ # Defers to DateTime#>=
182
204
  def >=(another_date)
183
205
  self.to_datetime >= another_date.to_datetime
184
206
  end
185
207
 
208
+ def invalid_date
209
+ ArgumentError.new("Invalid date #{year}-#{month}-#{day}")
210
+ end
211
+
186
212
  end
187
213
  end
@@ -1,28 +1,46 @@
1
1
  module CarbonDate
2
2
 
3
3
  ##
4
- # Responsible for formatting a CarbonDate::Date to a human-readable string
4
+ # Responsible for formatting a CarbonDate::Date as a human-readable string. Used when CarbonDate::Date#to_s is called.
5
+ #
6
+ # You can extend Formatter to create your own custom output for dates.
7
+ # class MyCustomFormatter < CarbonDate::Formatter
8
+ # def year(date)
9
+ # # ...
10
+ # end
11
+ # # ...
12
+ # end
13
+ #
14
+ # Then, to use your custom formatter, simply do:
15
+ # CarbonDate::Date.formatter = MyCustomFormatter.new
16
+ # All subsequent dates will be formatted using your custom formatter.
17
+ # Implementations of Formatter need to override all of the following methods:
18
+ # - +billion_years(date)+
19
+ # - +hundred_million_years(date)+
20
+ # - +ten_million_years(date)+
21
+ # - +million_years(date)+
22
+ # - +hundred_thousand_years(date)+
23
+ # - +ten_thousand_years(date)+
24
+ # - +millennium(date)+
25
+ # - +century(date)+
26
+ # - +decade(date)+
27
+ # - +year(date)+
28
+ # - +month(date)+
29
+ # - +day(date)+
30
+ # - +hour(date)+
31
+ # - +minute(date)+
32
+ # - +second(date)+
33
+ # All of the above methods take a CarbonDate::Date as a parameter.
5
34
  class Formatter
6
35
 
36
+ ##
37
+ # Formats a CarbonDate::Date object as a human-readable string
7
38
  def date_to_string(date)
8
- precision = date.precision.fetch(:symbol, nil)
9
- case precision
10
- when :billion_years then billion_years(date)
11
- when :hundred_million_years then hundred_million_years(date)
12
- when :ten_million_years then ten_million_years(date)
13
- when :million_years then million_years(date)
14
- when :hundred_thousand_years then hundred_thousand_years(date)
15
- when :ten_thousand_years then ten_thousand_years(date)
16
- when :millennium then millennium(date)
17
- when :century then century(date)
18
- when :decade then decade(date)
19
- when :year then year(date)
20
- when :month then month(date)
21
- when :day then day(date)
22
- when :hour then hour(date)
23
- when :minute then minute(date)
24
- when :second then second(date)
25
- else raise StandardError.new("Unrecognized precision: #{precision}")
39
+ precision = date.precision
40
+ if CarbonDate::Date::PRECISION.include? precision # Call me paranoid: whitelist the available functions
41
+ public_send(precision, date)
42
+ else
43
+ raise StandardError.new("Unrecognized precision: #{precision}")
26
44
  end
27
45
  end
28
46
  end
@@ -6,86 +6,135 @@ module CarbonDate
6
6
  # The default formatter for CarbonDate::Date
7
7
  class StandardFormatter < Formatter
8
8
 
9
- ##
10
9
  # Suffix to use for Before Common Era dates (quite often BCE or BC)
11
10
  BCE_SUFFIX = 'BCE'
12
11
 
12
+ # Collection of strings denoting month names for this Formatter
13
13
  MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
14
14
 
15
- private
16
-
15
+ # Formats a CarbonDate::Date with year precision as a string
16
+ # Returns:
17
+ # A human-readable string representing the Date
17
18
  def year(date)
18
19
  y = date.year.abs.to_s
19
20
  return [y, BCE_SUFFIX].join(' ') if (date.year <= -1)
20
21
  y
21
22
  end
22
23
 
24
+ # Formats a CarbonDate::Date with month precision as a string
25
+ # Returns:
26
+ # A human-readable string representing the Date
23
27
  def month(date)
24
28
  [MONTHS[date.month - 1], year(date)].join(', ')
25
29
  end
26
30
 
31
+ # Formats a CarbonDate::Date with day precision as a string
32
+ # Returns:
33
+ # A human-readable string representing the Date
27
34
  def day(date)
28
35
  [date.day.ordinalize.to_s, month(date)].join(' ')
29
36
  end
30
37
 
38
+ # Formats a CarbonDate::Date with hour precision as a string
39
+ # Returns:
40
+ # A human-readable string representing the Date
31
41
  def hour(date)
32
42
  h = date.minute >= 30 ? date.hour + 1 : date.hour
33
43
  time = [pad(h.to_s), '00'].join(':')
34
44
  [time, day(date)].join(' ')
35
45
  end
36
46
 
47
+ # Formats a CarbonDate::Date with minute precision as a string
48
+ # Returns:
49
+ # A human-readable string representing the Date
37
50
  def minute(date)
38
51
  time = [pad(date.hour.to_s), pad(date.minute.to_s)].join(':')
39
52
  [time, day(date)].join(' ')
40
53
  end
41
54
 
55
+ # Formats a CarbonDate::Date with second precision as a string
56
+ # Returns:
57
+ # A human-readable string representing the Date
42
58
  def second(date)
43
59
  time = [pad(date.hour.to_s), pad(date.minute.to_s), pad(date.second.to_s)].join(':')
44
60
  [time, day(date)].join(' ')
45
61
  end
46
62
 
63
+ # Formats a CarbonDate::Date with decade precision
64
+ # Returns:
65
+ # A human-readable string representing the Date
47
66
  def decade(date)
48
67
  d = ((date.year.abs.to_i / 10) * 10).to_s + 's'
49
68
  return [d, BCE_SUFFIX].join(' ') if (date.year <= -1)
50
69
  d
51
70
  end
52
71
 
72
+ # Formats a CarbonDate::Date with century precision
73
+ # Returns:
74
+ # A human-readable string representing the Date
53
75
  def century(date)
54
76
  c = ((date.year.abs.to_i / 100) + 1).ordinalize + ' century'
55
77
  return [c, BCE_SUFFIX].join(' ') if (date.year <= -1)
56
78
  c
57
79
  end
58
80
 
81
+ # Formats a CarbonDate::Date with millennium precision
82
+ # Returns:
83
+ # A human-readable string representing the Date
59
84
  def millennium(date)
60
85
  m = ((date.year.abs.to_i / 1000) + 1).ordinalize + ' millennium'
61
86
  return [m, BCE_SUFFIX].join(' ') if (date.year <= -1)
62
87
  m
63
88
  end
64
89
 
90
+ # Formats a CarbonDate::Date with ten_thousand_years precision
91
+ # Returns:
92
+ # A human-readable string representing the Date
65
93
  def ten_thousand_years(date)
66
94
  coarse_precision(date.year, 10e3.to_i)
67
95
  end
68
96
 
97
+ # Formats a CarbonDate::Date with hundred_thousand_years precision
98
+ # Returns:
99
+ # A human-readable string representing the Date
69
100
  def hundred_thousand_years(date)
70
101
  coarse_precision(date.year, 100e3.to_i)
71
102
  end
72
103
 
104
+ # Formats a CarbonDate::Date with million_years precision
105
+ # Returns:
106
+ # A human-readable string representing the Date
73
107
  def million_years(date)
74
108
  coarse_precision(date.year, 1e6.to_i)
75
109
  end
76
110
 
111
+ # Formats a CarbonDate::Date with ten_million_years precision
112
+ # Returns:
113
+ # A human-readable string representing the Date
77
114
  def ten_million_years(date)
78
115
  coarse_precision(date.year, 10e6.to_i)
79
116
  end
80
117
 
118
+ # Formats a CarbonDate::Date with hundred_million_years precision
119
+ # Returns:
120
+ # A human-readable string representing the Date
81
121
  def hundred_million_years(date)
82
122
  coarse_precision(date.year, 100e6.to_i)
83
123
  end
84
124
 
125
+ # Formats a CarbonDate::Date with billion_years precision
126
+ # Returns:
127
+ # A human-readable string representing the Date
85
128
  def billion_years(date)
86
129
  coarse_precision(date.year, 1e9.to_i)
87
130
  end
88
131
 
132
+ # A helper function used to format dates that have less than millenium precision
133
+ # Params:
134
+ # +date_year+ The year component of the CarbonDate::Date being formatted
135
+ # +interval+ The precision in years
136
+ # Returns:
137
+ # A human-readable string representing the Date
89
138
  def coarse_precision(date_year, interval)
90
139
 
91
140
  date_year = date_year.to_i
@@ -102,10 +151,26 @@ module CarbonDate
102
151
  nil
103
152
  end
104
153
 
154
+ # Converts an integer number into a human-readable string with thousands delimiters.
155
+ # Example:
156
+ # number_with_delimiter(1234567890, ',')
157
+ # => 1,234,567,890
158
+ # Params:
159
+ # +n+ the number to be delimited. Will be converted to an integer
160
+ # +delim+ the string to be used as the thousands delimiter. Defaults to ','
105
161
  def number_with_delimiter(n, delim = ',')
106
162
  n.to_i.to_s.reverse.chars.each_slice(3).map(&:join).join(delim).reverse
107
163
  end
108
164
 
165
+ # Pad a string with '0' to ensure it has two characters.
166
+ # If a string of 2 or more characters is used as parameter, will not alter the string.
167
+ # Example:
168
+ # pad('1')
169
+ # => "01"
170
+ # Params:
171
+ # +s+ The string to pad.
172
+ # Returns:
173
+ # A string of at least 2 characters
109
174
  def pad(s)
110
175
  s.rjust(2, '0')
111
176
  end
@@ -1,3 +1,3 @@
1
1
  module CarbonDate
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carbon_date
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bradley Marques
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-12 00:00:00.000000000 Z
11
+ date: 2016-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -184,6 +184,26 @@ dependencies:
184
184
  - - ">="
185
185
  - !ruby/object:Gem::Version
186
186
  version: 1.1.0
187
+ - !ruby/object:Gem::Dependency
188
+ name: coveralls
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: 0.8.13
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: 0.8.13
197
+ type: :development
198
+ prerelease: false
199
+ version_requirements: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - "~>"
202
+ - !ruby/object:Gem::Version
203
+ version: 0.8.13
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: 0.8.13
187
207
  - !ruby/object:Gem::Dependency
188
208
  name: activesupport
189
209
  requirement: !ruby/object:Gem::Requirement