dotiw 0.4.1 → 0.6.0

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