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.
- data/README.rdoc +17 -7
- data/approximately.gemspec +3 -3
- data/lib/approximately.rb +23 -14
- data/test/test_approximately.rb +41 -7
- metadata +25 -10
data/README.rdoc
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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.
|
data/approximately.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "approximately"
|
|
8
|
-
s.version = "1.
|
|
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-
|
|
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.
|
|
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
|
data/lib/approximately.rb
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
|
+
# Include this module into your spec/test case/whatever
|
|
1
2
|
module Approximately
|
|
2
|
-
VERSION = "1.
|
|
3
|
+
VERSION = "1.1.0"
|
|
3
4
|
DEFAULT_DELTA = 0.01
|
|
4
5
|
|
|
5
|
-
# This object can be used for float comparisons. When
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
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
|
-
|
|
14
|
+
float.to_f
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
def <=>(another)
|
|
23
|
-
d = (
|
|
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
|
data/test/test_approximately.rb
CHANGED
|
@@ -1,25 +1,59 @@
|
|
|
1
1
|
require 'helper'
|
|
2
2
|
|
|
3
|
-
class
|
|
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.
|
|
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.
|
|
18
|
+
assert_in_delta 10.0, obj.to_f, 0.01
|
|
12
19
|
end
|
|
13
20
|
|
|
14
|
-
should "compare to another
|
|
21
|
+
should "compare to another DeltaFloat within delta" do
|
|
15
22
|
d = 0.1
|
|
16
|
-
assert_equal
|
|
17
|
-
assert_equal
|
|
18
|
-
assert_not_equal
|
|
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.
|
|
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-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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: -
|
|
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.
|
|
103
|
+
rubygems_version: 1.8.24
|
|
89
104
|
signing_key:
|
|
90
105
|
specification_version: 3
|
|
91
106
|
summary: Facilitates float comparisons in mocks
|