mixed_number 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb9cfd1b0dab7adc12a070e8e8bf697bd1cfb4b6
4
+ data.tar.gz: 9ccfe67060027962c7dbb9e9fb122913610b4fb7
5
+ SHA512:
6
+ metadata.gz: 537d8fffee40fade1d71950a739ff66df3942dfae8a02eb581228d551004f384a7796667373d9c9b1d47097bf9f60cea276b1fb7f97a5cf17aa6d31e5de6bcfb
7
+ data.tar.gz: 9bd557ce4c04aad34dce189f3f2d554f66cd4324216ff2c831253e5822fdd6a647c5d4575710b5fd36e489c5cd4ce736fc0b3e6839bd72fcf1cdd7481f9b9051
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mixed_number.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Tim Padjen
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.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # MixedNumber
2
+
3
+ Mixed numbers in ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mixed_number'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mixed_number
18
+
19
+ ## Usage
20
+ ```ruby
21
+ # Creating Mixed Numbers
22
+ MixedNumber() == 0 # => true
23
+ MixedNumber(8) # => 8
24
+ MixedNumber(1.5).to_s # => "1 1/2"
25
+ MixedNumber("2 6/18") # => 2 1/3
26
+ MixedNumber(9.0/3) # => 3
27
+ MixedNumber("-4 3/4").to_f # => -4.75
28
+ ```
29
+ ```ruby
30
+ # MixedNumbers are Numerics
31
+ mixed = MixedNumber("3 3/4")
32
+ mixed.truncate # => 3
33
+ mixed.round # => 4
34
+ mixed.numerator # => 15
35
+ mixed + 2 # => 5 3/4
36
+ 2 * mixed # => 7 1/2
37
+ # ...
38
+ ```
39
+ ```ruby
40
+ # Convert Numbers and Strings
41
+ 1.5.to_mixed # => 1 1/2
42
+ (15.0/4).to_m # => 3 3/4
43
+ Rational(14, 4).to_m # => 3 1/2
44
+ BigDecimal(1.8, 4).to_m # => 1 4/5
45
+ "3 5/6".to_m # => 3 5/6
46
+ ```
47
+
48
+ ## Contributing
49
+
50
+ 1. Fork it ( https://github.com/tpadjen/mixed_number/fork )
51
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
52
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
53
+ 4. Push to the branch (`git push origin my-new-feature`)
54
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ def set_remote_url(url)
4
+ `git remote set-url origin #{url}`
5
+ puts "Set remote url to #{url}"
6
+ end
7
+
8
+ task :ssh do
9
+ set_remote_url('git@github.com:tpadjen/mixed_number.git')
10
+ end
11
+
12
+ task :http do
13
+ set_remote_url('https://github.com/tpadjen/mixed_number.git')
14
+ end
15
+
@@ -0,0 +1,3 @@
1
+ class MixedNumber < Numeric
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,135 @@
1
+ require_relative "mixed_number/version"
2
+ require "bigdecimal"
3
+
4
+ class MixedNumber < Numeric
5
+
6
+ class << self
7
+ DECIMAL_NUMBERS = /^-?\d+(.\d+)?$/
8
+ RATIONAL_NUMBERS = /^-?\d+\/\d+$/
9
+ MIXED_NUMBERS = /^-?\d+\s+\d+\/\d+$/
10
+ VALID_NUMBERS = Regexp.union(DECIMAL_NUMBERS, RATIONAL_NUMBERS, MIXED_NUMBERS)
11
+
12
+ def parse(input=0)
13
+ n = stringify(input).strip
14
+ raise MixedNumberFormatError unless n =~ VALID_NUMBERS
15
+
16
+ reduction_method = n =~ /^-/ ? :- : :+
17
+ new(n.split.map { |r| Rational(r) }.reduce(reduction_method).to_r)
18
+ end
19
+
20
+ private
21
+ def stringify(n)
22
+ n.is_a?(BigDecimal) ? n.to_s('F') : n.to_s
23
+ end
24
+ end
25
+
26
+ def whole
27
+ to_i
28
+ end
29
+
30
+ def fraction
31
+ abs.to_r - whole.abs
32
+ end
33
+
34
+ def ==(other)
35
+ @rational == other
36
+ end
37
+
38
+ def <=>(other)
39
+ @rational <=> other
40
+ end
41
+
42
+ def +(other)
43
+ return to_s + other if other.is_a? String
44
+
45
+ combine(:+, other)
46
+ end
47
+
48
+ [:-, :*, :**, :quo].each do |method_name|
49
+ define_method method_name do |other|
50
+ combine(method_name, other)
51
+ end
52
+ end
53
+
54
+ def coerce(other)
55
+ [MixedNumber(other), self]
56
+ end
57
+
58
+ def to_s
59
+ @rational_string
60
+ end
61
+
62
+ def to_d
63
+ BigDecimal(@rational, 32)
64
+ end
65
+
66
+ def to_m
67
+ self
68
+ end
69
+
70
+ alias_method :/, :quo
71
+ alias_method :to_str, :to_s
72
+ alias_method :to_mixed, :to_m
73
+
74
+ def method_missing(name, *args, &block)
75
+ @rational.send(name, *args, &block)
76
+ end
77
+
78
+ private_class_method :new
79
+
80
+ private
81
+
82
+ def initialize(r)
83
+ @rational = r
84
+ @rational_string = sign + remove_zeroes("#{whole.abs} #{fraction}")
85
+ end
86
+
87
+ def sign
88
+ self < 0 ? "-" : ""
89
+ end
90
+
91
+ def remove_zeroes(string)
92
+ string.gsub(/^0 /, "").gsub(/ 0$/, "").gsub(/ 0\/\d+/, "")
93
+ end
94
+
95
+ def combine(method, other)
96
+ if other.is_a? Numeric
97
+ MixedNumber(@rational.send(method, other.to_r))
98
+ else
99
+ raise TypeError, "#{other.class} can't be coerced into MixedNumber" unless other.respond_to? :coerce
100
+ a, b = other.coerce(self)
101
+ a.send(method, b)
102
+ end
103
+ end
104
+
105
+ class MixedNumberFormatError < StandardError; end
106
+ end
107
+
108
+ def MixedNumber(input=0)
109
+ return input if input.kind_of?(MixedNumber)
110
+
111
+ MixedNumber.parse(input)
112
+ end
113
+
114
+ module CoreExtensions
115
+ module MixedNumberConversions
116
+
117
+ module Strict
118
+ def to_mixed
119
+ MixedNumber(self)
120
+ end
121
+
122
+ alias_method :to_m, :to_mixed
123
+ end
124
+
125
+ module Unstrict
126
+ def to_m
127
+ MixedNumber(self)
128
+ end
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+ Numeric.include CoreExtensions::MixedNumberConversions::Strict
135
+ String.include CoreExtensions::MixedNumberConversions::Unstrict
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mixed_number/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mixed_number"
8
+ spec.version = MixedNumber::VERSION
9
+ spec.authors = ["Tim Padjen"]
10
+ spec.email = ["tpadjen@gmail.com"]
11
+ spec.summary = %q{Mixed numbers in ruby}
12
+ spec.homepage = "https://github.com/tpadjen/mixed_number"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "bigdecimal"
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,333 @@
1
+ require "mixed_number"
2
+
3
+ describe MixedNumber do
4
+
5
+ context 'Creating' do
6
+
7
+ it 'should have a private constructor' do
8
+ expect(MixedNumber.respond_to?(:new)).to be(false)
9
+ end
10
+
11
+ it 'should be a Numeric' do
12
+ expect(MixedNumber(1)).to be_a(Numeric)
13
+ end
14
+
15
+ end
16
+
17
+ context 'Operators : ' do
18
+
19
+ context '==' do
20
+ it 'compares equality' do
21
+ expect(MixedNumber(4) == MixedNumber(2)).to eq(false)
22
+ expect(MixedNumber(4) == MixedNumber(4)).to eq(true)
23
+ expect(4 == MixedNumber(4)).to eq(true)
24
+ expect(4 == MixedNumber(2)).to eq(false)
25
+ expect(MixedNumber(2) == 4).to eq(false)
26
+ expect(MixedNumber(4) == 4).to eq(true)
27
+ end
28
+ end
29
+
30
+ context '<=>' do
31
+ it 'compares' do
32
+ expect(MixedNumber( 0) <=> 1).to be(-1)
33
+ expect(MixedNumber( 1) <=> 1/2).to be( 1)
34
+ expect(MixedNumber(1.5) <=> 1.5).to be( 0)
35
+ end
36
+ end
37
+
38
+ context '+' do
39
+ it 'adds' do
40
+ expect(MixedNumber(0) + MixedNumber(1)).to eq(1)
41
+ expect(0 + MixedNumber(1)).to eq(1)
42
+ expect(MixedNumber(1) + Rational(1, 2)).to eq(1.5)
43
+ expect(MixedNumber("2 2/5") + 1.5).to eq(3.9)
44
+ end
45
+
46
+ it 'concatenates' do
47
+ expect(MixedNumber("2 2/4") + " hello").to eq("2 1/2 hello")
48
+ expect("hello " + MixedNumber("2 2/4")).to eq("hello 2 1/2")
49
+ end
50
+
51
+ it 'fails to add to something non-coercable' do
52
+ expect{MixedNumber(1) + Object.new()}.to raise_error(TypeError)
53
+ end
54
+ end
55
+
56
+ context '-' do
57
+ it 'subtracts' do
58
+ expect(MixedNumber(0) - MixedNumber(1)).to eq(-1)
59
+ expect(0 - MixedNumber(1)).to eq(-1)
60
+ expect(MixedNumber(1) - Rational(1, 2)).to eq(0.5)
61
+ expect(MixedNumber("2 2/5") - 1.7).to eq(7.0/10)
62
+ end
63
+
64
+ it 'fails to subtract from something non-coercable' do
65
+ expect{MixedNumber(1) - Object.new()}.to raise_error(TypeError)
66
+ end
67
+ end
68
+
69
+ context '/' do
70
+ it 'divides' do
71
+ expect(MixedNumber(4) / MixedNumber(2)).to eq(2)
72
+ expect(4 / MixedNumber(2)).to eq(2)
73
+ expect(MixedNumber(1) / Rational(1, 2)).to eq(2)
74
+ expect(MixedNumber("2 1/2") / 2).to eq(1.25)
75
+ end
76
+
77
+ it 'fails to divide something non/coercable' do
78
+ expect{MixedNumber(1) / Object.new()}.to raise_error(TypeError)
79
+ end
80
+ end
81
+
82
+ context '*' do
83
+ it 'multiplies' do
84
+ expect(MixedNumber(4) * MixedNumber(2)).to eq(8)
85
+ expect(4 * MixedNumber(2)).to eq(8)
86
+ expect(MixedNumber(3) * Rational(1, 2)).to eq(1.5)
87
+ expect(MixedNumber("2 1/2") * 2).to eq(5)
88
+ end
89
+
90
+ it 'fails to multiply something non/coercable' do
91
+ expect{MixedNumber(1) * Object.new()}.to raise_error(TypeError)
92
+ end
93
+ end
94
+
95
+ context '**' do
96
+ it 'exponentiates' do
97
+ expect(MixedNumber(4) ** MixedNumber(2)).to eq(16)
98
+ expect(4 ** MixedNumber(2)).to eq(16)
99
+ expect(MixedNumber(3) ** Rational(1, 2)).to eq(3**0.5)
100
+ expect(MixedNumber("2 1/2") ** 2).to eq(2.5**2)
101
+ end
102
+
103
+ it 'fails to exponentiate something non/coercable' do
104
+ expect{MixedNumber(1) ** Object.new()}.to raise_error(TypeError)
105
+ end
106
+ end
107
+ end
108
+
109
+ context 'Parsing : ' do
110
+
111
+ context 'valid input :' do
112
+
113
+ it 'defaults to zero' do
114
+ expect(MixedNumber()).to eq(0)
115
+ end
116
+
117
+ it 'a Fixnum' do
118
+ expect(MixedNumber( 1)).to eq( 1)
119
+ expect(MixedNumber(135)).to eq(135)
120
+ expect(MixedNumber( -1)).to eq( -1)
121
+ end
122
+
123
+ it 'a Rational' do
124
+ expect(MixedNumber(Rational( 1, 2))).to eq( 0.5)
125
+ expect(MixedNumber(Rational( 1, -2))).to eq(-0.5)
126
+ expect(MixedNumber(Rational(-1, 2))).to eq(-0.5)
127
+ expect(MixedNumber(Rational(-1, -2))).to eq( 0.5)
128
+ end
129
+
130
+ it 'a Float' do
131
+ expect(MixedNumber( 1.5)).to eq( 3.0/2)
132
+ expect(MixedNumber(-1.5)).to eq(-3.0/2)
133
+ end
134
+
135
+ it 'a BigDecimal' do
136
+ expect(MixedNumber(BigDecimal( 1.5, 16))).to eq( 3.0/2)
137
+ expect(MixedNumber(BigDecimal(-1.5, 16))).to eq(-3.0/2)
138
+ expect(MixedNumber(BigDecimal(1.0/3, 16))).to be_within(0.000001).of(1.0/3)
139
+ end
140
+
141
+ context 'Strings : ' do
142
+ it 'a whole number' do
143
+ expect(MixedNumber( "1")).to eq( 1)
144
+ expect(MixedNumber("-1")).to eq(-1)
145
+ end
146
+
147
+ it 'a fraction' do
148
+ expect(MixedNumber(" 1/2")).to eq( 0.5)
149
+ expect(MixedNumber("-1/2")).to eq(-0.5)
150
+ end
151
+
152
+ it 'a mixed number' do
153
+ expect(MixedNumber(" 1 2/3")).to eq( 5.0/3)
154
+ expect(MixedNumber("-1 2/3")).to eq(-5.0/3)
155
+ end
156
+
157
+ it 'trims input' do
158
+ expect(MixedNumber( " 1 2/3\t\t")).to eq( 5.0/3)
159
+ expect(MixedNumber(" -1 2/3\t\t")).to eq(-5.0/3)
160
+ end
161
+
162
+ it 'ignores extra space between whole and fractional part' do
163
+ expect(MixedNumber( "1 \t2/3")).to eq( 5.0/3)
164
+ expect(MixedNumber("-1 \t2/3")).to eq(-5.0/3)
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+
171
+ context 'invalid input : ' do
172
+
173
+ it 'raises an error when dividing by zero' do
174
+ expect{MixedNumber("1 2/0")}.to raise_error(ZeroDivisionError)
175
+ expect{MixedNumber( "2/0")}.to raise_error(ZeroDivisionError)
176
+ end
177
+
178
+ it 'raises an error when not formatted like a mixed number' do
179
+ ["", "1 1 2/3", "1/2 1", "a", "a/b", "a 3/4", "1 2 / 3", "1 -2/3", "1 2/-3", "word"].each do |mixed|
180
+ expect{MixedNumber(mixed)}.to raise_error(MixedNumber::MixedNumberFormatError)
181
+ end
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+
188
+ context 'Conversion : ' do
189
+
190
+ context 'to String' do
191
+
192
+ it 'reduces to the closest whole number' do
193
+ expect(MixedNumber("2 2/10").to_s).to eq("2 1/5")
194
+ expect(MixedNumber("3/15").to_s).to eq("1/5")
195
+ expect(MixedNumber("35/15").to_s).to eq("2 1/3")
196
+ expect(MixedNumber(1.5).to_s).to eq("1 1/2")
197
+ end
198
+
199
+ it 'works with negative numbers' do
200
+ expect(MixedNumber("-2 2/10").to_s).to eq("-2 1/5")
201
+ expect(MixedNumber("-3/15").to_s).to eq("-1/5")
202
+ expect(MixedNumber("-35/15").to_s).to eq("-2 1/3")
203
+ expect(MixedNumber(-1.5).to_s).to eq("-1 1/2")
204
+ end
205
+
206
+ it 'is the same explicit and implicit' do
207
+ mixed = MixedNumber("-3 8/4")
208
+ expect(mixed.to_s).to eq(mixed.to_str)
209
+ end
210
+
211
+ it 'removes zero parts' do
212
+ expect(MixedNumber("2/10").to_s).to eq("1/5")
213
+ expect(MixedNumber("1 0/10").to_s).to eq("1")
214
+ end
215
+
216
+ end
217
+
218
+ context 'to BigDecimal' do
219
+
220
+ it 'converts' do
221
+ expect(MixedNumber().to_d).to be_a(BigDecimal)
222
+ end
223
+
224
+ it 'is accurate' do
225
+ expect(MixedNumber( 4.0/3).to_d).to be_within(0.0000001).of(4.0/3)
226
+ expect(MixedNumber("1 1/3").to_d).to be_within(0.0000001).of(4.0/3)
227
+ end
228
+
229
+ end
230
+
231
+ end
232
+
233
+ context 'Parts' do
234
+
235
+ it 'finds the whole part' do
236
+ expect(MixedNumber(2).whole).to eq(2)
237
+ expect(MixedNumber("2 1/2").whole).to eq(2)
238
+ expect(MixedNumber("1/2").whole).to eq(0)
239
+ end
240
+
241
+ it 'finds the fractional part' do
242
+ expect(MixedNumber(2).fraction).to eq(0)
243
+ expect(MixedNumber("2 1/2").fraction).to eq(0.5)
244
+ expect(MixedNumber("1/2").fraction).to eq(0.5)
245
+ expect(MixedNumber("1 99999/100000").fraction).to eq(Rational(99999, 100000))
246
+ expect(MixedNumber(1 + Math::PI).fraction.to_f).to be_within(0.0000001).of(Math::PI - 3)
247
+ end
248
+
249
+ end
250
+
251
+ context 'Converting to MixedNumbers' do
252
+
253
+ context 'Strings : ' do
254
+
255
+ it 'has a conversion method' do
256
+ expect("1/3").to respond_to(:to_m)
257
+ expect("1/3").to_not respond_to(:to_mixed)
258
+ end
259
+
260
+ it 'can convert to a mixed number' do
261
+ expect("1/2".to_m).to be_a(MixedNumber)
262
+ expect("1/2".to_m).to eq(MixedNumber(1.0/2))
263
+ end
264
+
265
+ end
266
+
267
+ context 'Fixnums : ' do
268
+
269
+ it 'has a conversion method' do
270
+ expect(1).to respond_to(:to_m)
271
+ expect(1).to respond_to(:to_mixed)
272
+ end
273
+
274
+ it 'can convert to a mixed number' do
275
+ expect(1.to_m).to be_a(MixedNumber)
276
+ expect(1.to_m).to eq(MixedNumber(1))
277
+ expect(1.to_mixed).to be_a(MixedNumber)
278
+ expect(1.to_mixed).to eq(MixedNumber(1))
279
+ end
280
+
281
+ end
282
+
283
+ context 'Floats : ' do
284
+
285
+ it 'has a conversion method' do
286
+ expect(1.5).to respond_to(:to_m)
287
+ expect(1.5).to respond_to(:to_mixed)
288
+ end
289
+
290
+ it 'can convert to a mixed number' do
291
+ expect(1.5.to_m).to be_a(MixedNumber)
292
+ expect(1.5.to_m).to eq(MixedNumber(1.5))
293
+ expect(1.5.to_mixed).to be_a(MixedNumber)
294
+ expect(1.5.to_mixed).to eq(MixedNumber(1.5))
295
+ end
296
+
297
+ end
298
+
299
+ context 'Rationals : ' do
300
+
301
+ it 'has a conversion method' do
302
+ expect(Rational(2, 4)).to respond_to(:to_m)
303
+ expect(Rational(2, 4)).to respond_to(:to_mixed)
304
+ end
305
+
306
+ it 'can convert to a mixed number' do
307
+ expect(Rational(2, 4).to_m).to be_a(MixedNumber)
308
+ expect(Rational(2, 4).to_m).to eq(MixedNumber(0.5))
309
+ expect(Rational(2, 4).to_mixed).to be_a(MixedNumber)
310
+ expect(Rational(2, 4).to_mixed).to eq(MixedNumber(0.5))
311
+ end
312
+
313
+ end
314
+
315
+ context 'BigDecimals : ' do
316
+
317
+ it 'has a conversion method' do
318
+ expect(BigDecimal(0.8, 4)).to respond_to(:to_m)
319
+ expect(BigDecimal(0.8, 4)).to respond_to(:to_mixed)
320
+ end
321
+
322
+ it 'can convert to a mixed number' do
323
+ expect(BigDecimal(0.8, 4).to_m).to be_a(MixedNumber)
324
+ expect(BigDecimal(0.8, 4).to_m).to eq(MixedNumber(0.8))
325
+ expect(BigDecimal(0.8, 4).to_mixed).to be_a(MixedNumber)
326
+ expect(BigDecimal(0.8, 4).to_mixed).to eq(MixedNumber(0.8))
327
+ end
328
+
329
+ end
330
+
331
+ end
332
+
333
+ end
@@ -0,0 +1,91 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.expect_with :rspec do |expectations|
24
+ # This option will default to `true` in RSpec 4. It makes the `description`
25
+ # and `failure_message` of custom matchers include text for helper methods
26
+ # defined using `chain`, e.g.:
27
+ # be_bigger_than(2).and_smaller_than(4).description
28
+ # # => "be bigger than 2 and smaller than 4"
29
+ # ...rather than:
30
+ # # => "be bigger than 2"
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ end
33
+
34
+ # rspec-mocks config goes here. You can use an alternate test double
35
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
36
+ config.mock_with :rspec do |mocks|
37
+ # Prevents you from mocking or stubbing a method that does not exist on
38
+ # a real object. This is generally recommended, and will default to
39
+ # `true` in RSpec 4.
40
+ mocks.verify_partial_doubles = true
41
+ end
42
+
43
+ # The settings below are suggested to provide a good initial experience
44
+ # with RSpec, but feel free to customize to your heart's content.
45
+ =begin
46
+ # These two settings work together to allow you to limit a spec run
47
+ # to individual examples or groups you care about by tagging them with
48
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
49
+ # get run.
50
+ config.filter_run :focus
51
+ config.run_all_when_everything_filtered = true
52
+
53
+ # Limits the available syntax to the non-monkey patched syntax that is
54
+ # recommended. For more details, see:
55
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
56
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
57
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
58
+ config.disable_monkey_patching!
59
+
60
+ # This setting enables warnings. It's recommended, but in some cases may
61
+ # be too noisy due to issues in dependencies.
62
+ config.warnings = true
63
+
64
+ # Many RSpec users commonly either run the entire suite or an individual
65
+ # file, and it's useful to allow more verbose output when running an
66
+ # individual spec file.
67
+ if config.files_to_run.one?
68
+ # Use the documentation formatter for detailed output,
69
+ # unless a formatter has already been configured
70
+ # (e.g. via a command-line flag).
71
+ config.default_formatter = 'doc'
72
+ end
73
+
74
+ # Print the 10 slowest examples and example groups at the
75
+ # end of the spec run, to help surface which specs are running
76
+ # particularly slow.
77
+ config.profile_examples = 10
78
+
79
+ # Run specs in random order to surface order dependencies. If you find an
80
+ # order dependency and want to debug it, you can fix the order by providing
81
+ # the seed, which is printed after each run.
82
+ # --seed 1234
83
+ config.order = :random
84
+
85
+ # Seed global randomization in this process using the `--seed` CLI option.
86
+ # Setting this allows you to use `--seed` to deterministically reproduce
87
+ # test failures related to randomization by passing the same `--seed` value
88
+ # as the one that triggered the failure.
89
+ Kernel.srand config.seed
90
+ =end
91
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mixed_number
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tim Padjen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bigdecimal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - tpadjen@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/mixed_number.rb
83
+ - lib/mixed_number/version.rb
84
+ - mixed_number.gemspec
85
+ - spec/mixed_number_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: https://github.com/tpadjen/mixed_number
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.2.2
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Mixed numbers in ruby
111
+ test_files:
112
+ - spec/mixed_number_spec.rb
113
+ - spec/spec_helper.rb