dr_light 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03cdec01261b9d5b682f4b85d71009abd4216912aaece529ada333ff4ab910e7
4
- data.tar.gz: a2e6c4d8013f389e5872de461e637bc6209365a2561b6cace450fd7d4b1ca367
3
+ metadata.gz: 6ac81b75a566891c9d1665bfe992e0cae6b17fd58966bdc73ed5262c0324daf7
4
+ data.tar.gz: 2e35f897b216a715d001ab6e4a18aeb9ccff6e29d9c64670eb707f8697a8c857
5
5
  SHA512:
6
- metadata.gz: 92a816d6c71135d96fbb5f8435aaf27316f3b44fb946c44592129ffeb8892eeac3a16c715293b978cec43490bc8e9a03587fc6ee476da1a3d0e41771fa13f914
7
- data.tar.gz: b4871424ed66e10973c2ef2e24c5197c024c5c2afbbf8d3c88ff1a2c57a3e011e466adb0334ee221f94e7618491d8f261a7918afbebea4876547c5b710167d22
6
+ metadata.gz: f79b5d554f23111d5b73b9f1e72de7fbee4e947448d8838cd460e053328b7616af3048d5b643bc544a4310f6cab36c71d715af95986d138bf28d1a656e92d5ac
7
+ data.tar.gz: 931a3d0eff2d2857cadc13e91d4cf948a9aea91f3c0b52015c498708b3fa064a77ea0c9fc5fbd32ecdca0d6ebf6784740a1c2fc40fdaafe8977491f82b8f9a00
data/README.md CHANGED
@@ -4,12 +4,11 @@ DrLight
4
4
  [![Test Coverage](https://codeclimate.com/github/darthjee/dr_light/badges/coverage.svg)](https://codeclimate.com/github/darthjee/dr_light/coverage)
5
5
  [![Issue Count](https://codeclimate.com/github/darthjee/dr_light/badges/issue_count.svg)](https://codeclimate.com/github/darthjee/dr_light)
6
6
  [![Gem Version](https://badge.fury.io/rb/dr_light.svg)](https://badge.fury.io/rb/dr_light)
7
- [![Inline docs](http://inch-ci.org/github/darthjee/dr_light.svg?branch=master)](http://inch-ci.org/github/darthjee/dr_light)
8
7
 
9
8
 
10
9
  ![dr_light](https://raw.githubusercontent.com/darthjee/dr_light/master/dr_light.jpg)
11
10
 
12
11
  Yard Documentation
13
12
  -------------------
14
- https://www.rubydoc.info/gems/dr_light/0.0.2
13
+ https://www.rubydoc.info/gems/dr_light/0.0.3
15
14
 
@@ -1,3 +1,4 @@
1
1
  ignore:
2
2
  - lib/dr_light.rb
3
3
  - lib/dr_light/version.rb
4
+ - lib/dr_light/matchers.rb
@@ -19,6 +19,7 @@ rules:
19
19
  - DrLight::ScientificNumber#value
20
20
  - DrLight::ScientificNumber#deviance
21
21
  - DrLight::ScientificNumber#initialize
22
+ - DrLight::ScientificNumber::DevianceDistance#initialize
22
23
  - DrLight::ScientificNumber::Formatter#initialize
23
24
  - DrLight::ScientificNumber::Normalizer#initialize
24
25
  ReturnTag:
@@ -27,7 +28,9 @@ rules:
27
28
  Summary::Presence:
28
29
  enabled: true
29
30
  exclude:
31
+ - DrLight::Matchers::CloseTo#initialize
30
32
  - DrLight::ScientificNumber#initialize
33
+ - DrLight::ScientificNumber::DevianceDistance#initialize
31
34
  - DrLight::ScientificNumber::Formatter#initialize
32
35
  - DrLight::ScientificNumber::Normalizer#initialize
33
36
  Summary::Length:
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrLight
4
+ # @api public
5
+ #
6
+ # Rspec matchers DSL to be included in rspec
7
+ #
8
+ # @example
9
+ # RSpec.configure do |config|
10
+ # config.include DrLight::Matchers
11
+ # end
12
+ module Matchers
13
+ autoload :CloseTo, 'dr_light/matchers/close_to'
14
+
15
+ # Checks if value is close to expected value
16
+ #
17
+ # @overload be_close_to(expected, deviance: nil)
18
+ # @param expected [Number] Target to be close to
19
+ # @param deviance [Number] Closeness deviance
20
+ #
21
+ # @overload be_close_to(expected)
22
+ # @param expected [ScientificNumber] target to be close to
23
+ #
24
+ # @return [CloseTo]
25
+ #
26
+ # @example
27
+ # describe DrLight::Matchers do
28
+ # describe 'be_close_to' do
29
+ # subject(:value) { 10.0 }
30
+ #
31
+ # context 'when they are close' do
32
+ # it do
33
+ # expect(value).to be_close_to(11, deviance: 1)
34
+ # end
35
+ # end
36
+ #
37
+ # context 'when they are not close' do
38
+ # let(:expected) { DrLight::ScientificNumber.new(9, 0.5) }
39
+ #
40
+ # it do
41
+ # expect(value).not_to be_close_to(expected)
42
+ # end
43
+ # end
44
+ # end
45
+ # end
46
+ def be_close_to(expected, deviance: nil)
47
+ CloseTo.new(expected, deviance)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrLight
4
+ module Matchers
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Matcher checking that 2 numbers are
9
+ # close to each other
10
+ class CloseTo < RSpec::Matchers::BuiltIn::BaseMatcher
11
+ # @overload initialize(expected, deviance)
12
+ # @param expected [Number] expected value
13
+ # to be close to
14
+ # @param deviance [Number] Proximity deviance
15
+ # @overload initialize(expected)
16
+ # @param expected [ScientificNumber] expected value
17
+ # to be close to
18
+ def initialize(expected, deviance)
19
+ @expected = if expected.is_a?(ScientificNumber)
20
+ expected
21
+ else
22
+ ScientificNumber.new(expected, deviance)
23
+ end
24
+ end
25
+
26
+ # returns if actual is close to expected
27
+ #
28
+ # @return [TrueClass,FalseClass]
29
+ def matches?(actual)
30
+ @actual = actual
31
+
32
+ distance <= 1.0
33
+ end
34
+
35
+ # returns matcher description on success
36
+ #
37
+ # @return [String]
38
+ def description
39
+ "be close to #{expected}"
40
+ end
41
+
42
+ # returns message for failure on should
43
+ #
44
+ # @return [String]
45
+ def failure_message_for_should
46
+ "expected #{actual} to be close to #{expected} but " \
47
+ "was #{distance} deviances far away"
48
+ end
49
+
50
+ # returns message for failure on should not
51
+ #
52
+ # @return [String]
53
+ def failure_message_for_should_not
54
+ "expected #{actual} not to be close to #{expected} " \
55
+ "but was only #{distance} deviances far away"
56
+ end
57
+
58
+ alias failure_message failure_message_for_should
59
+ alias failure_message_when_negated failure_message_for_should_not
60
+
61
+ private
62
+
63
+ attr_reader :expected, :actual
64
+ # @method expected
65
+ # @api private
66
+ # @private
67
+ #
68
+ # expected value to be close to
69
+ #
70
+ # @return [ScientificNumber]
71
+
72
+ # @method actual
73
+ # @api private
74
+ # @private
75
+ #
76
+ # value to be close to expected
77
+ #
78
+ # @return [Number,ScientificNumber]
79
+
80
+ # distance in deviances between the 2 numbers
81
+ #
82
+ # @return [Float]
83
+ def distance
84
+ @distance ||= expected.deviance_distance(actual)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -6,6 +6,9 @@ module DrLight
6
6
  #
7
7
  # Number to be exibed in scientific number
8
8
  class ScientificNumber
9
+ autoload :DevianceDistance,
10
+ 'dr_light/scientific_number/deviance_distance'
11
+
9
12
  autoload :Formatter, 'dr_light/scientific_number/formatter'
10
13
  autoload :Normalizer, 'dr_light/scientific_number/normalizer'
11
14
 
@@ -26,9 +29,9 @@ module DrLight
26
29
 
27
30
  # @param value [Nuber] number to be exibed
28
31
  # @param deviance [Number] deviance of number
29
- def initialize(value, deviance = 0)
30
- @value = value
31
- @deviance = deviance
32
+ def initialize(value, deviance = nil)
33
+ @value = value.to_f
34
+ @deviance = deviance.to_f
32
35
  end
33
36
 
34
37
  # string representation of number
@@ -47,6 +50,29 @@ module DrLight
47
50
  )
48
51
  end
49
52
 
53
+ # Calculates the distance to another number in deviances
54
+ #
55
+ # the deviance will be a composition of both numbers
56
+ # deviances
57
+ #
58
+ # @example With Number
59
+ # number = DrLight::ScientificNumber.new(100, 3)
60
+ #
61
+ # number.deviance_distance(115) # returns 5
62
+ #
63
+ # @example With scientifica number
64
+ # number = DrLight::ScientificNumber.new(100, 3)
65
+ # other = DrLight::ScientificNumber.new(115, 4)
66
+ #
67
+ # number.deviance_distance(other) # returns 3
68
+ #
69
+ # @see DevianceDistance
70
+ #
71
+ # @return [Float] always positive number
72
+ def deviance_distance(other)
73
+ DevianceDistance.new(self, other).to_f
74
+ end
75
+
50
76
  private
51
77
 
52
78
  # @private
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrLight
4
+ class ScientificNumber
5
+ # @api private
6
+ #
7
+ # @author Dathjee
8
+ #
9
+ # Class Responsible for calculating distance between 2 numbers
10
+ # in number of deviances
11
+ #
12
+ # The combined deviance of numbers n1(d1), n2(d2)
13
+ # is d = sqrt(d1 ** 2 + d2 ** 2)
14
+ #
15
+ # @example With scientific number
16
+ # number = DrLight::ScientificNumber.new(100, 3)
17
+ # other = DrLight::ScientificNumber.new(110, 4)
18
+ #
19
+ # distance = DrLight::ScientificNumber::DevianceDistance.new(
20
+ # number, other
21
+ # )
22
+ #
23
+ # distance.to_f # returns 2
24
+ #
25
+ # @example With scientific number
26
+ # number = DrLight::ScientificNumber.new(100, 3)
27
+ # other = 91
28
+ #
29
+ # distance = DrLight::ScientificNumber::DevianceDistance.new(
30
+ # number, other
31
+ # )
32
+ #
33
+ # distance.to_f # returns 3
34
+ class DevianceDistance
35
+ # @param number [ScientificNumber] first number
36
+ # @param other [ScientificNumber,Number] second number
37
+ def initialize(number, other)
38
+ @number = number
39
+
40
+ @other = if other.is_a?(ScientificNumber)
41
+ other
42
+ else
43
+ ScientificNumber.new(other)
44
+ end
45
+ end
46
+
47
+ # Calculates the distance of numbers in deviances
48
+ #
49
+ # @return [Float] always positive number
50
+ def to_f
51
+ return 0 if difference.zero?
52
+
53
+ difference / deviance
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :number, :other
59
+ # @method number
60
+ # @api private
61
+ # @private
62
+ #
63
+ # first number
64
+ #
65
+ # @return [ScientificNumber]
66
+
67
+ # @method other
68
+ # @api private
69
+ # @private
70
+ #
71
+ # second_number
72
+ #
73
+ # @return [ScientificNumber]
74
+
75
+ # @private
76
+ # Raw difference between two numbers
77
+ #
78
+ # @return [Float] always positive number
79
+ def difference
80
+ @difference ||= (other.value - number.value).abs
81
+ end
82
+
83
+ # @private
84
+ #
85
+ # Combined deviances
86
+ #
87
+ # Combined deviances of n1(d1) and n2(d2)
88
+ # is d = sqrt(d1 ** 2 + d2 ** 2)
89
+ #
90
+ # @return [Float] always positive number
91
+ def deviance
92
+ @deviance ||= Math.sqrt(
93
+ number.deviance**2 + other.deviance**2
94
+ )
95
+ end
96
+ end
97
+ end
98
+ end
@@ -8,8 +8,8 @@ module DrLight
8
8
  # Class responsible for formatting the values of
9
9
  # {ScientificNumber}
10
10
  class Formatter
11
- # @param value [Numeric] number to be exibed
12
- # @param deviance [Numeric] deviance of number
11
+ # @param normalizer [Normalizer] normalizer with number
12
+ # and deviance information
13
13
  def initialize(normalizer)
14
14
  @normalizer = normalizer
15
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DrLight
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DrLight::Matchers do
6
+ describe 'be_close_to' do
7
+ subject(:value) { 10.0 }
8
+
9
+ context 'when passing numbers without deviance' do
10
+ context 'when they are the same' do
11
+ it do
12
+ expect(value).to be_close_to(10)
13
+ end
14
+ end
15
+
16
+ context 'when they are not the same' do
17
+ it do
18
+ expect(value).not_to be_close_to(10.00001)
19
+ end
20
+ end
21
+ end
22
+
23
+ context 'when passing numbers with deviance' do
24
+ context 'when they are the same' do
25
+ it do
26
+ expect(value).to be_close_to(10, deviance: 1)
27
+ end
28
+ end
29
+
30
+ context 'when they are not the same but close' do
31
+ it do
32
+ expect(value).to be_close_to(11, deviance: 1)
33
+ end
34
+ end
35
+
36
+ context 'when they are not the same and not close' do
37
+ it do
38
+ expect(value).not_to be_close_to(11.1, deviance: 1)
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when passing scientific number for expected' do
44
+ context 'when they are the same' do
45
+ let(:expected) { DrLight::ScientificNumber.new(10, 1) }
46
+
47
+ it do
48
+ expect(value).to be_close_to(expected)
49
+ end
50
+ end
51
+
52
+ context 'when they are not the same but close' do
53
+ let(:expected) { DrLight::ScientificNumber.new(9, 1) }
54
+
55
+ it do
56
+ expect(value).to be_close_to(expected)
57
+ end
58
+ end
59
+
60
+ context 'when they are not the same and not close' do
61
+ let(:expected) { DrLight::ScientificNumber.new(8.9, 1) }
62
+
63
+ it do
64
+ expect(value).not_to be_close_to(expected)
65
+ end
66
+ end
67
+ end
68
+
69
+ context 'when scientific number is close to number' do
70
+ let(:value) { DrLight::ScientificNumber.new(10, 1) }
71
+
72
+ context 'when they are the same' do
73
+ it do
74
+ expect(value).to be_close_to(10)
75
+ end
76
+ end
77
+
78
+ context 'when they are not the same but close' do
79
+ it do
80
+ expect(value).to be_close_to(11)
81
+ end
82
+ end
83
+
84
+ context 'when they are not the same but not close' do
85
+ it do
86
+ expect(value).not_to be_close_to(8)
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'when both are scientific numbers' do
92
+ let(:value) { DrLight::ScientificNumber.new(10, 3) }
93
+
94
+ context 'when they are the same' do
95
+ let(:other) { DrLight::ScientificNumber.new(10, 4) }
96
+
97
+ it do
98
+ expect(value).to be_close_to(other)
99
+ end
100
+ end
101
+
102
+ context 'when they are not the same but close' do
103
+ let(:other) { DrLight::ScientificNumber.new(5, 4) }
104
+
105
+ it do
106
+ expect(value).to be_close_to(other)
107
+ end
108
+ end
109
+
110
+ context 'when they are not the same but not close' do
111
+ let(:other) { DrLight::ScientificNumber.new(16, 4) }
112
+
113
+ it do
114
+ expect(value).not_to be_close_to(other)
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DrLight::Matchers do
6
+ describe 'be_close_to' do
7
+ subject(:value) { 10.0 }
8
+
9
+ context 'when they are close' do
10
+ it do
11
+ expect(value).to be_close_to(11, deviance: 1)
12
+ end
13
+ end
14
+
15
+ context 'when they are not close' do
16
+ let(:expected) { DrLight::ScientificNumber.new(9, 0.5) }
17
+
18
+ it do
19
+ expect(value).not_to be_close_to(expected)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DrLight::ScientificNumber::DevianceDistance do
6
+ describe '#to_f' do
7
+ describe 'yard' do
8
+ subject(:distance) { described_class.new(number, other) }
9
+
10
+ let(:number) { DrLight::ScientificNumber.new(100, 3) }
11
+
12
+ context 'with scientific number' do
13
+ let(:other) { DrLight::ScientificNumber.new(110, 4) }
14
+
15
+ it 'calculates distance' do
16
+ expect(distance.to_f).to eq(2)
17
+ end
18
+ end
19
+
20
+ context 'with number' do
21
+ let(:other) { 91 }
22
+
23
+ it 'calculates distance' do
24
+ expect(distance.to_f).to eq(3)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -15,4 +15,22 @@ describe DrLight::ScientificNumber do
15
15
  end
16
16
  end
17
17
  end
18
+
19
+ describe 'deviance_distance' do
20
+ subject(:number) { described_class.new(100, 3) }
21
+
22
+ context 'when other is a number' do
23
+ it 'returns the deviance distance' do
24
+ expect(number.deviance_distance(115)).to eq(5)
25
+ end
26
+ end
27
+
28
+ context 'when other is a scientific number' do
29
+ let(:other) { described_class.new(115, 4) }
30
+
31
+ it 'returns the deviance distance' do
32
+ expect(number.deviance_distance(other)).to eq(3)
33
+ end
34
+ end
35
+ end
18
36
  end
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DrLight::Matchers::CloseTo do
6
+ subject(:matcher) { described_class.new(expected, deviance) }
7
+
8
+ let(:expected) { 120 }
9
+ let(:deviance) { 10 }
10
+
11
+ describe '#matches?' do
12
+ context 'when passing a number' do
13
+ context 'when passing a number smaller, but within 1 deviance' do
14
+ let(:number) { 111 }
15
+
16
+ it do
17
+ expect(matcher).to be_matches(number)
18
+ end
19
+ end
20
+
21
+ context 'when passing a number bigger, but within 2 deviance' do
22
+ let(:number) { 139 }
23
+
24
+ it do
25
+ expect(matcher).not_to be_matches(number)
26
+ end
27
+ end
28
+
29
+ context 'when passing a number equal' do
30
+ let(:number) { 120 }
31
+
32
+ it do
33
+ expect(matcher).to be_matches(number)
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'when passing a scientific number without deviance' do
39
+ context 'when passing a number smaller, but within 1 deviance' do
40
+ let(:number) { DrLight::ScientificNumber.new(111) }
41
+
42
+ it do
43
+ expect(matcher).to be_matches(number)
44
+ end
45
+ end
46
+
47
+ context 'when passing a number bigger, but within 2 deviance' do
48
+ let(:number) { DrLight::ScientificNumber.new(139) }
49
+
50
+ it do
51
+ expect(matcher).not_to be_matches(number)
52
+ end
53
+ end
54
+
55
+ context 'when passing a number equal' do
56
+ let(:number) { DrLight::ScientificNumber.new(120) }
57
+
58
+ it do
59
+ expect(matcher).to be_matches(number)
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'when passing a scientific number and having no deviance' do
65
+ let(:deviance) { 0 }
66
+
67
+ context 'when passing a number smaller, but within 1 deviance' do
68
+ let(:number) { DrLight::ScientificNumber.new(111) }
69
+
70
+ it do
71
+ expect(matcher).not_to be_matches(number)
72
+ end
73
+ end
74
+
75
+ context 'when passing a number bigger, but within 2 deviance' do
76
+ let(:number) { DrLight::ScientificNumber.new(139) }
77
+
78
+ it do
79
+ expect(matcher).not_to be_matches(number)
80
+ end
81
+ end
82
+
83
+ context 'when passing a number equal' do
84
+ let(:number) { DrLight::ScientificNumber.new(120) }
85
+
86
+ it do
87
+ expect(matcher).to be_matches(number)
88
+ end
89
+ end
90
+ end
91
+
92
+ context 'when passing a scientific number with deviance' do
93
+ let(:deviance) { 40 }
94
+
95
+ context 'when passing a number smaller, but within 1 deviance' do
96
+ let(:number) { DrLight::ScientificNumber.new(80, 30) }
97
+
98
+ it do
99
+ expect(matcher).to be_matches(number)
100
+ end
101
+ end
102
+
103
+ context 'when passing a number bigger, but within 2 deviance' do
104
+ let(:number) { DrLight::ScientificNumber.new(30, 30) }
105
+
106
+ it do
107
+ expect(matcher).not_to be_matches(number)
108
+ end
109
+ end
110
+
111
+ context 'when passing a number equal' do
112
+ let(:number) { DrLight::ScientificNumber.new(120, 30) }
113
+
114
+ it do
115
+ expect(matcher).to be_matches(number)
116
+ end
117
+ end
118
+ end
119
+
120
+ context 'when passing a number with deviance and having no deviance' do
121
+ let(:deviance) { 0 }
122
+
123
+ context 'when passing a number smaller, but within 1 deviance' do
124
+ let(:number) { DrLight::ScientificNumber.new(111, 10) }
125
+
126
+ it do
127
+ expect(matcher).to be_matches(number)
128
+ end
129
+ end
130
+
131
+ context 'when passing a number bigger, but within 2 deviance' do
132
+ let(:number) { DrLight::ScientificNumber.new(139, 10) }
133
+
134
+ it do
135
+ expect(matcher).not_to be_matches(number)
136
+ end
137
+ end
138
+
139
+ context 'when passing a number equal' do
140
+ let(:number) { DrLight::ScientificNumber.new(120, 10) }
141
+
142
+ it do
143
+ expect(matcher).to be_matches(number)
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ describe '#description' do
150
+ it 'returns description' do
151
+ expect(matcher.description)
152
+ .to eq('be close to 1.20(10)e2')
153
+ end
154
+ end
155
+
156
+ describe '#failure_message_for_should' do
157
+ it 'returns failure message' do
158
+ expect(matcher.failure_message_for_should)
159
+ .to eq(
160
+ 'expected to be close to 1.20(10)e2 ' \
161
+ 'but was 12.0 deviances far away'
162
+ )
163
+ end
164
+ end
165
+
166
+ describe '#failure_message' do
167
+ it 'returns failure message' do
168
+ expect(matcher.failure_message)
169
+ .to eq(
170
+ 'expected to be close to 1.20(10)e2 ' \
171
+ 'but was 12.0 deviances far away'
172
+ )
173
+ end
174
+ end
175
+
176
+ describe '#failure_message_for_should_not' do
177
+ it 'returns failure message' do
178
+ expect(matcher.failure_message_for_should_not)
179
+ .to eq(
180
+ 'expected not to be close to 1.20(10)e2 but ' \
181
+ 'was only 12.0 deviances far away'
182
+ )
183
+ end
184
+ end
185
+
186
+ describe '#failure_message_when_negated' do
187
+ it 'returns failure message' do
188
+ expect(matcher.failure_message_when_negated)
189
+ .to eq(
190
+ 'expected not to be close to 1.20(10)e2 but ' \
191
+ 'was only 12.0 deviances far away'
192
+ )
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,191 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DrLight::ScientificNumber::DevianceDistance do
6
+ subject(:distance) { described_class.new(number, other) }
7
+
8
+ let(:value) { 120 }
9
+ let(:deviance) { 10 }
10
+ let(:number) do
11
+ DrLight::ScientificNumber.new(value, deviance)
12
+ end
13
+
14
+ describe 'to_f' do
15
+ context 'when passing a number' do
16
+ context 'when passing a number smaller, but within 1 deviance' do
17
+ let(:other) { 111 }
18
+
19
+ it do
20
+ expect(distance.to_f).to be_positive
21
+ end
22
+
23
+ it 'returns deviance distance' do
24
+ expect(distance.to_f).to eq(0.9)
25
+ end
26
+ end
27
+
28
+ context 'when passing a number bigger, but within 2 deviance' do
29
+ let(:other) { 139 }
30
+
31
+ it do
32
+ expect(distance.to_f).to be_positive
33
+ end
34
+
35
+ it 'returns deviance distance' do
36
+ expect(distance.to_f).to eq(1.9)
37
+ end
38
+ end
39
+
40
+ context 'when passing a number equal' do
41
+ let(:other) { 120 }
42
+
43
+ it do
44
+ expect(distance.to_f).to be_zero
45
+ end
46
+ end
47
+ end
48
+
49
+ context 'when passing a scientific number without deviance' do
50
+ context 'when passing a number smaller, but within 1 deviance' do
51
+ let(:other) { DrLight::ScientificNumber.new(111) }
52
+
53
+ it do
54
+ expect(distance.to_f).to be_positive
55
+ end
56
+
57
+ it 'returns deviance distance' do
58
+ expect(distance.to_f).to eq(0.9)
59
+ end
60
+ end
61
+
62
+ context 'when passing a number bigger, but within 2 deviance' do
63
+ let(:other) { DrLight::ScientificNumber.new(139) }
64
+
65
+ it do
66
+ expect(distance.to_f).to be_positive
67
+ end
68
+
69
+ it 'returns deviance distance' do
70
+ expect(distance.to_f).to eq(1.9)
71
+ end
72
+ end
73
+
74
+ context 'when passing a number equal' do
75
+ let(:other) { DrLight::ScientificNumber.new(120) }
76
+
77
+ it do
78
+ expect(distance.to_f).to be_zero
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'when passing a scientific number and having no deviance' do
84
+ let(:deviance) { 0 }
85
+
86
+ context 'when passing a number smaller, but within 1 deviance' do
87
+ let(:other) { DrLight::ScientificNumber.new(111) }
88
+
89
+ it do
90
+ expect(distance.to_f).to be_positive
91
+ end
92
+
93
+ it do
94
+ expect(distance.to_f).to eq(Float::INFINITY)
95
+ end
96
+ end
97
+
98
+ context 'when passing a number bigger, but within 2 deviance' do
99
+ let(:other) { DrLight::ScientificNumber.new(139) }
100
+
101
+ it do
102
+ expect(distance.to_f).to be_positive
103
+ end
104
+
105
+ it do
106
+ expect(distance.to_f).to eq(Float::INFINITY)
107
+ end
108
+ end
109
+
110
+ context 'when passing a number equal' do
111
+ let(:other) { DrLight::ScientificNumber.new(120) }
112
+
113
+ it do
114
+ expect(distance.to_f).to be_zero
115
+ end
116
+ end
117
+ end
118
+
119
+ context 'when passing a scientific number with deviance' do
120
+ let(:deviance) { 40 }
121
+
122
+ context 'when passing a number smaller, but within 1 deviance' do
123
+ let(:other) { DrLight::ScientificNumber.new(80, 30) }
124
+
125
+ it do
126
+ expect(distance.to_f).to be_positive
127
+ end
128
+
129
+ it 'returns deviance distance with combined deviance' do
130
+ expect(distance.to_f).to eq(0.8)
131
+ end
132
+ end
133
+
134
+ context 'when passing a number bigger, but within 2 deviance' do
135
+ let(:other) { DrLight::ScientificNumber.new(30, 30) }
136
+
137
+ it do
138
+ expect(distance.to_f).to be_positive
139
+ end
140
+
141
+ it 'returns deviance distance with combined deviance' do
142
+ expect(distance.to_f).to eq(1.8)
143
+ end
144
+ end
145
+
146
+ context 'when passing a number equal' do
147
+ let(:other) { DrLight::ScientificNumber.new(120, 30) }
148
+
149
+ it do
150
+ expect(distance.to_f).to be_zero
151
+ end
152
+ end
153
+ end
154
+
155
+ context 'when passing a number with deviance and having no deviance' do
156
+ let(:deviance) { 0 }
157
+
158
+ context 'when passing a number smaller, but within 1 deviance' do
159
+ let(:other) { DrLight::ScientificNumber.new(111, 10) }
160
+
161
+ it do
162
+ expect(distance.to_f).to be_positive
163
+ end
164
+
165
+ it 'returns deviance distance with combined deviance' do
166
+ expect(distance.to_f).to eq(0.9)
167
+ end
168
+ end
169
+
170
+ context 'when passing a number bigger, but within 2 deviance' do
171
+ let(:other) { DrLight::ScientificNumber.new(139, 10) }
172
+
173
+ it do
174
+ expect(distance.to_f).to be_positive
175
+ end
176
+
177
+ it 'returns deviance distance with combined deviance' do
178
+ expect(distance.to_f).to eq(1.9)
179
+ end
180
+ end
181
+
182
+ context 'when passing a number equal' do
183
+ let(:other) { DrLight::ScientificNumber.new(120, 10) }
184
+
185
+ it do
186
+ expect(distance.to_f).to be_zero
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
@@ -5,12 +5,13 @@ require 'spec_helper'
5
5
  shared_examples 'value normalized' do |order:, expctd_order: 1, devnc_fctr: 0|
6
6
  let(:multiplier) { 0.1 * 10**order }
7
7
  let(:expected_multiplier) { 10**expctd_order }
8
+ let(:random) { Random.rand * 0.9 + 0.1 }
8
9
  let(:deviance) do
9
10
  Random.rand * multiplier * devnc_fctr
10
11
  end
11
12
 
12
13
  context 'when value is positive' do
13
- let(:value) { Random.rand * multiplier }
14
+ let(:value) { random * multiplier }
14
15
  let(:range) do
15
16
  [0.1 * expected_multiplier, expected_multiplier]
16
17
  end
@@ -21,7 +22,7 @@ shared_examples 'value normalized' do |order:, expctd_order: 1, devnc_fctr: 0|
21
22
  end
22
23
 
23
24
  context 'when value is positive' do
24
- let(:value) { -1 * Random.rand * multiplier }
25
+ let(:value) { -1 * random * multiplier }
25
26
  let(:range) do
26
27
  [-expected_multiplier, -0.1 * expected_multiplier]
27
28
  end
@@ -5,6 +5,9 @@ require 'spec_helper'
5
5
  describe DrLight::ScientificNumber do
6
6
  subject(:number) { described_class.new(value, deviance) }
7
7
 
8
+ let(:value) { 120 }
9
+ let(:deviance) { 10 }
10
+
8
11
  describe '#to_s' do
9
12
  context 'when there is no deviance' do
10
13
  subject(:number) { described_class.new(value) }
@@ -436,4 +439,182 @@ describe DrLight::ScientificNumber do
436
439
  end
437
440
  end
438
441
  end
442
+
443
+ describe 'deviance_distance?' do
444
+ context 'when passing a number' do
445
+ context 'when passing a number smaller, but within 1 deviance' do
446
+ let(:other) { 111 }
447
+
448
+ it do
449
+ expect(number.deviance_distance(other)).to be_positive
450
+ end
451
+
452
+ it 'returns deviance distance' do
453
+ expect(number.deviance_distance(other)).to eq(0.9)
454
+ end
455
+ end
456
+
457
+ context 'when passing a number bigger, but within 2 deviance' do
458
+ let(:other) { 139 }
459
+
460
+ it do
461
+ expect(number.deviance_distance(other)).to be_positive
462
+ end
463
+
464
+ it 'returns deviance distance' do
465
+ expect(number.deviance_distance(other)).to eq(1.9)
466
+ end
467
+ end
468
+
469
+ context 'when passing a number equal' do
470
+ let(:other) { 120 }
471
+
472
+ it do
473
+ expect(number.deviance_distance(other)).to be_zero
474
+ end
475
+ end
476
+ end
477
+
478
+ context 'when passing a scientific number without deviance' do
479
+ context 'when passing a number smaller, but within 1 deviance' do
480
+ let(:other) { described_class.new(111) }
481
+
482
+ it do
483
+ expect(number.deviance_distance(other)).to be_positive
484
+ end
485
+
486
+ it 'returns deviance distance' do
487
+ expect(number.deviance_distance(other)).to eq(0.9)
488
+ end
489
+ end
490
+
491
+ context 'when passing a number bigger, but within 2 deviance' do
492
+ let(:other) { described_class.new(139) }
493
+
494
+ it do
495
+ expect(number.deviance_distance(other)).to be_positive
496
+ end
497
+
498
+ it 'returns deviance distance' do
499
+ expect(number.deviance_distance(other)).to eq(1.9)
500
+ end
501
+ end
502
+
503
+ context 'when passing a number equal' do
504
+ let(:other) { described_class.new(120) }
505
+
506
+ it do
507
+ expect(number.deviance_distance(other)).to be_zero
508
+ end
509
+ end
510
+ end
511
+
512
+ context 'when passing a scientific number and having no deviance' do
513
+ let(:deviance) { 0 }
514
+
515
+ context 'when passing a number smaller, but within 1 deviance' do
516
+ let(:other) { described_class.new(111) }
517
+
518
+ it do
519
+ expect(number.deviance_distance(other)).to be_positive
520
+ end
521
+
522
+ it do
523
+ expect(number.deviance_distance(other)).to eq(Float::INFINITY)
524
+ end
525
+ end
526
+
527
+ context 'when passing a number bigger, but within 2 deviance' do
528
+ let(:other) { described_class.new(139) }
529
+
530
+ it do
531
+ expect(number.deviance_distance(other)).to be_positive
532
+ end
533
+
534
+ it do
535
+ expect(number.deviance_distance(other)).to eq(Float::INFINITY)
536
+ end
537
+ end
538
+
539
+ context 'when passing a number equal' do
540
+ let(:other) { described_class.new(120) }
541
+
542
+ it do
543
+ expect(number.deviance_distance(other)).to be_zero
544
+ end
545
+ end
546
+ end
547
+
548
+ context 'when passing a scientific number with deviance' do
549
+ let(:deviance) { 40 }
550
+
551
+ context 'when passing a number smaller, but within 1 deviance' do
552
+ let(:other) { described_class.new(80, 30) }
553
+
554
+ it do
555
+ expect(number.deviance_distance(other)).to be_positive
556
+ end
557
+
558
+ it 'returns deviance distance with combined deviance' do
559
+ expect(number.deviance_distance(other)).to eq(0.8)
560
+ end
561
+ end
562
+
563
+ context 'when passing a number bigger, but within 2 deviance' do
564
+ let(:other) { described_class.new(30, 30) }
565
+
566
+ it do
567
+ expect(number.deviance_distance(other)).to be_positive
568
+ end
569
+
570
+ it 'returns deviance distance with combined deviance' do
571
+ expect(number.deviance_distance(other)).to eq(1.8)
572
+ end
573
+ end
574
+
575
+ context 'when passing a number equal' do
576
+ let(:other) { described_class.new(120, 30) }
577
+
578
+ it do
579
+ expect(number.deviance_distance(other)).to be_zero
580
+ end
581
+ end
582
+ end
583
+
584
+ context 'when passing a number with deviance and having no deviance' do
585
+ let(:deviance) { 0 }
586
+
587
+ context 'when passing a number smaller, but within 1 deviance' do
588
+ let(:other) { described_class.new(111, 10) }
589
+
590
+ it do
591
+ expect(number.deviance_distance(other)).to be_positive
592
+ end
593
+
594
+ it 'returns deviance distance with combined deviance' do
595
+ expect(number.deviance_distance(other)).to eq(0.9)
596
+ end
597
+ end
598
+
599
+ context 'when passing a number bigger, but within 2 deviance' do
600
+ let(:other) { described_class.new(139, 10) }
601
+
602
+ it do
603
+ expect(number.deviance_distance(other)).to be_positive
604
+ end
605
+
606
+ it 'returns deviance distance with combined deviance' do
607
+ expect(number.deviance_distance(other)).to eq(1.9)
608
+ end
609
+ end
610
+
611
+ context 'when passing a number equal' do
612
+ let(:other) { described_class.new(120, 10) }
613
+
614
+ it do
615
+ expect(number.deviance_distance(other)).to be_zero
616
+ end
617
+ end
618
+ end
619
+ end
439
620
  end
@@ -9,6 +9,7 @@ end
9
9
  SimpleCov.start 'gem'
10
10
 
11
11
  require 'dr_light'
12
+ require 'dr_light/matchers'
12
13
  require 'pry-nav'
13
14
 
14
15
  support_files = File.expand_path('spec/support/**/*.rb')
@@ -20,4 +21,5 @@ RSpec.configure do |config|
20
21
  config.filter_run_excluding :integration unless ENV['ALL']
21
22
 
22
23
  config.order = 'random'
24
+ config.include DrLight::Matchers
23
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dr_light
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
@@ -257,13 +257,21 @@ files:
257
257
  - docker-compose.yml
258
258
  - dr_light.gemspec
259
259
  - lib/dr_light.rb
260
+ - lib/dr_light/matchers.rb
261
+ - lib/dr_light/matchers/close_to.rb
260
262
  - lib/dr_light/scientific_number.rb
263
+ - lib/dr_light/scientific_number/deviance_distance.rb
261
264
  - lib/dr_light/scientific_number/formatter.rb
262
265
  - lib/dr_light/scientific_number/normalizer.rb
263
266
  - lib/dr_light/utils.rb
264
267
  - lib/dr_light/version.rb
268
+ - spec/integration/dr_light/matchers_spec.rb
269
+ - spec/integration/yard/dr_light/matchers_spec.rb
270
+ - spec/integration/yard/dr_light/scientific_number/deviance_distance_spec.rb
265
271
  - spec/integration/yard/dr_light/scientific_number_spec.rb
266
272
  - spec/integration/yard/dr_light/utils_spec.rb
273
+ - spec/lib/dr_light/matchers/close_to_spec.rb
274
+ - spec/lib/dr_light/scientific_number/deviance_distance_spec.rb
267
275
  - spec/lib/dr_light/scientific_number/formatter_spec.rb
268
276
  - spec/lib/dr_light/scientific_number/normalizer_spec.rb
269
277
  - spec/lib/dr_light/scientific_number_spec.rb