timeliness 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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