approximately 1.0.0 → 1.1.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.
@@ -4,7 +4,7 @@ Facilitates comparisons of Floats, primarily in mocking. Some mocking libraries
4
4
  delta assertions within the expectations of your method calls. For example:
5
5
 
6
6
  some_animated_point = mock()
7
- mock.should_receive(:move_to).with(0.01456, -234.786)
7
+ some_animated_point.should_receive(:move_to).with(0.01456, -234.786)
8
8
 
9
9
  Then you feed this mock from the outside, using some iterative algorithm with arbitrary precision, and your
10
10
  assertion fails.
@@ -13,20 +13,30 @@ assertion fails.
13
13
 
14
14
  This comes because what you should have done is comparing within a delta/epsilon value instead of comparing verbatim.
15
15
 
16
- And this is what most mocking libraries will do.
16
+ However, once the expected argument has been swallowed by the mocking library you don't really have any control
17
+ on what is going to happen to it, and in most mocking libraries you cannot add detailed assertions on the
18
+ expectation arguments.
17
19
 
18
- Some mocking libraries allow you to stuff an "assert_in_delta" call into the block of the expectation setup, but not
19
- all of them - and the expectation block might not be called at all if the passed arguments do not match. So what
20
- we can do instead is create a special object that will be equal to another Float object when they both are in delta
21
- of one another. So instead you would do this (in your unit/spec framework du jour)
20
+ So what we can do instead is create a special object that will be equal to another Float object when they both are in delta
21
+ of one another. For example:
22
+
23
+ Approximately.approx(23.4, 0.1) == 23.44 # true
24
+
25
+ In your unit testing/spec framework du jour your test would look like this:
22
26
 
23
27
  include Approximately
24
28
 
25
29
  some_animated_point = mock()
26
- mock.should_receive(:move_to).with(approx(0.01456, 0.001), approx(-234.786, 0.001))
30
+ some_animated_point.should_receive(:move_to).with(approx(0.01456, 0.001), approx(-234.786, 0.001))
27
31
 
28
32
  These objects will compare properly with your reference inputs.
29
33
 
34
+ You can also get this magic float object without including Approximately by calling
35
+
36
+ Approximately.approx(23.4, 0.1)
37
+
38
+ This module is completely uninvasive and contains no hacks for minitest, RSpec or other testing/mocking frameworks.
39
+
30
40
  == Contributing to approximately
31
41
 
32
42
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "approximately"
8
- s.version = "1.0.0"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik"]
12
- s.date = "2012-05-07"
12
+ s.date = "2012-09-07"
13
13
  s.email = "me@julik.nl"
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.homepage = "http://github.com/julik/approximately"
30
30
  s.licenses = ["MIT"]
31
31
  s.require_paths = ["lib"]
32
- s.rubygems_version = "1.8.15"
32
+ s.rubygems_version = "1.8.24"
33
33
  s.summary = "Facilitates float comparisons in mocks"
34
34
 
35
35
  if s.respond_to? :specification_version then
@@ -1,32 +1,41 @@
1
+ # Include this module into your spec/test case/whatever
1
2
  module Approximately
2
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
3
4
  DEFAULT_DELTA = 0.01
4
5
 
5
- # This object can be used for float comparisons. When
6
- # compared to another Float (or an object that responds to to_f)
7
- # it will be equal to that object if the float value of the ApproximateFloat
8
- # and the value being compared to are within a passed delta
9
- class DeltaFloat
6
+ # This object can be used for float comparisons. When it is instantiaded
7
+ # with a float and a delta it will respond to <=>(another_float) and
8
+ # will return equality if the float it's being compared to is within the
9
+ # delta
10
+ class DeltaFloat < Struct.new(:float, :delta)
10
11
  include Comparable
11
- attr_accessor :float, :delta
12
- alias_method :to_f, :float
13
-
14
- def initialize(float_value, delta)
15
- @float, @delta = float_value.to_f, delta
16
- end
17
12
 
18
13
  def to_f
19
- @float
14
+ float.to_f
20
15
  end
21
16
 
22
17
  def <=>(another)
23
- d = (@float - another.to_f).abs
18
+ d = (to_f - another.to_f).abs
24
19
  return 0 if d < delta
25
20
  float <=> another.to_f
26
21
  end
22
+
23
+ def inspect
24
+ "~%0.8f" % to_f
25
+ end
26
+
27
+ def to_s
28
+ inspect
29
+ end
30
+
27
31
  end
28
32
 
