approximately 1.0.0 → 1.1.0

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