timeliness 0.3.3 → 0.3.4

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.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,6 @@
1
+ = 0.3.4 - 2011-05-26
2
+ * Compact time array when creating time in zone so that invalid time handling works properly. Fixes issue#3.
3
+
1
4
  = 0.3.3 - 2011-01-02
2
5
  * Add String core extension for to_time, to_date and to_datetime methods, like ActiveSupport
3
6
  * Allow arbitrary format string as :format option and it will be compiled, if not found.
data/Rakefile CHANGED
@@ -1,16 +1,11 @@
1
- require 'rubygems'
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
2
4
  require 'rake/rdoctask'
3
5
  require 'rspec/core/rake_task'
4
6
 
5
- GEM_NAME = "timeliness"
6
-
7
- desc 'Default: run specs.'
8
- task :default => :spec
9
-
10
7
  desc "Run specs"
11
- RSpec::Core::RakeTask.new do |t|
12
- t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
13
- end
8
+ RSpec::Core::RakeTask.new(:spec)
14
9
 
15
10
  desc "Generate code coverage"
16
11
  RSpec::Core::RakeTask.new(:coverage) do |t|
@@ -27,7 +22,5 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
27
22
  rdoc.rdoc_files.include('lib/**/*.rb')
28
23
  end
29
24
 
30
- desc "Create a gemspec file"
31
- task :build do
32
- `gem build #{GEM_NAME}.gemspec`
33
- end
25
+ desc 'Default: run specs.'
26
+ task :default => :spec
@@ -85,7 +85,7 @@ module Timeliness
85
85
  # regexp and key for format component mapping, if any.
86
86
  #
