infinite_time 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed911579f92e11434eb1dc9571f440039f99acb9
4
+ data.tar.gz: d4ab5b1acba42309f0d0203cbb3361bda6983b06
5
+ SHA512:
6
+ metadata.gz: e91c24535500d61408012dd8cd4e1347398b0652a9042d2ecf10f97a666534c2a50449a246caad0b1c095c7274396f9ae53d95ac425d55e29abf9db03aab0bbf
7
+ data.tar.gz: 287f71c2e8bfc8a95b7168ee77ab6ee103b1812f193841261f9373681d6b7bfedd17dd66e649cbe7ee207074d9d41405ac78f117246ddcd9c4c7ee4625dae65c
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in infinite_time.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 J. Andrew Marshall <http://johnandrewmarshall.com/>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ # InfiniteTime
2
+
3
+ [![Build Status](https://secure.travis-ci.org/amarshall/infinite_time.png?branch=master)](http://travis-ci.org/amarshall/infinite_time)
4
+
5
+ Provides a representation of a (positively or negatively) infinite time. This allows easier comparison with times when, for instance, you have an end date for an object but it is not yet known. Using `nil` would cause TypeErrors everywhere and you must then guard against that, this avoids that issue.
6
+
7
+ Many judgement calls were made in how to best reimplement methods that exist on Time but don’t really make sense on an infinite time. Comments and suggestions on how the behavior of any method on InfiniteTime could be improved is welcome. Open an issue or submit a pull request.
8
+
9
+ ## Installation
10
+
11
+ Install as usual: `gem install infinite_time` or add `gem 'infinite_time'` to your Gemfile. Note that Ruby 2.0 is required.
12
+
13
+ ## Usage
14
+
15
+ Simply create a new positive or negative infinite time:
16
+
17
+ ```ruby
18
+ positive = InfiniteTime.new :+
19
+ negative = InfiniteTime.new :-
20
+
21
+ positive == InfiniteTime.new #=> true
22
+ ```
23
+
24
+ Feel free to read the specs for more details.
25
+
26
+ ## Contributing
27
+
28
+ Contributions are welcome. Please be sure that your pull requests are atomic so they can be considered and accepted separately.
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
35
+
36
+ ## Credits & License
37
+
38
+ Copyright © 2013 J. Andrew Marshall. License is available in the LICENSE file.
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Run specs'
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.ruby_opts = '-w' unless ENV['TRAVIS']
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'infinite_time/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'infinite_time'
8
+ spec.version = InfiniteTime::VERSION
9
+ spec.authors = ['Andrew Marshall']
10
+ spec.email = ['andrew@johnandrewmarshall.com']
11
+ spec.description = %q{Provides a representation of a (positively or negatively) infinite time.}
12
+ spec.summary = %q{Provides a representation of a (positively or negatively) infinite time.}
13
+ spec.homepage = 'http://johnandrewmarshall.com/projects/infinite_time'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'rspec'
26
+ end
@@ -0,0 +1,114 @@
1
+ require 'infinite_time/version'
2
+ require 'infinite_time/core_ext'
3
+
4
+ class InfiniteTime < Time
5
+ class << self
6
+ undef at
7
+ undef gm
8
+ undef local
9
+ undef mktime
10
+ undef now
11
+ undef utc
12
+ end
13
+
14
+ def initialize sign = :+
15
+ sign = sign.to_sym
16
+ raise InvalidSign unless [:+, :-].include? sign
17
+ @sign = sign
18
+ end
19
+
20
+ def positive?
21
+ @sign == :+
22
+ end
23
+
24
+ def negative?
25
+ !positive?
26
+ end
27
+
28
+ def <=> other
29
+ case other
30
+ when InfiniteTime
31
+ if positive? && other.negative?
32
+ 1
33
+ elsif negative? && other.positive?
34
+ -1
35
+ else
36
+ 0
37
+ end
38
+ when Time then (positive?) ? 1 : -1
39
+ else raise ArgumentError, "comparison of InfiniteTime with #{other.inspect} failed"
40
+ end
41
+ end
42
+
43
+ def + _; self; end
44
+ def - _; self; end
45
+
46
+ def hash
47
+ self.class.hash ^ @sign.hash
48
+ end
49
+
50
+ def to_i; raise TypeError, 'InfiniteTime has no Integer representation'; end
51
+ def to_r; raise TypeError, 'InfiniteTime has no Rational representation'; end
52
+
53
+ def to_s
54
+ "#{@sign}∞"
55
+ end
56
+ alias_method :asctime, :to_s
57
+ alias_method :ctime, :to_s
58
+ alias_method :inspect, :to_s
59
+
60
+ def strftime _; to_s; end
61
+
62
+ private
63
+
64
+ def signed_float
65
+ (positive?) ? Float::INFINITY : -Float::INFINITY
66
+ end
67
+
68
+ class InvalidSign < StandardError; end
69
+
70
+ module TimeCompatability
71
+ def self.define_method name, arity = 0, &block
72
+ super name do |*args|
73
+ unless arity === args.length
74
+ raise ArgumentError, "wrong number of arguments (#{args.length} for #{arity})"
75
+ end
76
+ instance_exec(*args, &block)
77
+ end
78
+ end
79
+
80
+ def self.nil_method name, arity = 0
81
+ define_method(name, arity) { nil }
82
+ end
83
+ def self.nil_methods names
84
+ names.each { |name| nil_method name }
85
+ end
86
+
87
+ def self.signed_method name, arity = 0
88
+ define_method(name, arity) { signed_float }
89
+ end
90
+ def self.signed_methods names
91
+ names.each { |name| signed_method name }
92
+ end
93
+
94
+ def self.self_method name, arity = 0
95
+ define_method(name, arity) { self }
96
+ end
97
+ def self.self_methods names
98
+ names.each { |name| self_method name }
99
+ end
100
+
101
+ signed_methods %i[year month day yday wday hour minute second subsec nsec usec]
102
+ nil_methods %i[monday? tuesday? wednesday? thursday? friday? saturday? sunday?]
103
+ nil_methods %i[dst? isdst gmt? gmt_offset gmtoff utc? utc_offset zone]
104
+ self_method :round, 0..1
105
+ self_method :succ
106
+ alias_method :mday, :day
107
+ alias_method :mon, :month
108
+ alias_method :sec, :second
109
+ alias_method :tv_nsec, :nsec
110
+ alias_method :tv_usec, :usec
111
+ end
112
+ private_constant :TimeCompatability
113
+ include TimeCompatability
114
+ end
@@ -0,0 +1,6 @@
1
+ require 'infinite_time/time_extension'
2
+
3
+ class Time
4
+ Infinity = InfiniteTime
5
+ prepend InfiniteTime::TimeExtension
6
+ end
@@ -0,0 +1,15 @@
1
+ class InfiniteTime
2
+ module TimeExtension
3
+ def infinite?
4
+ is_a? InfiniteTime
5
+ end
6
+
7
+ def <=> other
8
+ if other.infinite?
9
+ (other.positive?) ? -1 : 1
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ class InfiniteTime < Time
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,17 @@
1
+ describe Time do
2
+ describe "#infinite?" do
3
+ it "is true when an infinite time" do
4
+ InfiniteTime.new.infinite?.should == true
5
+ end
6
+
7
+ it "is false when not an infinite time" do
8
+ Time.new.infinite?.should == false
9
+ end
10
+ end
11
+
12
+ describe "comparison" do
13
+ it "still works against other times" do
14
+ (Time.now < Time.now).should be_true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,224 @@
1
+ require './lib/infinite_time'
2
+
3
+ describe InfiniteTime do
4
+ it "behaves like a Time" do
5
+ InfiniteTime.new.is_a?(Time).should == true
6
+ end
7
+
8
+ it "is positively infinite by default" do
9
+ itime = InfiniteTime.new
10
+ itime.positive?.should == true
11
+ itime.negative?.should == false
12
+ end
13
+
14
+ it "raises InvalidSign when given anything other than :+ or :-" do
15
+ expect { InfiniteTime.new }.to_not raise_error InfiniteTime::InvalidSign
16
+ expect { InfiniteTime.new :+ }.to_not raise_error InfiniteTime::InvalidSign
17
+ expect { InfiniteTime.new :- }.to_not raise_error InfiniteTime::InvalidSign
18
+ expect { InfiniteTime.new :~ }.to raise_error InfiniteTime::InvalidSign
19
+ end
20
+
21
+ it "returns an unchanged self when math is performed on it" do
22
+ itime = InfiniteTime.new
23
+ (itime + 1).should eql itime
24
+ (itime + 1).should equal itime
25
+ (itime - 1).should eql itime
26
+ (itime - 1).should equal itime
27
+ itime.round.should eql itime
28
+ itime.round.should equal itime
29
+ itime.round(0).should eql itime
30
+ itime.round(0).should equal itime
31
+ itime.succ.should eql itime
32
+ itime.succ.should equal itime
33
+ end
34
+
35
+ it "returns an unchanged self when timezone conversion is performed on it" do
36
+ itime = InfiniteTime.new
37
+ itime.getgm.should eql itime
38
+ itime.getutc.should eql itime
39
+ itime.getlocal.should eql itime
40
+ itime.getlocal('+01:00').should eql itime
41
+ itime.localtime.should eql itime
42
+ itime.localtime('+01:00').should eql itime
43
+
44
+ itime.gmtime.should eql itime
45
+ itime.utc.should eql itime
46
+ end
47
+
48
+ it "cannot be compared against anything but Time objects" do
49
+ expect { InfiniteTime.new <=> Object.new }.to raise_error ArgumentError
50
+ expect { InfiniteTime.new <=> Date.new }.to raise_error ArgumentError
51
+ expect { InfiniteTime.new <=> 321 }.to raise_error ArgumentError
52
+ end
53
+
54
+ describe "time compatibility" do
55
+ it "returns nil for all day of the week predicate methods" do
56
+ positive = InfiniteTime.new :+
57
+ negative = InfiniteTime.new :-
58
+
59
+ [positive, negative].each do |itime|
60
+ itime.monday?.should == nil
61
+ itime.tuesday?.should == nil
62
+ itime.wednesday?.should == nil
63
+ itime.thursday?.should == nil
64
+ itime.friday?.should == nil
65
+ itime.saturday?.should == nil
66
+ itime.sunday?.should == nil
67
+ end
68
+ end
69
+
70
+ it "returns nil for all time zone inquiry methods" do
71
+ positive = InfiniteTime.new :+
72
+ negative = InfiniteTime.new :-
73
+
74
+ [positive, negative].each do |itime|
75
+ itime.dst?.should == nil
76
+ itime.isdst.should == nil
77
+
78
+ itime.gmt?.should == nil
79
+ itime.utc?.should == nil
80
+ itime.zone.should == nil
81
+
82
+ itime.gmt_offset.should == nil
83
+ itime.gmtoff.should == nil
84
+ itime.utc_offset.should == nil
85
+ end
86
+ end
87
+
88
+ it "returns the appropriate infinity for time/date inquiry methods" do
89
+ positive = InfiniteTime.new :+
90
+ negative = InfiniteTime.new :-
91
+
92
+ positive.year.should == +Float::INFINITY
93
+ positive.month.should == +Float::INFINITY
94
+ positive.mon.should == +Float::INFINITY
95
+ positive.day.should == +Float::INFINITY
96
+ positive.yday.should == +Float::INFINITY
97
+ positive.mday.should == +Float::INFINITY
98
+ positive.wday.should == +Float::INFINITY
99
+ positive.hour.should == +Float::INFINITY
100
+ positive.minute.should == +Float::INFINITY
101
+ positive.second.should == +Float::INFINITY
102
+ positive.sec.should == +Float::INFINITY
103
+ positive.subsec.should == +Float::INFINITY
104
+ positive.nsec.should == +Float::INFINITY
105
+ positive.usec.should == +Float::INFINITY
106
+ positive.tv_nsec.should == +Float::INFINITY
107
+ positive.tv_usec.should == +Float::INFINITY
108
+
109
+ negative.year.should == -Float::INFINITY
110
+ negative.month.should == -Float::INFINITY
111
+ negative.mon.should == -Float::INFINITY
112
+ negative.day.should == -Float::INFINITY
113
+ negative.yday.should == -Float::INFINITY
114
+ negative.mday.should == -Float::INFINITY
115
+ negative.wday.should == -Float::INFINITY
116
+ negative.hour.should == -Float::INFINITY
117
+ negative.minute.should == -Float::INFINITY
118
+ negative.second.should == -Float::INFINITY
119
+ negative.sec.should == -Float::INFINITY
120
+ negative.subsec.should == -Float::INFINITY
121
+ negative.nsec.should == -Float::INFINITY
122
+ negative.usec.should == -Float::INFINITY
123
+ negative.tv_nsec.should == -Float::INFINITY
124
+ negative.tv_usec.should == -Float::INFINITY
125
+ end
126
+
127
+ it "returns a TypeError for impossible numeric conversions" do
128
+ itime = InfiniteTime.new
129
+
130
+ expect { itime.to_i }.to raise_error TypeError
131
+ expect { itime.to_r }.to raise_error TypeError
132
+ end
133
+
134
+ it "has sensible string representations" do
135
+ positive = InfiniteTime.new :+
136
+ negative = InfiniteTime.new :-
137
+
138
+ plus_∞ = '+∞'
139
+ minus_∞ = '-∞'
140
+
141
+ positive.asctime.should == plus_∞
142
+ positive.ctime.should == plus_∞
143
+ positive.inspect.should == plus_∞
144
+ positive.strftime('').should == plus_∞
145
+ positive.to_s.should == plus_∞
146
+
147
+ negative.asctime.should == minus_∞
148
+ negative.ctime.should == minus_∞
149
+ negative.inspect.should == minus_∞
150
+ negative.strftime('').should == minus_∞
151
+ negative.to_s.should == minus_∞
152
+ end
153
+
154
+ (Time.methods - Time.superclass.methods).each do |method|
155
+ it "undefines the class method '#{method}' since it makes no sense" do
156
+ expect { InfiniteTime.public_send method }.to raise_error NoMethodError
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "a positively infinite time" do
162
+ it "is created by passing :+ to #new" do
163
+ itime = InfiniteTime.new :+
164
+ itime.positive?.should == true
165
+ itime.negative?.should == false
166
+ end
167
+
168
+ it "is greater than all non-infinite times" do
169
+ itime = InfiniteTime.new :+
170
+ time = Time.now + 10000
171
+
172
+ (itime > time).should == true
173
+ (itime <= time).should == false
174
+ (time < itime).should == true
175
+ (time >= itime).should == false
176
+ end
177
+
178
+ it "is equal to another positively infinite time" do
179
+ a, b = InfiniteTime.new(:+), InfiniteTime.new(:+)
180
+ (a == b).should == true
181
+ (a.eql? b).should == true
182
+ (a.equal? b).should == false
183
+ end
184
+
185
+ it "is greater than a negatively infinite time" do
186
+ positive = InfiniteTime.new :+
187
+ negative = InfiniteTime.new :-
188
+
189
+ (positive > negative).should == true
190
+ end
191
+ end
192
+
193
+ describe "a negatively infinite time" do
194
+ it "is created by passing :- to #new" do
195
+ itime = InfiniteTime.new :-
196
+ itime.positive?.should == false
197
+ itime.negative?.should == true
198
+ end
199
+
200
+ it "is less than all non-infinite times" do
201
+ itime = InfiniteTime.new :-
202
+ time = Time.now - 10000
203
+
204
+ (itime < time).should == true
205
+ (itime >= time).should == false
206
+ (time > itime).should == true
207
+ (time <= itime).should == false
208
+ end
209
+
210
+ it "is equal to another negatively infinite time" do
211
+ a, b = InfiniteTime.new(:-), InfiniteTime.new(:-)
212
+ (a == b).should == true
213
+ (a.eql? b).should == true
214
+ (a.equal? b).should == false
215
+ end
216
+
217
+ it "is less than a positively infinite time" do
218
+ positive = InfiniteTime.new :+
219
+ negative = InfiniteTime.new :-
220
+
221
+ (negative < positive).should == true
222
+ end
223
+ end
224
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: infinite_time
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Marshall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Provides a representation of a (positively or negatively) infinite time.
56
+ email:
57
+ - andrew@johnandrewmarshall.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .travis.yml
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - infinite_time.gemspec
69
+ - lib/infinite_time.rb
70
+ - lib/infinite_time/core_ext.rb
71
+ - lib/infinite_time/time_extension.rb
72
+ - lib/infinite_time/version.rb
73
+ - spec/infinite_time/core_ext_spec.rb
74
+ - spec/infinite_time_spec.rb
75
+ homepage: http://johnandrewmarshall.com/projects/infinite_time
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: 2.0.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.0.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Provides a representation of a (positively or negatively) infinite time.
99
+ test_files:
100
+ - spec/infinite_time/core_ext_spec.rb
101
+ - spec/infinite_time_spec.rb
102
+ has_rdoc: