english_number 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a053e2c56dfe0f64d6f63e9e60719e71293ea963
4
+ data.tar.gz: 556c5c36185fdc0132ebb64e1aa85f3810fb0223
5
+ SHA512:
6
+ metadata.gz: e1f7feb9e523690330727b652475f90138805d1b2f4b10ec3a0af600a02f1856eb4ac6dfe92d6f59dcbdf23dd973e11780bb6292b7372ae8cccb82a372fb3ba8
7
+ data.tar.gz: 6ac17d9095c4df023d5348505e0d1d76abdd01d968c267d13d79b3f87a9a05fa7f78d4a393c76417b132a963e646e2ad6ca819b44b48d81d7653a2531231275b
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .byebug_history
2
+ Gemfile.lock
3
+ coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'activesupport'
4
+
5
+ group :test do
6
+ gem 'rspec', '~> 3.0'
7
+ gem 'simplecov', :require => false
8
+ end
9
+
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'english_number'
3
+ s.version = '0.0.1'
4
+ s.date = '2016-05-13'
5
+ s.summary = "Converting English numbers to strings"
6
+ s.description = "Example: EnglishNumber.new(63).in_english # => 'sixty-three'.
7
+ EnglishNumber objects can be added, subtracted, multiplied, divided."
8
+
9
+ s.authors = ["Piotr Brych"]
10
+ s.email = 'pbrych@gmail.com'
11
+ s.files = `git ls-files`.split($/)
12
+ s.homepage = 'http://rubygems.org/gems/english-number.rb'
13
+
14
+ s.add_dependency 'activesupport', '~> 4.2.6'
15
+ s.add_development_dependency 'rspec', '~> 3.4.0'
16
+ s.add_development_dependency 'simplecov', '~> 0.11.2'
17
+
18
+ s.license = 'MIT'
19
+ end
@@ -0,0 +1,44 @@
1
+ require 'modules/compute'
2
+ require 'modules/translate'
3
+
4
+ class TwoDigits
5
+ include Compute
6
+ include Translate
7
+
8
+ def self.run(num)
9
+ new(num).in_words
10
+ end
11
+
12
+ def in_words
13
+ less_than_20? ? less_than_20 : more_than_19
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :num
19
+
20
+ def initialize(num)
21
+ @num = num
22
+ end
23
+
24
+ def less_than_20?
25
+ num_abs < 20
26
+ end
27
+
28
+ def less_than_20
29
+ numbers_in_words['tenss'][num_mod]
30
+ end
31
+
32
+ def more_than_19
33
+ num_mod.zero? ? simple_tens : complex_tens
34
+ end
35
+
36
+ def simple_tens
37
+ numbers_in_words['tens'][num_abs/10]
38
+ end
39
+
40
+ def complex_tens
41
+ simple_tens+'-'+numbers_in_words['ones'][num_mod]
42
+ end
43
+
44
+ end
@@ -0,0 +1,21 @@
1
+ require 'yaml'
2
+ require 'active_support/inflector'
3
+
4
+ require 'digits/two_digits'
5
+ require 'modules/compute'
6
+ require 'modules/translate'
7
+
8
+ class EnglishNumber
9
+ include Compute
10
+ include Translate
11
+ attr_reader :num
12
+
13
+ def initialize(num)
14
+ raise ArgumentError unless num.is_a?(Numeric)
15
+ @num = num.to_i
16
+ end
17
+
18
+ # To get translation use #in_english method from ::Translate
19
+
20
+ end
21
+
@@ -0,0 +1,3 @@
1
+ ones: [zero, one, two, three, four, five, six, seven, eight, nine]
2
+ tenss: [ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen]
3
+ tens: [zero, ten, twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety]
@@ -0,0 +1,20 @@
1
+ # Requires a class with num attribute(which is Numeric) and it's reader
2
+
3
+ module Compute
4
+ OPERATIONS = [:+, :-, :*, :/]
5
+
6
+ def method_missing(method, arg)
7
+ if OPERATIONS.include?(method)
8
+ self.class.new(num.send(method, arg.num))
9
+ end
10
+ end
11
+
12
+ def num_mod
13
+ num_abs.modulo(10)
14
+ end
15
+
16
+ def num_abs
17
+ num.abs
18
+ end
19
+
20
+ end
@@ -0,0 +1,28 @@
1
+ module Translate
2
+
3
+ def in_english
4
+ # Limit of digits - ready for further extensions
5
+ return nil if digits_count > 2
6
+
7
+ num < 0 ? "minus-#{in_words}" : in_words
8
+ end
9
+
10
+ private
11
+
12
+ def numbers_in_words
13
+ return YAML.load_file('./lib/english_numbers.yml')
14
+ end
15
+
16
+ def in_words
17
+ return single_digits(num_abs) unless digits_count > 1
18
+ "#{single_digits(digits_count).capitalize}Digits".constantize.send(:run, num)
19
+ end
20
+
21
+ def digits_count
22
+ num.to_s.delete('-').split(//).count
23
+ end
24
+
25
+ def single_digits(number)
26
+ numbers_in_words['ones'][number]
27
+ end
28
+ end
@@ -0,0 +1,76 @@
1
+ require './lib/english_number.rb'
2
+
3
+ RSpec.describe EnglishNumber do
4
+ subject(:eng_num) { described_class }
5
+
6
+ # Integration tests
7
+ it 'includes Compute module' do
8
+ expect(eng_num.included_modules).to include(Compute)
9
+ end
10
+
11
+ describe '::Translate module' do
12
+
13
+ it 'translates one digit numbers to English words' do
14
+ expect(eng_num.new(6).in_english).to eq('six')
15
+ end
16
+
17
+ it 'translates two digit numbers < 20 to English words' do
18
+ expect(eng_num.new(11).in_english).to eq('eleven')
19
+ end
20
+
21
+ it 'translates two digit numbers >= 20 to English words' do
22
+ expect(eng_num.new(22).in_english).to eq('twenty-two')
23
+ end
24
+
25
+ it 'translates float numbers to English words rounded down' do
26
+ expect(eng_num.new(24.5).in_english).to eq('twenty-four')
27
+ end
28
+
29
+ it 'doesn\'t translate numbers greater than 99' do
30
+ expect(eng_num.new(99).in_english).to eq('ninety-nine')
31
+ expect(eng_num.new(100).in_english).to eq(nil)
32
+ end
33
+
34
+ it 'translates negative one digit numbers' do
35
+ expect(eng_num.new(-7).in_english).to eq('minus-seven')
36
+ end
37
+
38
+ it 'translates negative two digit numbers < 20' do
39
+ expect(eng_num.new(-15).in_english).to eq('minus-fifteen')
40
+ end
41
+
42
+ it 'translates negative two digit numbers >= 20' do
43
+ expect(eng_num.new(-43).in_english).to eq('minus-forty-three')
44
+ end
45
+
46
+ it 'doesn\'t translate numbers lower than -99' do
47
+ expect(eng_num.new(-99).in_english).to eq('minus-ninety-nine')
48
+ expect(eng_num.new(-100).in_english).to eq(nil)
49
+ end
50
+
51
+ end
52
+
53
+ it 'includes Translate module' do
54
+ expect(eng_num.included_modules).to include(Translate)
55
+ end
56
+
57
+ describe '::Compute module' do
58
+
59
+ it 'adds numbers and returns new object' do
60
+ expect((eng_num.new(12) + eng_num.new(86)).in_english).to eq('ninety-eight')
61
+ end
62
+
63
+ it 'subtracts numbers and returns new object' do
64
+ expect((eng_num.new(10) - eng_num.new(17)).in_english).to eq('minus-seven')
65
+ end
66
+
67
+ it 'multiplies numbers and returns new object' do
68
+ expect((eng_num.new(2) * eng_num.new(2)).in_english).to eq('four')
69
+ end
70
+
71
+ it 'divides numbers and returns new object' do
72
+ expect((eng_num.new(55) / eng_num.new(2)).in_english).to eq('twenty-seven')
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,99 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
7
+ # this file to always be loaded, without a need to explicitly require it in any
8
+ # files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need
16
+ # it.
17
+ #
18
+ # The `.rspec` file also contains a few flags that are not defaults but that
19
+ # users commonly want.
20
+ #
21
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
22
+ RSpec.configure do |config|
23
+ # rspec-expectations config goes here. You can use an alternate
24
+ # assertion/expectation library such as wrong or the stdlib/minitest
25
+ # assertions if you prefer.
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ # rspec-mocks config goes here. You can use an alternate test double
38
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
39
+ config.mock_with :rspec do |mocks|
40
+ # Prevents you from mocking or stubbing a method that does not exist on
41
+ # a real object. This is generally recommended, and will default to
42
+ # `true` in RSpec 4.
43
+ mocks.verify_partial_doubles = true
44
+ end
45
+
46
+ # The settings below are suggested to provide a good initial experience
47
+ # with RSpec, but feel free to customize to your heart's content.
48
+
49
+ # These two settings work together to allow you to limit a spec run
50
+ # to individual examples or groups you care about by tagging them with
51
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
52
+ # get run.
53
+ config.filter_run :focus
54
+ config.run_all_when_everything_filtered = true
55
+
56
+ # Allows RSpec to persist some state between runs in order to support
57
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
58
+ # you configure your source control system to ignore this file.
59
+ # config.example_status_persistence_file_path = "spec/examples.txt"
60
+
61
+ # Limits the available syntax to the non-monkey patched syntax that is
62
+ # recommended. For more details, see:
63
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
64
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
65
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
66
+ config.disable_monkey_patching!
67
+
68
+ # This setting enables warnings. It's recommended, but in some cases may
69
+ # be too noisy due to issues in dependencies.
70
+ config.warnings = true
71
+
72
+ # Many RSpec users commonly either run the entire suite or an individual
73
+ # file, and it's useful to allow more verbose output when running an
74
+ # individual spec file.
75
+ if config.files_to_run.one?
76
+ # Use the documentation formatter for detailed output,
77
+ # unless a formatter has already been configured
78
+ # (e.g. via a command-line flag).
79
+ config.default_formatter = 'doc'
80
+ end
81
+
82
+ # Print the 10 slowest examples and example groups at the
83
+ # end of the spec run, to help surface which specs are running
84
+ # particularly slow.
85
+ # config.profile_examples = 10
86
+
87
+ # Run specs in random order to surface order dependencies. If you find an
88
+ # order dependency and want to debug it, you can fix the order by providing
89
+ # the seed, which is printed after each run.
90
+ # --seed 1234
91
+ config.order = :random
92
+
93
+ # Seed global randomization in this process using the `--seed` CLI option.
94
+ # Setting this allows you to use `--seed` to deterministically reproduce
95
+ # test failures related to randomization by passing the same `--seed` value
96
+ # as the one that triggered the failure.
97
+ Kernel.srand config.seed
98
+
99
+ end
@@ -0,0 +1,76 @@
1
+ require './lib/modules/compute.rb'
2
+
3
+ RSpec.describe 'Compute module' do
4
+ let(:dummy_class) { Class.new {
5
+ include Compute
6
+ attr_reader :num
7
+ def initialize(num)
8
+ @num = num
9
+ end } }
10
+
11
+ context 'having two objects with num attributes' do
12
+ let(:first_arg) { dummy_class.new(25) }
13
+ let(:second_arg) { dummy_class.new(5) }
14
+
15
+ context 'adding two objects with +' do
16
+
17
+ it 'returns new object' do
18
+ expect(first_arg.send(:+,second_arg)).to be_a(dummy_class)
19
+ end
20
+
21
+ it 'stores sum in new object\'s num attribute' do
22
+ expect((first_arg.send(:+,second_arg)).num).to eq(30)
23
+ end
24
+
25
+ end
26
+
27
+ context 'subtracting two objects with -' do
28
+
29
+ it 'returns new object' do
30
+ expect(first_arg.send(:-,second_arg)).to be_a(dummy_class)
31
+ end
32
+
33
+ it 'stores difference in new object\'s num attribute' do
34
+ expect((first_arg.send(:-,second_arg)).num).to eq(20)
35
+ end
36
+
37
+ end
38
+
39
+ context 'multiplying two objects with *' do
40
+
41
+ it 'returns new object' do
42
+ expect(first_arg.send(:*,second_arg)).to be_a(dummy_class)
43
+ end
44
+
45
+ it 'stores product in new object\'s num attribute' do
46
+ expect((first_arg.send(:*,second_arg)).num).to eq(125)
47
+ end
48
+
49
+ end
50
+
51
+ context 'dividing two objects with /' do
52
+
53
+ it 'returns new object' do
54
+ expect(first_arg.send(:/,second_arg)).to be_a(dummy_class)
55
+ end
56
+
57
+ it 'stores quotien in new object\'s num attribute' do
58
+ expect((first_arg.send(:/,second_arg)).num).to eq(5)
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'having any object with num attribute' do
64
+ let(:object) { dummy_class.new(-68) }
65
+
66
+ it '#num_abs returns absolute from the num attribute' do
67
+ expect(object.num_abs).to eq(68)
68
+ end
69
+
70
+ it '#num_mod returns modulo from dividing num attribute absolute by 10' do
71
+ expect(object.num_mod).to eq(8)
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,62 @@
1
+ require './lib/english_number.rb'
2
+
3
+ RSpec.describe EnglishNumber do
4
+ subject(:eng_num) { described_class }
5
+
6
+ context 'has one instance variable' do
7
+
8
+ it 'throws error for no arguments given' do
9
+ expect { eng_num.new }.to raise_error(ArgumentError)
10
+ end
11
+
12
+ it 'runs with one number argument given' do
13
+ expect { eng_num.new(6) }.not_to raise_error
14
+ end
15
+
16
+ it 'throws error for two arguments given' do
17
+ expect { eng_num.new(2,4) }.to raise_error(ArgumentError)
18
+ end
19
+
20
+ end
21
+
22
+ context 'accepts only numeric arguments' do
23
+
24
+ it 'throws error for string argument' do
25
+ expect { eng_num.new('') }.to raise_error(ArgumentError)
26
+ end
27
+
28
+ it 'throws error for array argument' do
29
+ expect { eng_num.new(Array.new) }.to raise_error(ArgumentError)
30
+ end
31
+
32
+ it 'accepts float argument' do
33
+ expect { eng_num.new(4.5) }.not_to raise_error
34
+ end
35
+
36
+ it 'accepts integer argument' do
37
+ expect { eng_num.new(56) }.not_to raise_error
38
+ end
39
+
40
+ it 'handles integer argument greater than gem\'s limit' do
41
+ expect { eng_num.new(523123) }.not_to raise_error
42
+ end
43
+
44
+ end
45
+
46
+ context 'allows to read the number instance variable' do
47
+
48
+ it 'doesn\'t throw error when the number is read' do
49
+ expect { eng_num.new(43).num }.not_to raise_error
50
+ end
51
+
52
+ it 'reads the right number' do
53
+ expect(eng_num.new(33).num).to eq(33)
54
+ end
55
+
56
+ end
57
+
58
+ it 'transforms floating numbers to integers' do
59
+ expect(eng_num.new(78.543).num).to eq(78)
60
+ end
61
+
62
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: english_number
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Brych
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.6
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.6
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.4.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.11.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.11.2
55
+ description: "Example: EnglishNumber.new(63).in_english # => 'sixty-three'. \n EnglishNumber
56
+ objects can be added, subtracted, multiplied, divided."
57
+ email: pbrych@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - Gemfile
65
+ - english_number.gemspec
66
+ - lib/digits/two_digits.rb
67
+ - lib/english_number.rb
68
+ - lib/english_numbers.yml
69
+ - lib/modules/compute.rb
70
+ - lib/modules/translate.rb
71
+ - spec/integrations/english_number_int_spec.rb
72
+ - spec/spec_helper.rb
73
+ - spec/unit_tests/compute_spec.rb
74
+ - spec/unit_tests/english_number_unit_spec.rb
75
+ homepage: http://rubygems.org/gems/english-number.rb
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.5.1
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Converting English numbers to strings
99
+ test_files: []