87
87
  @format_tokens = {
88
- 'ddd' => [ '\w{3,9}', :wday ],
88
+ 'ddd' => [ '\w{3,9}' ],
89
89
  'dd' => [ '\d{2}', :day ],
90
90
  'd' => [ '\d{1,2}', :day ],
91
91
  'mmm' => [ '\w{3,9}', :month ],
@@ -1,4 +1,6 @@
1
1
  module Timeliness
2
+ class CompilationError < StandardError; end
3
+
2
4
  class Format
3
5
  include Helpers
4
6
 
@@ -39,7 +41,7 @@ module Timeliness
39
41
  @regexp = Regexp.new("^(#{format})$")
40
42
  self
41
43
  rescue => ex
42
- raise "The format '#{format_string}' failed to compile using regexp string #{format}. Error: #{ex.inspect}"
44
+ raise CompilationError, "The format '#{format_string}' failed to compile using regexp string #{format}. Error message: #{ex.inspect}"
43
45
  end
44
46
 
45
47
  # Redefined on compile
@@ -27,11 +27,11 @@ module Timeliness
27
27
  end
28
28
 
29
29
  def month_names
30
- defined?(I18n) ? I18n.t('date.month_names') : Date::MONTHNAMES
30
+ i18n_loaded? ? I18n.t('date.month_names') : Date::MONTHNAMES
31
31
  end
32
32
 
33
33
  def abbr_month_names
34
- defined?(I18n) ? I18n.t('date.abbr_month_names') : Date::ABBR_MONTHNAMES
34
+ i18n_loaded? ? I18n.t('date.abbr_month_names') : Date::ABBR_MONTHNAMES
35
35
  end
36
36
 
37
37
  def microseconds(usec)
@@ -45,5 +45,9 @@ module Timeliness
45
45
  (parts[0] + parts[1]) * sign * 3600
46
46
  end
47
47
 
48
+ def i18n_loaded?
49
+ defined?(I18n)
50
+ end
51
+
48
52
  end
49
53
  end
@@ -23,11 +23,10 @@ module Timeliness
23
23
  def make_time(time_array, zone_option=nil)
24
24
  return nil unless fast_date_valid_with_fallback(*time_array[0..2])
25
25
 
26
- zone_or_offset = time_array.delete_at(7)
27
- zone, offset = zone_and_offset(zone_or_offset) if zone_or_offset
26
+ zone, offset = zone_and_offset(time_array[7]) if time_array[7]
28
27
 
29
- value = create_time_in_zone(time_array, zone || zone_option)
30
- value = time_in_zone(value, zone_option) if zone
28
+ value = create_time_in_zone(time_array[0..6].compact, zone || zone_option)
29
+ value = shift_time_to_zone(value, zone_option) if zone
31
30
 
32
31
  offset ? value + (value.utc_offset - offset) : value
33
32
  rescue ArgumentError, TypeError
@@ -36,8 +35,7 @@ module Timeliness
36
35
 
37
36
  def _parse(string, type=nil, options={})
38
37
  if options[:strict] && type
39
- set = Definitions.send("#{type}_format_set")
40
- set.match(string, options[:format])
38
+ Definitions.send("#{type}_format_set").match(string, options[:format])
41
39
  else
42
40
  values = nil
43
41
  Definitions.format_sets(type, string).find {|set| values = set.match(string, options[:format]) }
@@ -96,7 +94,7 @@ module Timeliness
96
94
  end
97
95
  end
98
96
 
99
- def time_in_zone(time, zone=nil)
97
+ def shift_time_to_zone(time, zone=nil)
100
98
  zone ||= Timeliness.default_timezone
101
99
  case zone
102
100
  when :utc, :local
@@ -112,7 +110,7 @@ module Timeliness
112
110
  zone ||= Timeliness.default_timezone
113
111
  case zone
114
112
  when :utc, :local
115
- time_with_datetime_fallback(zone, *time_array.compact)
113
+ time_with_datetime_fallback(zone, *time_array)
116
114
  when :current
117
115
  Time.zone.local(*time_array)
118
116
  else
@@ -1,3 +1,3 @@
1
1
  module Timeliness
2
- VERSION = '0.3.3'
2
+ VERSION = '0.3.4'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -31,7 +31,7 @@ module TimelinessHelpers
31
31
  end
32
32
  end
33
33
 
34
- Rspec.configure do |c|
34
+ RSpec.configure do |c|
35
35
  c.mock_with :rspec
36
36
  c.include TimelinessHelpers
37
37
  end
@@ -1,7 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Timeliness::Format do
4
- context "#process" do
4
+ describe "#compile!" do
5
+ it 'should compile valid string format' do
6
+ expect {
7
+ Timeliness::Format.new('yyyy-mm-dd hh:nn:ss.u zo').compile!
8
+ }.should_not raise_error
9
+ end
10
+
11
+ it 'should return self' do
12
+ format = Timeliness::Format.new('yyyy-mm-dd hh:nn:ss.u zo')
13
+ format.compile!.should == format
14
+ end
15
+
16
+ it 'should raise compilation error for bad format' do
17
+ expect {
18
+ Timeliness::Format.new('|--[)').compile!
19
+ }.should raise_error(Timeliness::CompilationError)
20
+ end
21
+ end
22
+
23
+ describe "#process" do
5
24
  it "should define method which outputs date array with values in correct order" do
6
25
  format_for('yyyy-mm-dd').process('2000', '1', '2').should == [2000,1,2,nil,nil,nil,nil,nil]
7
26
  end
@@ -33,6 +52,45 @@ describe Timeliness::Format do
33
52
  it "should define method which outputs datetime array with timezone string" do
34
53
  format_for('yyyy-mm-dd hh:nn:ss.u tz').process('2001', '02', '03', '04', '05', '06', '99', 'EST').should == [2001,2,3,4,5,6,990000,'EST']
35
54
  end
55
+
56
+ context "with long month" do
57
+ let(:format) { format_for('dd mmm yyyy') }
58
+
59
+ context "with I18n loaded" do
60
+ before(:all) do
61
+ I18n.locale = :es
62
+ I18n.backend.store_translations :es, :date => { :month_names => %w{ ~ Enero Febrero Marzo } }
63
+ I18n.backend.store_translations :es, :date => { :abbr_month_names => %w{ ~ Ene Feb Mar } }
64
+ end
65
+
66
+ it 'should parse abbreviated month for current locale to correct value' do
67
+ format.process('2', 'Ene', '2000').should == [2000,1,2,nil,nil,nil,nil,nil]
68
+ end
69
+
70
+ it 'should parse full month for current locale to correct value' do
71
+ format.process('2', 'Enero', '2000').should == [2000,1,2,nil,nil,nil,nil,nil]
72
+ end
73
+
74
+ after(:all) do
75
+ I18n.locale = :en
76
+ end
77
+ end
78
+
79
+ context "without I18n loaded" do
80
+ before do
81
+ format.stub(:i18n_loaded?).and_return(false)
82
+ I18n.should_not_receive(:t)
83
+ end
84
+
85
+ it 'should parse abbreviated month to correct value' do
86
+ format.process('2', 'Jan', '2000').should == [2000,1,2,nil,nil,nil,nil,nil]
87
+ end
88
+
89
+ it 'should parse full month to correct value' do
90
+ format.process('2', 'January', '2000').should == [2000,1,2,nil,nil,nil,nil,nil]
91
+ end
92
+ end
93
+ end
36
94
  end
37
95
 
38
96
  def format_for(format)
@@ -6,7 +6,7 @@ describe Timeliness::Parser do
6
6
  end
7
7
 
8
8
  describe "parse" do
9
- it "should return time object for valid datetime string" do
9
+ it "should return Time object for valid datetime string" do
10
10
  parse("2000-01-01 12:13:14").should be_kind_of(Time)
11
11
  end
12
12
 
@@ -88,11 +88,35 @@ describe Timeliness::Parser do
88
88
  end
89
89
 
90
90
  context "string with zone abbreviation" do
91
- it 'should return value using string zone in default timezone' do
91
+ before do
92
+ Time.zone = 'Melbourne'
93
+ end
94
+
95
+ it 'should return value using string zone adjusted to default :local timezone' do
96
+ Timeliness.default_timezone = :local
92
97
  value = parse("Thu, 01 Jun 2000 03:00:00 MST")
93
98
  value.should == Time.local(2000,6,1,20,0,0)
94
99
  value.utc_offset.should == 10.hours
95
100
  end
101
+
102
+ it 'should return value using string zone adjusted to default :current timezone' do
103
+ Timeliness.default_timezone = :current
104
+ Time.zone = 'Adelaide'
105
+ value = parse("Thu, 01 Jun 2000 03:00:00 MST")
106
+ value.should == Time.zone.local(2000,6,1,19,30,0)
107
+ value.utc_offset.should == 9.5.hours
108
+ end
109
+
110
+ it 'should return value using string zone adjusted to :zone option string timezone' do
111
+ Timeliness.default_timezone = :local
112
+ value = parse("Thu, 01 Jun 2000 03:00:00 MST", :zone => 'Perth')
113
+ value.should == Time.use_zone('Perth') { Time.zone.local(2000,6,1,18,0,0) }
114
+ value.utc_offset.should == 8.hours
115
+ end
116
+
117
+ after do
118
+ Time.zone = nil
119
+ end
96
120
  end
97
121
 
98
122
  context "with :datetime type" do
@@ -132,12 +156,23 @@ describe Timeliness::Parser do
132
156
  end
133
157
  end
134
158
 
159
+ context "with time value argument" do
160
+ it 'should use argument as :now option value' do
161
+ time = parse("12:13:14", Time.local(2010,1,1))
162
+ time.should == Time.local(2010,1,1,12,13,14)
163
+ end
164
+ end
165
+
135
166
  context "with :zone option" do
136
167
  context ":utc" do
137
168
  it "should return time object in utc timezone" do
138
169
  time = parse("2000-06-01 12:13:14", :datetime, :zone => :utc)
139
170
  time.utc_offset.should == 0
140
171
  end
172
+
173
+ it 'should return nil for partial invalid time component' do
174
+ parse("2000-06-01 12:60", :datetime, :zone => :utc).should be_nil
175
+ end
141
176
  end
142
177
 
143
178
  context ":local" do
@@ -145,6 +180,10 @@ describe Timeliness::Parser do
145
180
  time = parse("2000-06-01 12:13:14", :datetime, :zone => :local)
146
181
  time.utc_offset.should == 10.hours
147
182
  end
183
+
184
+ it 'should return nil for partial invalid time component' do
185
+ parse("2000-06-01 12:60", :datetime, :zone => :local).should be_nil
186
+ end
148
187
  end
149
188
 
150
189
  context ":current" do
@@ -153,6 +192,10 @@ describe Timeliness::Parser do
153
192
  time = parse("2000-06-01 12:13:14", :datetime, :zone => :current)
154
193
  time.utc_offset.should == 9.5.hours
155
194
  end
195
+
196
+ it 'should return nil for partial invalid time component' do
197
+ parse("2000-06-01 12:60", :datetime, :zone => :current).should be_nil
198
+ end
156
199
  end
157
200
 
158
201
  context "named zone" do
@@ -160,6 +203,10 @@ describe Timeliness::Parser do
160
203
  time = parse("2000-06-01 12:13:14", :datetime, :zone => 'London')
161
204
  time.utc_offset.should == 1.hour
162
205
  end
206
+
207
+ it 'should return nil for partial invalid time component' do
208
+ parse("2000-06-01 12:60", :datetime, :zone => 'London').should be_nil
209
+ end
163
210
  end
164
211
 
165
212
  context "without ActiveSupport loaded" do
data/timeliness.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.rubyforge_project = %q{timeliness}
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.files = `git ls-files`.split("\n") - %w{ .gitignore .rspec Gemfile Gemfile.lock }
19
19
  s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc"]
20
20
  s.require_paths = ["lib"]
21
21
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeliness
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 27
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 3
9
- version: 0.3.3
9
+ - 4
10
+ version: 0.3.4
10
11
  platform: ruby
11
12
  authors:
12
13
  - Adam Meehan
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2011-01-02 00:00:00 +11:00
18
+ date: 2011-05-26 00:00:00 +10:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -28,8 +29,6 @@ extra_rdoc_files:
28
29
  - README.rdoc
29
30
  - CHANGELOG.rdoc
30
31
  files:
31
- - .gitignore
32
- - .rspec
33
32
  - CHANGELOG.rdoc
34
33
  - LICENSE
35
34
  - README.rdoc
@@ -65,6 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - ">="
67
66
  - !ruby/object:Gem::Version
67
+ hash: 3
68
68
  segments:
69
69
  - 0
70
70
  version: "0"
@@ -73,20 +73,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
+ hash: 3
76
77
  segments:
77
78
  - 0
78
79
  version: "0"
79
80
  requirements: []
80
81
 
81
82
  rubyforge_project: timeliness
82
- rubygems_version: 1.3.7
83
+ rubygems_version: 1.5.2
83
84
  signing_key:
84
85
  specification_version: 3
85
86
  summary: Date/time parsing for the control freak.
86
- test_files:
87
- - spec/spec_helper.rb
88
- - spec/timeliness/core_ext/string_spec.rb
89
- - spec/timeliness/definitions_spec.rb
90
- - spec/timeliness/format_set_spec.rb
91
- - spec/timeliness/format_spec.rb
92
- - spec/timeliness/parser_spec.rb
87
+ test_files: []
88
+
data/.gitignore DELETED
@@ -1 +0,0 @@
1
- pkg/*
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color