dotiw 0.4.1 → 0.6.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.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  tmp
2
2
  pkg
3
3
  spec/fixtures/database.yml
4
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dotiw (0.6.0)
5
+ actionpack (~> 3.0.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ abstract (1.0.0)
11
+ actionpack (3.0.3)
12
+ activemodel (= 3.0.3)
13
+ activesupport (= 3.0.3)
14
+ builder (~> 2.1.2)
15
+ erubis (~> 2.6.6)
16
+ i18n (~> 0.4)
17
+ rack (~> 1.2.1)
18
+ rack-mount (~> 0.6.13)
19
+ rack-test (~> 0.5.6)
20
+ tzinfo (~> 0.3.23)
21
+ activemodel (3.0.3)
22
+ activesupport (= 3.0.3)
23
+ builder (~> 2.1.2)
24
+ i18n (~> 0.4)
25
+ activesupport (3.0.3)
26
+ builder (2.1.2)
27
+ diff-lcs (1.1.2)
28
+ erubis (2.6.6)
29
+ abstract (>= 1.0.0)
30
+ i18n (0.5.0)
31
+ rack (1.2.1)
32
+ rack-mount (0.6.13)
33
+ rack (>= 1.0.0)
34
+ rack-test (0.5.6)
35
+ rack (>= 1.0)
36
+ rspec (2.3.0)
37
+ rspec-core (~> 2.3.0)
38
+ rspec-expectations (~> 2.3.0)
39
+ rspec-mocks (~> 2.3.0)
40
+ rspec-core (2.3.1)
41
+ rspec-expectations (2.3.0)
42
+ diff-lcs (~> 1.1.2)
43
+ rspec-mocks (2.3.0)
44
+ tzinfo (0.3.23)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ actionpack (~> 3.0.0)
51
+ bundler (~> 1.0.0)
52
+ dotiw!
53
+ rspec (~> 2.0)
54
+
55
+ METADATA
56
+ version: 1.0.6
data/README.markdown CHANGED
@@ -137,5 +137,6 @@ If you want to calculate a distance of time in percent, use `distance_of_time_in
137
137
 
138
138
  ## Contributors
139
139
 
140
- chendo - for talking through it with me and drawing on the whiteboard
141
- Derander - correct Spanish translations
140
+ * [chendo][http://github.com/chendo] - for talking through it with me and drawing on the whiteboard
141
+ * [Derander][http://github.com/derander] - correct Spanish translations
142
+ * [DBA][http://github.com/dba] - Commits leading up to the 0.6 release.
data/Rakefile CHANGED
@@ -1,50 +1,13 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
3
6
 
4
7
  begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "dotiw"
8
- gem.summary = %Q{Better distance_of_time_in_words for Rails}
9
- gem.description = %Q{Better distance_of_time_in_words for Rails}
10
- gem.email = "radarlistener@gmail.com"
11
- gem.homepage = "http://github.com/radar/dotiw"
12
- gem.authors = ["Ryan Bigg"]
13
- gem.add_development_dependency "rspec"
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
- end
16
- Jeweler::GemcutterTasks.new
8
+ require 'rspec/core/rake_task'
9
+ [:spec, :rcov].each { |task| RSpec::Core::RakeTask.new(task) }
10
+ task :default => :spec
17
11
  rescue LoadError
18
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
- end
20
-
21
- require 'spec/rake/spectask'
22
- Spec::Rake::SpecTask.new(:spec) do |spec|
23
- spec.libs << 'lib' << 'spec'
24
- spec.spec_files = FileList['spec/**/*_spec.rb']
25
- end
26
-
27
- Spec::Rake::SpecTask.new(:rcov) do |spec|
28
- spec.libs << 'lib' << 'spec'
29
- spec.pattern = 'spec/**/*_spec.rb'
30
- spec.rcov = true
31
- end
32
-
33
- task :spec => :check_dependencies
34
-
35
- task :default => :spec
36
-
37
- require 'rake/rdoctask'
38
- Rake::RDocTask.new do |rdoc|
39
- if File.exist?('VERSION')
40
- version = File.read('VERSION')
41
- else
42
- version = ""
43
- end
44
-
45
- rdoc.rdoc_dir = 'rdoc'
46
- rdoc.title = "dotiw #{version}"
47
- rdoc.rdoc_files.include('README*')
48
- rdoc.rdoc_files.include('lib/**/*.rb')
49
- end
50
-
12
+ raise 'RSpec could not be loaded. Run `bundle install` to get all development dependencies.'
13
+ end
data/dotiw.gemspec CHANGED
@@ -1,55 +1,28 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
1
+ # dotiw.gemspec
4
2
  # -*- encoding: utf-8 -*-
5
3
 
6
- Gem::Specification.new do |s|
7
- s.name = %q{dotiw}
8
- s.version = "0.4.1"
4
+ $:.unshift File.join(File.dirname(__FILE__), 'lib') unless $:.include? File.join(File.dirname(__FILE__), 'lib')
5
+ require 'dotiw/version'
9
6
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ Gem::Specification.new do |s|
8
+ s.name = 'dotiw'
9
+ s.version = DOTIW::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.required_rubygems_version = '>= 1.3.6'
11
12
  s.authors = ["Ryan Bigg"]
12
- s.date = %q{2010-10-02}
13
- s.description = %q{Better distance_of_time_in_words for Rails}
14
- s.email = %q{radarlistener@gmail.com}
15
- s.extra_rdoc_files = [
16
- "README.markdown"
17
- ]
18
- s.files = [
19
- ".gitignore",
20
- "MIT-LICENSE",
21
- "README.markdown",
22
- "Rakefile",
23
- "VERSION",
24
- "dotiw.gemspec",
25
- "lib/dotiw.rb",
26
- "rails/init.rb",
27
- "spec/dotiw_spec.rb",
28
- "spec/spec_helper.rb",
29
- "spec/translations/en.yml",
30
- "spec/translations/es.yml"
31
- ]
32
- s.homepage = %q{http://github.com/radar/dotiw}
33
- s.rdoc_options = ["--charset=UTF-8"]
34
- s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.7}
36
- s.summary = %q{Better distance_of_time_in_words for Rails}
37
- s.test_files = [
38
- "spec/dotiw_spec.rb",
39
- "spec/spec_helper.rb"
40
- ]
13
+ s.date = %q{2010-12-23}
14
+ s.description = "Better distance_of_time_in_words for Rails"
15
+ s.summary = "Better distance_of_time_in_words for Rails"
16
+ s.email = "radarlistener@gmail.com"
41
17
 
42
- if s.respond_to? :specification_version then
43
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
- s.specification_version = 3
18
+ s.add_dependency "actionpack", "~> 3.0.0"
19
+
20
+ s.add_development_dependency "bundler", "~> 1.0.0"
21
+ s.add_development_dependency "rspec", "~> 2.0"
45
22
 
46
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
- s.add_development_dependency(%q<rspec>, [">= 0"])
48
- else
49
- s.add_dependency(%q<rspec>, [">= 0"])
50
- end
51
- else
52
- s.add_dependency(%q<rspec>, [">= 0"])
53
- end
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
54
27
  end
55
28
 
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rails/init'
data/lib/dotiw.rb CHANGED
@@ -1,122 +1,77 @@
1
1
  # encoding: utf-8
2
+
3
+ module DOTIW
4
+ autoload :VERSION, 'dotiw/version'
5
+ autoload :TimeHash, 'dotiw/time_hash'
6
+ end # DOTIW
7
+
2
8
  module ActionView
3
9
  module Helpers
4
10
  module DateHelper
5
- def distance_of_time_in_words_hash(from_time, to_time, options={})
6
- from_time = from_time.to_time if from_time.respond_to?(:to_time)
7
- to_time = to_time.to_time if to_time.respond_to?(:to_time)
8
-
9
- distance = (from_time - to_time).abs
10
- distance_of_time_hash(distance, from_time, to_time, options)
11
- end
12
-
13
- def distance_of_time_hash(distance, from_time = nil, to_time = nil, options={})
14
- output = HashWithIndifferentAccess.new
15
- from_time ||= Time.now
16
- to_time ||= from_time + distance.seconds
17
- I18n.with_options :locale => options[:locale] do |locale|
18
- while distance > 0
19
- if distance < 1.minute
20
- output[locale.t(:seconds, :default => "seconds")] = distance.to_i
21
- distance = 0
22
- elsif distance < 1.hour
23
- output[locale.t(:minutes, :default => "minutes")], distance = distance.divmod(1.minute)
24
- elsif distance < 1.day
25
- output[locale.t(:hours, :default => "hours")], distance = distance.divmod(1.hour)
26
- elsif distance < 28.days
27
- output[locale.t(:days, :default => "days")], distance = distance.divmod(1.day)
28
- # Time has to be greater than a month
29
- else
30
- smallest, largest = from_time < to_time ? [from_time, to_time] : [to_time, from_time]
31
-
32
- months = (largest.year - smallest.year) * 12 + (largest.month - smallest.month)
33
- years, months = months.divmod(12)
34
-
35
- days = largest.day - smallest.day
36
-
37
- # Will otherwise incorrectly say one more day if our range goes over a day.
38
- days -= 1 if largest.hour < smallest.hour
39
-
40
- if days < 0
41
- # Convert the last month to days and add to total
42
- months -= 1
43
- last_month = largest.advance(:months => -1)
44
- days += Time.days_in_month(last_month.month, last_month.year)
45
- end
46
-
47
- if months < 0
48
- # Convert a year to months
49
- years -= 1
50
- months += 12
51
- end
52
-
53
- output[locale.t(:years, :default => "years")] = years
54
- output[locale.t(:months, :default => "months")] = months
55
- output[locale.t(:days, :default => "days")] = days
56
-
57
- total_days, distance = distance.divmod(1.day)
58
- end
59
- end
60
- end
61
- output
62
- end
63
-
64
11
  alias_method :old_distance_of_time_in_words, :distance_of_time_in_words
65
-
12
+
13
+ def distance_of_time_in_words_hash(from_time, to_time, options = {})
14
+ from_time = from_time.to_time if !from_time.is_a?(Time) && from_time.respond_to?(:to_time)
15
+ to_time = to_time.to_time if !to_time.is_a?(Time) && to_time.respond_to?(:to_time)
16
+
17
+ DOTIW::TimeHash.new((from_time - to_time).abs, from_time, to_time, options).to_hash
18
+ end
19
+
66
20
  def distance_of_time(seconds, options = {})
67
- display_time_in_words(distance_of_time_hash(seconds), options)
21
+ display_time_in_words DOTIW::TimeHash.new(seconds).to_hash, options
68
22
  end
69
-
23
+
70
24
  def display_time_in_words(hash, include_seconds = false, options = {})
71
25
  options.symbolize_keys!
72
- hash.delete(:seconds) if !include_seconds && hash[:minutes]
73
- I18n.with_options :locale => options[:locale] do |locale|
74
- # Remove all the values that are nil.
75
- time_measurements = [locale.t(:years, :default => "years"),
76
- locale.t(:months, :default => "months"),
77
- locale.t(:weeks, :default => "weeks"),
78
- locale.t(:days, :default => "days"),
79
- locale.t(:hours, :default => "hours"),
80
- locale.t(:minutes, :default => "minutes"),
81
- locale.t(:seconds, :default => "seconds")].delete_if do |key|
82
- hash[key].nil? || hash[key].zero? ||
83
- # Remove the keys that we don't want.
84
- (!options[:except].nil? && options[:except].include?(key)) ||
85
- # keep the keys we only want.
26
+ I18n.locale = options[:locale] if options[:locale]
27
+
28
+ time_measurements = { :years => I18n.t(:years, :default => "years"),
29
+ :months => I18n.t(:months, :default => "months"),
30
+ :weeks => I18n.t(:weeks, :default => "weeks"),
31
+ :days => I18n.t(:days, :default => "days"),
32
+ :hours => I18n.t(:hours, :default => "hours"),
33
+ :minutes => I18n.t(:minutes, :default => "minutes"),
34
+ :seconds => I18n.t(:seconds, :default => "seconds") }
35
+
36
+ hash.delete(time_measurements[:seconds]) if !include_seconds && hash[time_measurements[:minutes]]
37
+
38
+ # Remove all the values that are nil or excluded. Keep the required ones.
39
+ time_measurements.delete_if do |measure, key|
40
+ hash[key].nil? || hash[key].zero? || (!options[:except].nil? && options[:except].include?(key)) ||
86
41
  (options[:only] && !options[:only].include?(key))
87
- end
88
-
89
- options.delete(:except)
90
- options.delete(:only)
91
- output = []
92
- time_measurements.each do |key|
93
- name = hash[key] > 1 ? key : key.singularize
94
- output += ["#{hash[key]} #{name}"]
95
- end
96
-
97
- # maybe only grab the first few values
98
- if options[:precision]
99
- output = output[0...options[:precision]]
100
- options.delete(:precision)
101
- end
102
-
103
-
104
- output.to_sentence(options)
105
42
  end
43
+
44
+ options.delete(:except)
45
+ options.delete(:only)
46
+
47
+ output = []
48
+
49
+ time_measurements.each do |measure, key|
50
+ name = hash[key] > 1 ? key : key.singularize
51
+ output += ["#{hash[key]} #{name}"]
52
+ end
53
+
54
+ # maybe only grab the first few values
55
+ if options[:precision]
56
+ output = output[0...options[:precision]]
57
+ options.delete(:precision)
58
+ end
59
+
60
+ output.to_sentence(options)
106
61
  end
107
-
62
+
108
63
  def distance_of_time_in_words(from_time, to_time, include_seconds = false, options = {})
109
64
  return old_distance_of_time_in_words(from_time, to_time, include_seconds, options) if options.delete(:vague)
110
65
  hash = distance_of_time_in_words_hash(from_time, to_time, options)
111
66
  display_time_in_words(hash, include_seconds, options)
112
67
  end
113
-
68
+
114
69
  def distance_of_time_in_percent(from_time, current_time, to_time, options = {})
115
70
  options[:precision] ||= 0
116
71
  distance = to_time - from_time
117
- number_with_precision(((current_time - from_time) / distance) * 100, options).to_s + "%"
72
+ result = ((current_time - from_time) / distance) * 100
73
+ number_with_precision(result, options).to_s + "%"
118
74
  end
119
- end
120
- end
121
- end
122
-
75
+ end # DateHelper
76
+ end # Helpers
77
+ end # ActionView
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+
3
+ module DOTIW
4
+ class TimeHash
5
+ TIME_FRACTIONS = [:seconds, :minutes, :hours, :days, :months, :years]
6
+
7
+ attr_accessor :distance, :smallest, :largest, :from_time, :to_time, :options
8
+
9
+ def initialize(distance, from_time = nil, to_time = nil, options = {})
10
+ self.output = {}
11
+ self.options = options
12
+ self.distance = distance
13
+ self.from_time = from_time || Time.now
14
+ self.to_time = to_time || (self.from_time + self.distance.seconds)
15
+ self.smallest, self.largest = [self.from_time, self.to_time].minmax
16
+
17
+ I18n.locale = options[:locale] if options[:locale]
18
+
19
+ build_time_hash
20
+ end
21
+
22
+ def to_hash
23
+ output
24
+ end
25
+
26
+ private
27
+ attr_accessor :options, :output
28
+
29
+ def build_time_hash
30
+ if accumulate_on = options.delete(:accumulate_on)
31
+ return build_time_hash if accumulate_on == :years
32
+ TIME_FRACTIONS.index(accumulate_on).downto(0) { |i| self.send("build_#{TIME_FRACTIONS[i]}") }
33
+ else
34
+ while distance > 0
35
+ if distance < 1.minute
36
+ build_seconds
37
+ elsif distance < 1.hour
38
+ build_minutes
39
+ elsif distance < 1.day
40
+ build_hours
41
+ elsif distance < 28.days
42
+ build_days
43
+ else # greater than a month
44
+ build_years_months_days
45
+ end
46
+ end
47
+ end
48
+
49
+ output
50
+ end
51
+
52
+ def build_seconds
53
+ output[I18n.t(:seconds, :default => "seconds")] = distance.to_i
54
+ self.distance = 0
55
+ end
56
+
57
+ def build_minutes
58
+ output[I18n.t(:minutes, :default => "minutes")], self.distance = distance.divmod(1.minute)
59
+ end
60
+
61
+ def build_hours
62
+ output[I18n.t(:hours, :default => "hours")], self.distance = distance.divmod(1.hour)
63
+ end
64
+
65
+ def build_days
66
+ output[I18n.t(:days, :default => "days")], self.distance = distance.divmod(1.day)
67
+ end
68
+
69
+ def build_months
70
+ build_years_months_days
71
+
72
+ if (years = output.delete(I18n.t(:years, :default => "years"))) > 0
73
+ output[I18n.t(:months, :default => "months")] += (years * 12)
74
+ end
75
+ end
76
+
77
+ def build_years_months_days
78
+ months = (largest.year - smallest.year) * 12 + (largest.month - smallest.month)
79
+ years, months = months.divmod(12)
80
+
81
+ days = largest.day - smallest.day
82
+
83
+ # Will otherwise incorrectly say one more day if our range goes over a day.
84
+ days -= 1 if largest.hour < smallest.hour
85
+
86
+ if days < 0
87
+ # Convert the last month to days and add to total
88
+ months -= 1
89
+ last_month = largest.advance(:months => -1)
90
+ days += Time.days_in_month(last_month.month, last_month.year)
91
+ end
92
+
93
+ if months < 0
94
+ # Convert a year to months
95
+ years -= 1
96
+ months += 12
97
+ end
98
+
99
+ output[I18n.t(:years, :default => "years")] = years
100
+ output[I18n.t(:months, :default => "months")] = months
101
+ output[I18n.t(:days, :default => "days")] = days
102
+
103
+ total_days, self.distance = (from_time - to_time).abs.divmod(1.day)
104
+ end
105
+ end # TimeHash
106
+ end # DOTIW
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module DOTIW
4
+ VERSION = "0.6.0"
5
+ end
@@ -0,0 +1,235 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe "A better distance_of_time_in_words" do
6
+ include ActionView::Helpers::DateHelper
7
+ include ActionView::Helpers::TextHelper
8
+ include ActionView::Helpers::NumberHelper
9
+
10
+ before do
11
+ I18n.locale = :en
12
+ time = "01-08-2009".to_time
13
+ Time.stub!(:now).and_return(time)
14
+ Time.zone.stub!(:now).and_return(time)
15
+ end
16
+
17
+ describe "distance of time" do
18
+ [
19
+ [5.minutes.to_i, "5 minutes"],
20
+ [10.minutes.to_i, "10 minutes"],
21
+ [1.hour.to_i, "1 hour"],
22
+ [4.weeks.to_i, "28 days"],
23
+ [24.weeks.to_i, "5 months and 15 days"]
24
+ ].each do |number, result|
25
+ it "#{number} == #{result}" do
26
+ distance_of_time(number).should eql(result)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "hash version" do
32
+ describe "giving correct numbers of" do
33
+
34
+ [:years, :months, :days, :minutes, :seconds].each do |name|
35
+ describe name do
36
+ it "exactly" do
37
+ hash = distance_of_time_in_words_hash(Time.now, Time.now + 1.send(name))
38
+ hash[name.to_s].should eql(1)
39
+ end
40
+
41
+ it "two" do
42
+ hash = distance_of_time_in_words_hash(Time.now, Time.now + 2.send(name))
43
+ hash[name.to_s].should eql(2)
44
+ end
45
+ end
46
+ end
47
+
48
+ it "should be happy with lots of measurements" do
49
+ hash = distance_of_time_in_words_hash(Time.now,
50
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds)
51
+ hash["years"].should eql(1)
52
+ hash["months"].should eql(2)
53
+ hash["days"].should eql(3)
54
+ hash["hours"].should eql(4)
55
+ hash["minutes"].should eql(5)
56
+ hash["seconds"].should eql(6)
57
+ end
58
+
59
+ it "debe estar contento con las mediciones en español" do
60
+ hash = distance_of_time_in_words_hash(Time.now,
61
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
62
+ :locale => "es")
63
+ hash["años"].should eql(1)
64
+ hash["meses"].should eql(2)
65
+ hash["días"].should eql(3)
66
+ hash["horas"].should eql(4)
67
+ hash["minutos"].should eql(5)
68
+ hash["segundos"].should eql(6)
69
+ end
70
+
71
+ it "debe hablar español" do
72
+ I18n.locale = :es
73
+ hash = distance_of_time_in_words_hash(Time.now, Time.now + 5.days)
74
+ hash["días"].should eql(5)
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "real version" do
80
+ it "debe hablar español" do
81
+ distance_of_time_in_words(Time.now, Time.now + 5.days, true, :locale => "es").should eql("5 días")
82
+ end
83
+
84
+ [
85
+ [Time.now, Time.now + 5.days + 3.minutes, "5 days and 3 minutes"],
86
+ [Time.now, Time.now + 1.minute, "1 minute"],
87
+ [Time.now, Time.now + 3.years, "3 years"],
88
+ [Time.now, Time.now + 10.years, "10 years"],
89
+ [Time.now, Time.now + 3.hour, "3 hours"],
90
+ # Need to be +1.day because it will output "1 year and 30 days" otherwise.
91
+ # Haven't investigated fully how this is caused.
92
+ [Time.now, Time.now + 13.months, "1 year and 1 month"],
93
+ # Any numeric sequence is merely coincidental.
94
+ [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
95
+ ["2009-3-16".to_time, "2008-4-14".to_time, "11 months and 2 days"],
96
+ ["2009-3-16".to_time + 1.minute, "2008-4-14".to_time, "11 months, 2 days, and 1 minute"],
97
+ ["2009-4-14".to_time, "2008-3-16".to_time, "1 year and 29 days"],
98
+ ["2009-2-01".to_time, "2009-3-01".to_time, "1 month"],
99
+ ["2008-2-01".to_time, "2008-3-01".to_time, "1 month"]
100
+ ].each do |start, finish, output|
101
+ it "should be #{output}" do
102
+ distance_of_time_in_words(start, finish, true).should eql(output)
103
+ end
104
+ end
105
+
106
+ describe "accumulate on" do
107
+ [
108
+ [Time.now,
109
+ Time.now + 10.minute,
110
+ :seconds,
111
+ "600 seconds"],
112
+ [Time.now,
113
+ Time.now + 10.hour + 10.minute + 1.second,
114
+ :minutes,
115
+ "610 minutes and 1 second"],
116
+ [Time.now,
117
+ Time.now + 2.day + 10000.hour + 10.second,
118
+ :hours,
119
+ "10048 hours and 10 seconds"],
120
+ [Time.now,
121
+ Time.now + 2.day + 10000.hour + 10.second,
122
+ :days,
123
+ "418 days, 16 hours, and 10 seconds"],
124
+ [Time.now,
125
+ Time.now + 2.day + 10000.hour + 10.second,
126
+ :months,
127
+ "13 months, 16 hours, and 10 seconds"],
128
+ [Time.now,
129
+ Time.now + 2.day + 10000.hour + 10.second,
130
+ :years,
131
+ "1 year, 1 month, 22 days, 16 hours, and 10 seconds"]
132
+ ].each do |start, finish, accumulator, output|
133
+ it "should be #{output}" do
134
+ distance_of_time_in_words(start, finish, true, :accumulate_on => accumulator).should eql(output)
135
+ end
136
+ end
137
+ end # :accumulate_on
138
+ end
139
+
140
+ describe "with output options" do
141
+ [
142
+ # Any numeric sequence is merely coincidental.
143
+ [Time.now,
144
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
145
+ { :words_connector => " - " },
146
+ "1 year - 2 months - 3 days - 4 hours - 5 minutes, and 6 seconds"],
147
+ [Time.now,
148
+ Time.now + 5.minutes + 6.seconds,
149
+ { :two_words_connector => " - " },
150
+ "5 minutes - 6 seconds"],
151
+ [Time.now,
152
+ Time.now + 4.hours + 5.minutes + 6.seconds,
153
+ { :last_word_connector => " - " },
154
+ "4 hours, 5 minutes - 6 seconds"],
155
+ [Time.now,
156
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
157
+ { :except => "minutes" },
158
+ "1 year, 2 months, 3 days, 4 hours, and 6 seconds"],
159
+ [Time.now,
160
+ Time.now + 1.hour + 1.minute,
161
+ { :except => "minutes"}, "1 hour"],
162
+ [Time.now,
163
+ Time.now + 1.hour + 1.day + 1.minute,
164
+ { :except => ["minutes", "hours"]},
165
+ "1 day"],
166
+ [Time.now,
167
+ Time.now + 1.hour + 1.day + 1.minute,
168
+ { :only => ["minutes", "hours"]},
169
+ "1 hour and 1 minute"],
170
+ [Time.now,
171
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
172
+ { :precision => 2 },
173
+ "1 year and 2 months"],
174
+ [Time.now,
175
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
176
+ { :precision => 3 },
177
+ "1 year, 2 months, and 3 days"],
178
+ [Time.now,
179
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
180
+ { :precision => 10 },
181
+ "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
182
+ [Time.now,
183
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
184
+ { :vague => true },
185
+ "about 1 year"],
186
+ [Time.now,
187
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
188
+ { :vague => "Yes please" },
189
+ "about 1 year"],
190
+ [Time.now,
191
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
192
+ { :vague => false },
193
+ "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
194
+ [Time.now,
195
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
196
+ { :vague => nil },
197
+ "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
198
+ [Time.now,
199
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
200
+ { "except" => "minutes" },
201
+ "1 year, 2 months, 3 days, 4 hours, and 6 seconds"],
202
+ ].each do |start, finish, options, output|
203
+ it "should be #{output}" do
204
+ distance_of_time_in_words(start, finish, true, options).should eql(output)
205
+ end
206
+ end
207
+
208
+ describe "include_seconds" do
209
+ it "is ignored if only seconds have passed" do
210
+ distance_of_time_in_words(Time.now, Time.now + 1.second, false).should eql("1 second")
211
+ end
212
+
213
+ it "removes seconds in all other cases" do
214
+ distance_of_time_in_words(Time.now,
215
+ Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
216
+ false).should eql("1 year, 2 months, 3 days, 4 hours, and 5 minutes")
217
+ end
218
+ end # include_seconds
219
+ end
220
+
221
+ describe "percentage of time" do
222
+ def time_in_percent(options = {})
223
+ distance_of_time_in_percent("04-12-2009".to_time, "29-01-2010".to_time, "04-12-2010".to_time, options)
224
+ end
225
+
226
+ it "calculates 15%" do
227
+ time_in_percent.should eql("15%")
228
+ end
229
+
230
+ it "calculates 15.3%" do
231
+ time_in_percent(:precision => 1).should eql("15.3%")
232
+ end
233
+ end
234
+
235
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  # encoding: utf-8
2
- require 'rubygems'
3
- $:.unshift(File.join(File.dirname(__FILE__), "../lib"))
4
2
 
5
- require 'action_controller'
6
- require 'active_support'
7
- require 'dotiw'
8
- require 'spec'
3
+ ROOT_PATH = File.join(File.dirname(__FILE__), '..')
4
+ $:.unshift ROOT_PATH unless $:.include? ROOT_PATH
9
5
 
10
- # Define time zone before loading, just like in the real world
11
- zone = "UTC"
12
- Time.zone = zone
6
+ # Files that are usually required by Rails, but in a testing context will not be.
7
+ require 'erb'
13
8
 
9
+ require 'active_support/all'
10
+
11
+ require 'action_view/context'
12
+ require 'action_view/helpers'
13
+
14
+ require 'init' # require dotiw through init (like a plugin would)
15
+
16
+ Time.zone = 'UTC'
17
+ I18n.load_path.clear
14
18
  I18n.load_path << Dir[File.join(File.dirname(__FILE__), "translations", "*")]
15
19
  I18n.locale = :en
16
-
17
- # bootstraping the plugin through init.rb
18
- # tests how it would load in a real application
19
- load File.dirname(__FILE__) + "/../rails/init.rb"
@@ -7,3 +7,18 @@ en:
7
7
  months: months
8
8
  years: years
9
9
 
10
+ support:
11
+ array:
12
+ two_words_connector: " and "
13
+ words_connector: ", "
14
+ last_word_connector: ", and "
15
+
16
+ datetime:
17
+ distance_in_words:
18
+ about_x_years:
19
+ one: "about 1 year"
20
+ many: "about %{count} years"
21
+
22
+ number:
23
+ format:
24
+ separator: "."
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotiw
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 4
9
- - 1
10
- version: 0.4.1
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Ryan Bigg
@@ -15,51 +14,86 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-02 00:00:00 +10:00
17
+ date: 2010-12-23 00:00:00 +10:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- name: rspec
21
+ name: actionpack
23
22
  prerelease: false
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
- - - ">="
26
+ - - ~>
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
29
+ - 3
31
30
  - 0
32
- version: "0"
33
- type: :development
31
+ - 0
32
+ version: 3.0.0
33
+ type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 0
46
+ - 0
47
+ version: 1.0.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rspec
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 2
60
+ - 0
61
+ version: "2.0"
62
+ type: :development
63
+ version_requirements: *id003
35
64
  description: Better distance_of_time_in_words for Rails
36
65
  email: radarlistener@gmail.com
37
66
  executables: []
38
67
 
39
68
  extensions: []
40
69
 
41
- extra_rdoc_files:
42
- - README.markdown
70
+ extra_rdoc_files: []
71
+
43
72
  files:
73
+ - .bundle/config
44
74
  - .gitignore
75
+ - Gemfile
76
+ - Gemfile.lock
45
77
  - MIT-LICENSE
46
78
  - README.markdown
47
79
  - Rakefile
48
- - VERSION
49
80
  - dotiw.gemspec
81
+ - init.rb
50
82
  - lib/dotiw.rb
83
+ - lib/dotiw/time_hash.rb
84
+ - lib/dotiw/version.rb
51
85
  - rails/init.rb
52
- - spec/dotiw_spec.rb
86
+ - spec/lib/dotiw_spec.rb
53
87
  - spec/spec_helper.rb
54
88
  - spec/translations/en.yml
55
89
  - spec/translations/es.yml
56
90
  has_rdoc: true
57
- homepage: http://github.com/radar/dotiw
91
+ homepage:
58
92
  licenses: []
59
93
 
60
94
  post_install_message:
61
- rdoc_options:
62
- - --charset=UTF-8
95
+ rdoc_options: []
96
+
63
97
  require_paths:
64
98
  - lib
65
99
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -67,7 +101,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
101
  requirements:
68
102
  - - ">="
69
103
  - !ruby/object:Gem::Version
70
- hash: 3
71
104
  segments:
72
105
  - 0
73
106
  version: "0"
@@ -76,10 +109,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
109
  requirements:
77
110
  - - ">="
78
111
  - !ruby/object:Gem::Version
79
- hash: 3
80
112
  segments:
81
- - 0
82
- version: "0"
113
+ - 1
114
+ - 3
115
+ - 6
116
+ version: 1.3.6
83
117
  requirements: []
84
118
 
85
119
  rubyforge_project:
@@ -88,5 +122,7 @@ signing_key:
88
122
  specification_version: 3
89
123
  summary: Better distance_of_time_in_words for Rails
90
124
  test_files:
91
- - spec/dotiw_spec.rb
125
+ - spec/lib/dotiw_spec.rb
92
126
  - spec/spec_helper.rb
127
+ - spec/translations/en.yml
128
+ - spec/translations/es.yml
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.3
data/spec/dotiw_spec.rb DELETED
@@ -1,157 +0,0 @@
1
- # encoding: utf-8
2
- require File.join(File.dirname(__FILE__), 'spec_helper')
3
- require 'dotiw'
4
-
5
- describe "A better distance_of_time_in_words" do
6
- include ActionView::Helpers::DateHelper
7
- include ActionView::Helpers::TextHelper
8
- include ActionView::Helpers::NumberHelper
9
-
10
- before do
11
- I18n.locale = :en
12
- time = "01-08-2009".to_time
13
- Time.stub!(:now).and_return(time)
14
- Time.zone.stub!(:now).and_return(time)
15
- end
16
-
17
- describe "distance of time" do
18
- [
19
- [5.minutes.to_i, "5 minutes"],
20
- [10.minutes.to_i, "10 minutes"],
21
- [1.hour.to_i, "1 hour"],
22
- [4.weeks.to_i, "28 days"],
23
- [24.weeks.to_i, "5 months and 15 days"]
24
- ].each do |number, result|
25
- it "#{number} == #{result}" do
26
- distance_of_time(number).should eql(result)
27
- end
28
- end
29
- end
30
-
31
- describe "hash version" do
32
- describe "giving correct numbers of" do
33
-
34
- [:years, :months, :days, :minutes, :seconds].each do |name|
35
- describe name do
36
- it "exactly" do
37
- hash = distance_of_time_in_words_hash(Time.now, Time.now + 1.send(name))
38
- hash[name].should eql(1)
39
- end
40
-
41
- it "two" do
42
- hash = distance_of_time_in_words_hash(Time.now, Time.now + 2.send(name))
43
- hash[name].should eql(2)
44
- end
45
- end
46
- end
47
-
48
- it "should be happy with lots of measurements" do
49
- hash = distance_of_time_in_words_hash(Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds)
50
- hash[:years].should eql(1)
51
- hash[:months].should eql(2)
52
- hash[:days].should eql(3)
53
- hash[:hours].should eql(4)
54
- hash[:minutes].should eql(5)
55
- hash[:seconds].should eql(6)
56
- end
57
-
58
- it "debe estar contento con las mediciones en español" do
59
- hash = distance_of_time_in_words_hash(Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, :locale => "es")
60
- hash[:años].should eql(1)
61
- hash[:meses].should eql(2)
62
- hash[:días].should eql(3)
63
- hash[:horas].should eql(4)
64
- hash[:minutos].should eql(5)
65
- hash[:segundos].should eql(6)
66
- end
67
-
68
-
69
- it "debe hablar español" do
70
- I18n.locale = :es
71
- hash = distance_of_time_in_words_hash(Time.now, Time.now + 5.days)
72
- hash["días"].should eql(5)
73
- end
74
- end
75
- end
76
-
77
- describe "real version" do
78
- it "debe hablar español" do
79
- distance_of_time_in_words(Time.now, Time.now + 5.days, true, :locale => "es").should eql("5 días")
80
- end
81
-
82
- [
83
- [Time.now, Time.now + 5.days + 3.minutes, "5 days and 3 minutes"],
84
- [Time.now, Time.now + 1.minute, "1 minute"],
85
- [Time.now, Time.now + 3.years, "3 years"],
86
- [Time.now, Time.now + 10.years, "10 years"],
87
- [Time.now, Time.now + 3.hour, "3 hours"],
88
- # Need to be +1.day because it will output "1 year and 30 days" otherwise.
89
- # Haven't investigated fully how this is caused.
90
- [Time.now, Time.now + 13.months + 1.day, "1 year and 1 month"],
91
- # Any numeric sequence is merely coincidental.
92
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
93
- ["2009-3-16".to_time, "2008-4-14".to_time, "11 months and 2 days"],
94
- ["2009-3-16".to_time + 1.minute, "2008-4-14".to_time, "11 months, 2 days, and 1 minute"],
95
- ["2009-4-14".to_time, "2008-3-16".to_time, "1 year and 29 days"],
96
- ["2009-2-01".to_time, "2009-3-01".to_time, "1 month"],
97
- ["2008-2-01".to_time, "2008-3-01".to_time, "1 month"]
98
- ].each do |start, finish, output|
99
- it "should be #{output}" do
100
- distance_of_time_in_words(start, finish, true).should eql(output)
101
- end
102
- end
103
- end
104
-
105
- describe "with output options" do
106
- [
107
- # Any numeric sequence is merely coincidental.
108
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :words_connector => " - " }, "1 year - 2 months - 3 days - 4 hours - 5 minutes, and 6 seconds"],
109
-
110
- [Time.now, Time.now + 5.minutes + 6.seconds, { :two_words_connector => " - " }, "5 minutes - 6 seconds"],
111
-
112
- [Time.now, Time.now + 4.hours + 5.minutes + 6.seconds, { :last_word_connector => " - " }, "4 hours, 5 minutes - 6 seconds"],
113
-
114
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :except => "minutes" }, "1 year, 2 months, 3 days, 4 hours, and 6 seconds"],
115
- [Time.now, Time.now + 1.hour + 1.minute, { :except => "minutes"}, "1 hour"],
116
- [Time.now, Time.now + 1.hour + 1.day + 1.minute, { :except => ["minutes", "hours"]}, "1 day"],
117
-
118
- [Time.now, Time.now + 1.hour + 1.day + 1.minute, { :only => ["minutes", "hours"]}, "1 hour and 1 minute"],
119
-
120
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :precision => 2 }, "1 year and 2 months"],
121
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :precision => 3 }, "1 year, 2 months, and 3 days"],
122
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :precision => 10 }, "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
123
-
124
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :vague => true }, "about 1 year"],
125
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :vague => "Yes please" }, "about 1 year"],
126
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :vague => false }, "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
127
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { :vague => nil }, "1 year, 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds"],
128
- [Time.now, Time.now + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds, { "except" => "minutes" }, "1 year, 2 months, 3 days, 4 hours, and 6 seconds"],
129
- ].each do |start, finish, options, output|
130
- it "should be #{output}" do
131
- distance_of_time_in_words(start, finish, true, options).should eql(output)
132
- end
133
- end
134
-
135
- it "outputs seconds regardless of include_seconds setting if only seconds have passed" do
136
- distance_of_time_in_words(Time.now, Time.now + 1.second).should eql("1 second")
137
- end
138
-
139
- end
140
-
141
- describe "percentage of time" do
142
-
143
- def time_in_percent(options = {})
144
- distance_of_time_in_percent("04-12-2009".to_time, "29-01-2010".to_time, "04-12-2010".to_time, options)
145
- end
146
-
147
- it "calculates 15%" do
148
- time_in_percent.should eql("15%")
149
- end
150
-
151
- it "calculates 15.3%" do
152
- time_in_percent(:precision => 1).should eql("15.3%")
153
- end
154
-
155
- end
156
-
157
- end