33
+ # Returns the passed Float into a DeltaFloat object. The optional
34
+ # second argument is the delta that will be considered sufficient for
35
+ # the comparison to evaluate to true
29
36
  def approx(float, delta = DEFAULT_DELTA)
30
37
  DeltaFloat.new(float, delta)
31
38
  end
39
+
40
+ module_function :approx
32
41
  end
@@ -1,25 +1,59 @@
1
1
  require 'helper'
2
2
 
3
- class TestApproximately < Test::Unit::TestCase
3
+ class TestModule < Test::Unit::TestCase
4
+ should "provide a module method" do
5
+ obj = Approximately.approx(10)
6
+ assert_kind_of Approximately::DeltaFloat, obj
7
+ end
8
+ end
9
+
10
+ class TestDeltaFloat < Test::Unit::TestCase
4
11
  include Approximately
5
12
 
6
13
  should "return an approximate object" do
7
14
  obj = approx(10)
8
15
  assert_kind_of Approximately::DeltaFloat, obj
9
- assert_kind_of Float, obj.float, "Should have stored a float in the attribute"
16
+ assert_kind_of Float, obj.to_f, "Should have stored a float in the attribute"
10
17
  assert_equal obj.float, obj.to_f
11
- assert_in_delta 10.0, obj.float, 0.01
18
+ assert_in_delta 10.0, obj.to_f, 0.01
12
19
  end
13
20
 
14
- should "compare to another float within delta" do
21
+ should "compare to another DeltaFloat within delta" do
15
22
  d = 0.1
16
- assert_equal approx(1, d), approx(1, d), "Should be equal within delta"
17
- assert_equal approx(1, d), approx(0.95, d), "Should be equal within delta"
18
- assert_not_equal approx(1, d), approx(1.11, d), "Should not be equal outside delta"
23
+ assert_equal DeltaFloat.new(1, d), DeltaFloat.new(1, d), "Should be equal within delta"
24
+ assert_equal DeltaFloat.new(1, d), DeltaFloat.new(0.95, d), "Should be equal within delta"
25
+ assert_not_equal DeltaFloat.new(1.0, d), DeltaFloat.new(1.11, d), "Should not be equal outside delta"
26
+ end
27
+
28
+ should "print well" do
29
+ d = 0.1
30
+ assert_equal "~1.00000000", DeltaFloat.new(1, d).to_s
31
+ end
32
+
33
+ should "compare to another float as a left-hand expression" do
34
+ assert_equal DeltaFloat.new(1.0, 0.1), 1.05, "Should be equal within delta"
35
+ end
36
+
37
+ should "compare to another float as a right-hand expression" do
38
+ assert_equal 1.05, approx(1.0, 0.1), "Should be equal within delta"
19
39
  end
20
40
 
21
41
  should "create the object with default delta" do
22
42
  a = approx(0.013)
43
+ assert_kind_of Approximately::DeltaFloat, a
44
+ assert_equal a.delta, Approximately::DEFAULT_DELTA
45
+ end
46
+
47
+ should "create the object with a module method" do
48
+ a = Approximately.approx(0.013)
49
+ assert_kind_of Approximately::DeltaFloat, a
23
50
  assert_equal a.delta, Approximately::DEFAULT_DELTA
24
51
  end
52
+
53
+ should "create the object with custom delta" do
54
+ d = 0.001
55
+ a = approx(0.013, d)
56
+ assert_equal d, a.delta
57
+ end
58
+
25
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: approximately
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-07 00:00:00.000000000 Z
12
+ date: 2012-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
16
- requirement: &9144310 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *9144310
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: bundler
27
- requirement: &9143030 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: 1.0.0
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *9143030
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.0
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: jeweler
38
- requirement: &9141960 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
@@ -43,7 +53,12 @@ dependencies:
43
53
  version: 1.8.3
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *9141960
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.3
47
62
  description:
48
63
  email: me@julik.nl
49
64
  executables: []
@@ -76,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
91
  version: '0'
77
92
  segments:
78
93
  - 0
79
- hash: -499016081
94
+ hash: -1659886568450334998
80
95
  required_rubygems_version: !ruby/object:Gem::Requirement
81
96
  none: false
82
97
  requirements:
@@ -85,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
100
  version: '0'
86
101
  requirements: []
87
102
  rubyforge_project:
88
- rubygems_version: 1.8.15
103
+ rubygems_version: 1.8.24
89
104
  signing_key:
90
105
  specification_version: 3
91
106
  summary: Facilitates float comparisons in mocks