measurb 0.0.1

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.
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb::Dimension do
4
+ before :context do
5
+ clear_defined_inches
6
+ clear_defined_feet
7
+ remove_loaded_default_dimensions
8
+
9
+ Measurb.configure do |config|
10
+ config.enable_defaults :inches, :feet
11
+ end
12
+ end
13
+
14
+ it 'defines all the comparison methods' do
15
+ expect(Measurb::Dimension).to have_method(:<=>)
16
+ expect(Measurb::Dimension).to have_method(:<)
17
+ expect(Measurb::Dimension).to have_method(:>)
18
+ expect(Measurb::Dimension).to have_method(:<=)
19
+ expect(Measurb::Dimension).to have_method(:>=)
20
+ end
21
+
22
+ it 'handles inequality operations correctly with same class' do
23
+ expect(2.feet).to_not be < 2.feet
24
+ expect(2.feet).to_not be > 2.feet
25
+ expect(2.feet).to be <= 2.feet
26
+ expect(2.feet).to be >= 2.feet
27
+ expect(2.feet <=> 2.feet).to be(0)
28
+
29
+ expect(2.feet).to be < 3.feet
30
+ expect(2.feet).to be <= 3.feet
31
+ expect(2.feet).to_not be > 3.feet
32
+ expect(2.feet).to_not be >= 3.feet
33
+ expect(2.feet <=> 3.feet).to be(-1)
34
+
35
+ expect(3.feet).to_not be < 2.feet
36
+ expect(3.feet).to_not be <= 2.feet
37
+ expect(3.feet).to be > 2.feet
38
+ expect(3.feet).to be >= 2.feet
39
+ expect(3.feet <=> 2.feet).to be(1)
40
+ end
41
+
42
+ it 'handles inequality operations correctly with a different dimension class' do
43
+ expect(2.feet).to_not be < 24.inches
44
+ expect(2.feet).to_not be > 24.inches
45
+ expect(2.feet).to be <= 24.inches
46
+ expect(2.feet).to be >= 24.inches
47
+ expect(2.feet <=> 24.inches).to be(0)
48
+
49
+ expect(2.feet).to be < 36.inches
50
+ expect(2.feet).to be <= 36.inches
51
+ expect(2.feet).to_not be > 36.inches
52
+ expect(2.feet).to_not be >= 36.inches
53
+ expect(2.feet <=> 36.inches).to be(-1)
54
+
55
+ expect(3.feet).to_not be < 24.inches
56
+ expect(3.feet).to_not be <= 24.inches
57
+ expect(3.feet).to be > 24.inches
58
+ expect(3.feet).to be >= 24.inches
59
+ expect(3.feet <=> 24.inches).to be(1)
60
+ end
61
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+ require 'rspec/expectations'
3
+
4
+ describe Measurb do
5
+ describe '.config' do
6
+ def get_config
7
+ Measurb.__send__(:config)
8
+ end
9
+
10
+ subject { get_config }
11
+
12
+ it { should be_a Measurb::Config }
13
+
14
+ describe '.enable_defaults' do
15
+ before :example do
16
+ clear_defined_inches
17
+ clear_defined_feet
18
+ clear_defined_yards
19
+ remove_loaded_default_dimensions
20
+ end
21
+
22
+ let :dims_dimensions do
23
+ Measurb.constants.reduce([]) do |array, constant_name|
24
+ constant = Measurb.const_get(constant_name)
25
+ array << constant if constant.is_a?(Class) && constant < Measurb::Dimension
26
+ array
27
+ end
28
+ end
29
+
30
+ context 'without arguments' do
31
+ subject { get_config.enable_defaults }
32
+
33
+ it "doesn't add any dimensions" do
34
+ subject
35
+ expect(dims_dimensions).to be_empty
36
+ end
37
+
38
+ it 'returns an empty array' do
39
+ expect(subject).to be_empty
40
+ end
41
+ end
42
+
43
+ context 'with one argument' do
44
+ subject { get_config.enable_defaults(:inches) }
45
+
46
+ it 'only adds the one dimension' do
47
+ subject
48
+ expect(dims_dimensions).to match_array [Measurb::Inches]
49
+ end
50
+
51
+ it 'returns the enabled dimension name in an array' do
52
+ expect(subject).to match_array [:inches]
53
+ end
54
+ end
55
+
56
+ context 'with more than one argument' do
57
+ subject { get_config.enable_defaults(:inches, :feet) }
58
+
59
+ it 'only adds the given dimensions' do
60
+ subject
61
+ expect(dims_dimensions).to match_array [Measurb::Inches, Measurb::Feet]
62
+ end
63
+
64
+ it 'returns the enabled dimension names in an array' do
65
+ expect(subject).to match_array [:inches, :feet]
66
+ end
67
+ end
68
+
69
+ context 'with fake default dimension name arguments' do
70
+ subject { get_config.enable_defaults(:inches, :miles, :feet, :leagues) }
71
+
72
+ it 'only adds the available default dimensions' do
73
+ subject
74
+ expect(dims_dimensions).to match_array [Measurb::Inches, Measurb::Feet]
75
+ end
76
+
77
+ it 'returns only the enabled available dimension names in an array' do
78
+ expect(subject).to match_array [:inches, :feet]
79
+ end
80
+
81
+ it 'outputs a warning for each unavailable default dimension name' do
82
+ expectation = "'miles' is not a default dimension\n" <<
83
+ "'leagues' is not a default dimension\n"
84
+
85
+ expect { subject }.to output(expectation).to_stderr
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb do
4
+ describe '.define' do
5
+ shared_context 'defines own conversion' do |with_abbrev = false|
6
+ it 'defines own conversion' do
7
+ expect(Measurb::Inches).to have_method(:to_inches)
8
+ end
9
+
10
+ it 'returns itself' do
11
+ n = 42.inches
12
+ expect(n.to_inches).to be(n)
13
+ end
14
+ end
15
+
16
+ context 'without define block' do
17
+ before :example do
18
+ clear_defined_inches
19
+ Measurb.define(:inches)
20
+ end
21
+
22
+ include_context 'defines own conversion'
23
+
24
+ it "doesn't have other conversions" do
25
+ expect(Measurb::Inches).to_not have_method(:to_feet)
26
+ end
27
+ end
28
+
29
+ context 'with define block' do
30
+ before :example do
31
+ clear_defined_inches
32
+ clear_defined_feet
33
+
34
+ Measurb.define(:inches) { feet value / 12.0 }
35
+ Measurb.define(:feet)
36
+ end
37
+
38
+ include_context 'defines own conversion'
39
+
40
+ it 'adds the `to_feet` conversion' do
41
+ expect(Measurb::Inches).to have_method(:to_feet)
42
+ end
43
+
44
+ it 'returns an instance of `Measurb::Feet` with the correct value' do
45
+ n = 24.inches
46
+
47
+ expect(n.to_feet).to be_a(Measurb::Feet)
48
+ expect(n.to_feet).to eq(2.feet)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb do
4
+ describe '.define' do
5
+ before :example do
6
+ clear_defined_inches
7
+ end
8
+
9
+ shared_context 'adding the Numeric method' do |method, options = {}|
10
+ it 'adds the Numeric method' do
11
+ int = 42
12
+ float = 3.14
13
+
14
+ expect { int.__send__(method) }.to raise_error(NoMethodError)
15
+ expect { float.__send__(method) }.to raise_error(NoMethodError)
16
+
17
+ Measurb.define(:inches, options)
18
+
19
+ expect(int.__send__(method)).to eq(Measurb::Inches.new(int))
20
+ expect(float.__send__(method)).to eq(Measurb::Inches.new(float))
21
+ end
22
+ end
23
+
24
+ it 'creates the class' do
25
+ expect { Measurb::Inches }.to raise_error(NameError)
26
+ Measurb.define(:inches)
27
+ expect(Measurb::Inches).to be < Measurb::Dimension
28
+ end
29
+
30
+ it 'adds the helper method' do
31
+ expect(Measurb).to_not respond_to(:inches)
32
+ Measurb.define(:inches)
33
+ expect(Measurb).to respond_to(:inches)
34
+ end
35
+
36
+ it 'returns the dimension class' do
37
+ expect(Measurb.define(:inches)).to be(Measurb::Inches)
38
+ end
39
+
40
+ it 'raises an error if the class is already defined' do
41
+ Measurb.define(:inches)
42
+
43
+ expect {
44
+ Measurb.define(:inches)
45
+ }.to raise_error(Measurb::DuplicateDimensionError, 'Already defined dimension class `Inches`')
46
+ end
47
+
48
+ include_context 'adding the Numeric method', :inches
49
+
50
+ context 'with `abbrev` option' do
51
+ include_context 'adding the Numeric method', :in, abbrev: 'in'
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb::DimensionBuilder do
4
+ describe '.get_dimension_class_name' do
5
+ def m(name)
6
+ Measurb::DimensionBuilder.get_dimension_class_name(name)
7
+ end
8
+
9
+ it 'generates the expected class name from a symbol' do
10
+ expect(m(:feet)).to eq('Feet')
11
+ expect(m(:nautical_miles)).to eq('NauticalMiles')
12
+ end
13
+
14
+ it 'generates the expected class name from a string' do
15
+ expect(m('feet')).to eq('Feet')
16
+ expect(m('nautical_miles')).to eq('NauticalMiles')
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb::Dimension do
4
+ describe '.new' do
5
+ before :context do
6
+ clear_defined_inches
7
+ clear_defined_feet
8
+ clear_defined_yards
9
+ remove_loaded_default_dimensions
10
+
11
+ Measurb.configure do |config|
12
+ config.enable_defaults :inches, :feet
13
+ end
14
+ end
15
+
16
+ let(:default_precision) { Measurb::DEFAULT_PRECISION }
17
+ let(:supplied_precision) { 2 }
18
+
19
+ let(:int) { Measurb::Inches.new(42) }
20
+ let(:int_precision) { Measurb::Inches.new(42, supplied_precision) }
21
+ let(:float) { Measurb::Inches.new(Math::PI) }
22
+ let(:float_precision) { Measurb::Inches.new(Math::PI, supplied_precision) }
23
+
24
+ context 'without precision supplied' do
25
+ it 'uses the default precision' do
26
+ expect(int).to have_precision(default_precision)
27
+ expect(float).to have_precision(default_precision)
28
+ end
29
+
30
+ it 'keeps the same precision when converted' do
31
+ expect(int.to_feet).to have_precision(int.precision)
32
+ expect(float.to_feet).to have_precision(float.precision)
33
+ end
34
+
35
+ it 'sets the value based on the precision' do
36
+ expect(int).to have_value(42.0)
37
+ expect(int).to have_value(42)
38
+ expect(float).to have_value(3.142)
39
+ expect(float).to_not have_value(Math::PI)
40
+ end
41
+
42
+ it 'rounds floats correctly' do
43
+ float1 = Measurb::Inches.new(1.2346)
44
+ float2 = Measurb::Inches.new(1.2344)
45
+ float3 = Measurb::Inches.new(1.2345)
46
+
47
+ expect(float1).to have_value(1.235)
48
+ expect(float2).to have_value(1.234)
49
+ expect(float3).to have_value(1.235)
50
+ end
51
+ end
52
+
53
+ context 'with precision supplied' do
54
+ it 'uses the supplied precision' do
55
+ expect(int_precision).to have_precision(supplied_precision)
56
+ expect(float_precision).to have_precision(supplied_precision)
57
+ end
58
+
59
+ it 'keeps the same precision when converted' do
60
+ expect(int_precision.to_feet).to have_precision(int_precision.precision)
61
+ expect(float_precision.to_feet).to have_precision(float_precision.precision)
62
+ end
63
+
64
+ it 'sets the value based on the precision' do
65
+ expect(int_precision).to have_value(42.0)
66
+ expect(int_precision).to have_value(42)
67
+ expect(float_precision).to have_value(3.14)
68
+ expect(float_precision).to_not have_value(3.1)
69
+ expect(float_precision).to_not have_value(Math::PI)
70
+ end
71
+
72
+ it 'rounds floats correctly' do
73
+ float1 = Measurb::Inches.new(1.237, supplied_precision)
74
+ float2 = Measurb::Inches.new(1.232, supplied_precision)
75
+ float3 = Measurb::Inches.new(1.235, supplied_precision)
76
+
77
+ expect(float1).to have_value(1.24)
78
+ expect(float2).to have_value(1.23)
79
+ expect(float3).to have_value(1.24)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Measurb::Dimension do
4
+ before :context do
5
+ clear_defined_inches
6
+ clear_defined_feet
7
+ remove_loaded_default_dimensions
8
+
9
+ Measurb.configure do |config|
10
+ config.enable_defaults :inches, :feet
11
+ end
12
+ end
13
+
14
+ describe '#==' do
15
+ it 'handles equality with itself correctly' do
16
+ n = 42.inches
17
+ expect(n).to eq(n)
18
+ expect(n).to be(n)
19
+ end
20
+
21
+ it 'handles equality with same dimension class correctly' do
22
+ x, y = 42.inches, 42.inches
23
+
24
+ expect(x).to eq(y)
25
+ expect(x).to_not be(y)
26
+ expect(x).to_not eq(24.inches)
27
+ end
28
+
29
+ it 'handles equality with another dimension class correctly' do
30
+ expect(24.inches).to eq(2.feet)
31
+ expect(2.inches).to_not eq(24.feet)
32
+ end
33
+ end
34
+
35
+ describe '#!=' do
36
+ it 'handles inequality with itself correctly' do
37
+ n = 42.inches
38
+ expect(n != n).to be(false)
39
+ expect(n).to be(n)
40
+ end
41
+
42
+ it 'handles inequality with same dimension class correctly' do
43
+ x = 42.inches
44
+ expect(x != 42.inches).to be(false)
45
+ expect(x != 24.inches).to be(true)
46
+ end
47
+
48
+ it 'handles inequality with another dimension class correctly' do
49
+ expect(24.inches != 2.feet).to be(false)
50
+ expect(2.inches != 24.feet).to be(true)
51
+ end
52
+ end
53
+
54
+ describe '#eql?' do
55
+ it 'recognizes equality with itself' do
56
+ n = 42.inches
57
+ expect(n).to eql(n)
58
+ expect(n).to be(n)
59
+ end
60
+
61
+ it 'recognizes equality only with dimensions of the same class and value' do
62
+ n = 24.inches
63
+
64
+ expect(n).to eql(24.inches)
65
+ expect(n).to_not eql(2.feet)
66
+ expect(n).to_not eql(3.feet)
67
+ expect(n).to_not eql(36.inches)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,26 @@
1
+ def remove_loaded_default_dimensions
2
+ $".delete_if do |file|
3
+ file =~ %r{measurb/lib/measurb/defaults}
4
+ end
5
+ end
6
+
7
+ def clear_defined_dimension(name, abbrev)
8
+ class_name = name.to_s.capitalize
9
+
10
+ Measurb.singleton_class.__send__(:remove_method, name) if Measurb.singleton_class.method_defined?(name)
11
+ Measurb.__send__(:remove_const, class_name) if Measurb.const_defined?(class_name)
12
+ Numeric.__send__(:remove_method, name) if Numeric.method_defined?(name)
13
+ Numeric.__send__(:remove_method, abbrev) if Numeric.method_defined?(abbrev)
14
+ end
15
+
16
+ def clear_defined_inches
17
+ clear_defined_dimension(:inches, :in)
18
+ end
19
+
20
+ def clear_defined_feet
21
+ clear_defined_dimension(:feet, :ft)
22
+ end
23
+
24
+ def clear_defined_yards
25
+ clear_defined_dimension(:yards, :yd)
26
+ end
@@ -0,0 +1,17 @@
1
+ RSpec::Matchers.define :have_method do |expected|
2
+ match do |actual|
3
+ actual.method_defined?(expected)
4
+ end
5
+ end
6
+
7
+ RSpec::Matchers.define :have_value do |expected|
8
+ match do |actual|
9
+ actual.value == expected
10
+ end
11
+ end
12
+
13
+ RSpec::Matchers.define :have_precision do |expected|
14
+ match do |actual|
15
+ actual.precision == expected
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Numeric do
4
+ describe '#inches' do
5
+ before :context do
6
+ clear_defined_inches
7
+ Measurb.define(:inches)
8
+ end
9
+
10
+ shared_context 'returning expected' do |n|
11
+ it 'returns the dimension class instance' do
12
+ expect(n.inches).to be_a(Measurb::Inches)
13
+ expect(n.inches).to eq(Measurb::Inches.new(n))
14
+ end
15
+ end
16
+
17
+ shared_context 'having correct precision' do |n|
18
+ it 'sets default precision without an argument' do
19
+ expect(n.inches).to have_precision(Measurb::DEFAULT_PRECISION)
20
+ end
21
+
22
+ it 'sets the supplied precision' do
23
+ expect(n.inches(2)).to have_precision(2)
24
+ end
25
+ end
26
+
27
+ context 'with integer value' do
28
+ n = 42
29
+
30
+ include_context 'returning expected', n
31
+ include_context 'having correct precision', n
32
+ end
33
+
34
+ context 'with float value' do
35
+ n = Math::PI
36
+
37
+ include_context 'returning expected', n
38
+ include_context 'having correct precision', n
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,77 @@
1
+ require 'measurb'
2
+ require 'helpers/matchers'
3
+ require 'helpers/clear_dimensions'
4
+
5
+ RSpec.configure do |config|
6
+ # Silence output
7
+ original_stderr = $stderr
8
+ original_stdout = $stdout
9
+ dummy_io = StringIO.new
10
+
11
+ config.before :context do
12
+ $stderr = dummy_io
13
+ $stdout = dummy_io
14
+ end
15
+
16
+ config.after :context do
17
+ $stderr = original_stderr
18
+ $stdout = original_stdout
19
+ end
20
+
21
+ # These two settings work together to allow you to limit a spec run
22
+ # to individual examples or groups you care about by tagging them with
23
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
24
+ # get run.
25
+ config.filter_run :focus
26
+ config.run_all_when_everything_filtered = true
27
+
28
+ # Many RSpec users commonly either run the entire suite or an individual
29
+ # file, and it's useful to allow more verbose output when running an
30
+ # individual spec file.
31
+ if config.files_to_run.one?
32
+ # Use the documentation formatter for detailed output,
33
+ # unless a formatter has already been configured
34
+ # (e.g. via a command-line flag).
35
+ config.default_formatter = 'doc'
36
+ end
37
+
38
+ # Print the 10 slowest examples and example groups at the
39
+ # end of the spec run, to help surface which specs are running
40
+ # particularly slow.
41
+ config.profile_examples = 10
42
+
43
+ # Run specs in random order to surface order dependencies. If you find an
44
+ # order dependency and want to debug it, you can fix the order by providing
45
+ # the seed, which is printed after each run.
46
+ # --seed 1234
47
+ config.order = :random
48
+
49
+ # Seed global randomization in this process using the `--seed` CLI option.
50
+ # Setting this allows you to use `--seed` to deterministically reproduce
51
+ # test failures related to randomization by passing the same `--seed` value
52
+ # as the one that triggered the failure.
53
+ Kernel.srand config.seed
54
+
55
+ # rspec-expectations config goes here. You can use an alternate
56
+ # assertion/expectation library such as wrong or the stdlib/minitest
57
+ # assertions if you prefer.
58
+ config.expect_with :rspec do |expectations|
59
+ # Enable only the newer, non-monkey-patching expect syntax.
60
+ # For more details, see:
61
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
62
+ expectations.syntax = :expect
63
+ end
64
+
65
+ # rspec-mocks config goes here. You can use an alternate test double
66
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
67
+ config.mock_with :rspec do |mocks|
68
+ # Enable only the newer, non-monkey-patching expect syntax.
69
+ # For more details, see:
70
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
71
+ mocks.syntax = :expect
72
+
73
+ # Prevents you from mocking or stubbing a method that does not exist on
74
+ # a real object. This is generally recommended.
75
+ mocks.verify_partial_doubles = true
76
+ end
77
+ end