money_extensions 0.0.2 → 1.2.0

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
- SHA1:
3
- metadata.gz: f56893765e2c83d2ffea6e7e80ca2cab0963370c
4
- data.tar.gz: 799f31640b6dc664c300e7ca4a01b3275e378cfb
2
+ SHA256:
3
+ metadata.gz: e3f8f70cfcaef8f46dcb30b9f80f2116b0d45210d043fa21c4e7fbbb8c3a4915
4
+ data.tar.gz: 949f3cee9063fc0a604087d06925739a8beacf6482cae52e3cb2f6ae3fb7126a
5
5
  SHA512:
6
- metadata.gz: a4144e85e7838f52c2cc39adb3e845cc4cbc48fa6c88c2e1836caf861e7592f65712b734e8b1c8306187b9a1040dfa0e7cc2e281c5344694e1b6cbac54c461a4
7
- data.tar.gz: c1d03bfdecca1db109625f7bd4f2ace3839f68ea389dfaf1460e48a01bd34802d37e172eb5dbe3404c5fe6ce7540dde68c50cc357bc998af567705660734117a
6
+ metadata.gz: fc5c87edadd0d2b03e45810f399037ea32b86f1d9aac412c7a79022b2202846e7b6a8f4be352d5c3705562b225123dbff71eb33c4aac3bb88fe1cc649d6f9300
7
+ data.tar.gz: c8caeb5dd952872c50805478ca22e04a8cd0caf63b934896133d30ea0d569e23e2f186bf9ce3726a04d8ed518ed0ea866a8ae99b8971969f09b25d92318b1f40
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "bundler"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "daily"
@@ -0,0 +1,59 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ name: Build
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ bundler-cache: true
18
+ - run: bundle exec rake
19
+
20
+ release:
21
+ needs: build
22
+ name: Release
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - name: Checkout
26
+ uses: actions/checkout@v2
27
+
28
+ - name: Generate Changelog
29
+ run: |
30
+ # Get version from github ref (remove 'refs/tags/' and prefix 'v')
31
+ version="${GITHUB_REF#refs/tags/v}"
32
+ npx changelog-parser CHANGELOG.md | jq -cr ".versions | .[] | select(.version == \"$version\") | .body" > ${{ github.workflow }}-CHANGELOG.txt
33
+
34
+ - name: Release
35
+ uses: softprops/action-gh-release@v1
36
+ with:
37
+ body_path: ${{ github.workflow }}-CHANGELOG.txt
38
+ env:
39
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ publish:
42
+ needs: [build, release]
43
+ name: Publish
44
+ runs-on: ubuntu-latest
45
+
46
+ steps:
47
+ - uses: actions/checkout@v2
48
+ - uses: ruby/setup-ruby@v1
49
+
50
+ - name: Publish to RubyGems
51
+ run: |
52
+ mkdir -p $HOME/.gem
53
+ touch $HOME/.gem/credentials
54
+ chmod 0600 $HOME/.gem/credentials
55
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
56
+ gem build *.gemspec
57
+ gem push *.gem
58
+ env:
59
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,24 @@
1
+ name: Build and Test
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ fail-fast: false
7
+ matrix:
8
+ gemfile: [rails60, rails61, rails70]
9
+ ruby: ["2.7", "3.0", "3.1"]
10
+ runs-on: ubuntu-latest
11
+ env:
12
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+ - run: bundle exec rake
20
+ - name: Coveralls
21
+ uses: coverallsapp/github-action@master
22
+ with:
23
+ github-token: ${{ secrets.GITHUB_TOKEN }}
24
+ path-to-lcov: coverage/lcov.info
data/.gitignore CHANGED
@@ -2,3 +2,5 @@ pkg
2
2
  coverage
3
3
  Gemfile.lock
4
4
  tmp
5
+ vendor
6
+ .bundle
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## 1.2.0
4
+
5
+ - [PLAT-183] Build with Ruby 3.1 / Rails 7 and publish coverage with github action
6
+
7
+ ## 1.1.0
8
+
9
+ - [TT-8625] Update to build with github actions / ruby 3.0 / rails 6.1
10
+
11
+ ## 1.0.0
12
+
13
+ * [TT-5845] Update to support money gems >= 6
14
+
15
+ ## 0.1.0
16
+
17
+ * Using Fixnum is deprecated
18
+ * Drop rails 2 and old ruby support
19
+ * Use coverage kit to enforce maximum coverage
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
- Money Extensions
2
- ================
1
+ # Money Extensions
3
2
 
4
- [![Build Status](https://travis-ci.org/sealink/money_extensions.png?branch=master)](https://travis-ci.org/sealink/money_extensions)
3
+ [![Gem Version](https://badge.fury.io/rb/money_extensions.svg)](http://badge.fury.io/rb/money_extensions)
4
+ [![Build Status](https://github.com/sealink/money_extensions/workflows/Build%20and%20Test/badge.svg?branch=master)](https://github.com/sealink/money_extensions/actions)
5
5
  [![Coverage Status](https://coveralls.io/repos/sealink/money_extensions/badge.png)](https://coveralls.io/r/sealink/money_extensions)
6
- [![Dependency Status](https://gemnasium.com/sealink/money_extensions.png?travis)](https://gemnasium.com/sealink/money_extensions)
7
6
  [![Code Climate](https://codeclimate.com/github/sealink/money_extensions.png)](https://codeclimate.com/github/sealink/money_extensions)
8
7
 
9
8
  # DESCRIPTION
@@ -11,7 +10,10 @@ Money Extensions
11
10
  Extends the money classes with helpful functions and currency functions
12
11
 
13
12
  e.g. in model
13
+
14
+ ```ruby
14
15
  money_fields :total, :discount
16
+ ```
15
17
 
16
18
  This will by default map a money object "total" to a database column total_in_cents and the same for discount.
17
19
 
@@ -24,3 +26,14 @@ See spec directory for examples.
24
26
  Add to your Gemfile:
25
27
  gem 'money_extensions'
26
28
 
29
+ # RELEASE
30
+
31
+ To publish a new version of this gem the following steps must be taken.
32
+
33
+ - Update the version in the following files
34
+ ```
35
+ CHANGELOG.md
36
+ lib/quick_travel/version.rb
37
+ ```
38
+ - Create a tag using the format v0.1.0
39
+ - Follow build progress in GitHub actions
@@ -1,8 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec :path => '../'
3
3
 
4
- gem 'money', '< 5.1', :platform => :ruby_18
5
-
6
4
  group :development, :test do
7
- gem 'activerecord', '~> 4.0'
5
+ gem 'activerecord', '~> 6.0'
6
+ gem 'activesupport', '~> 6.0'
8
7
  end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activerecord', '~> 6.1'
6
+ gem 'activesupport', '~> 6.1'
7
+ end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activerecord', '~> 7.0'
6
+ gem 'activesupport', '~> 7.0'
7
+ end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Extensions
3
-
4
5
  def self.included(base)
5
6
  base.extend(ClassMethods)
6
7
  end
@@ -18,20 +19,14 @@ module ActiveRecord
18
19
 
19
20
  field_name = "#{attr_name}_iso_code"
20
21
 
21
- composed_of attr_name, :class_name => "Money::Currency",
22
- :mapping => [field_name, 'iso_code'],
23
- :allow_nil => true,
24
- :constructor => Proc.new{|value| Money::Currency.new(value) unless value.blank?}
22
+ composed_of attr_name, class_name: 'Money::Currency',
23
+ mapping: [field_name, 'iso_code'],
24
+ allow_nil: true,
25
+ constructor: proc { |value| Money::Currency.new(value) unless value.blank? }
25
26
 
26
- if Rails.version > '3'
27
- scope :for_currency, lambda{ |currency|
28
- where(:currency_iso_code => currency.iso_code)
27
+ scope :for_currency, lambda { |currency|
28
+ where(currency_iso_code: currency.iso_code)
29
29
  }
30
- else
31
- named_scope :for_currency, lambda{ |currency|
32
- {:conditions => {:currency_iso_code => currency.iso_code}}
33
- }
34
- end
35
30
 
36
31
  if options[:default]
37
32
  before_validation :set_default_currency
@@ -43,13 +38,9 @@ module ActiveRecord
43
38
  METHOD
44
39
  end
45
40
 
46
- if options[:required]
47
- validates_presence_of :currency_iso_code
48
- end
41
+ validates_presence_of :currency_iso_code if options[:required]
49
42
  end
50
-
51
43
  end
52
-
53
44
  end
54
45
  end
55
46
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Returns sum as a money - and returns 0 for empty arrays
3
5
  def total_money
4
6
  empty? ? ::Money.new(0) : inject(:+)
5
7
  end
6
- end
8
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/output_safety'
4
+
5
+ module HtmlFormat
6
+ def format(**rules)
7
+ html_wrap = rules.delete(:html_wrap)
8
+ return html_wrap(super(**rules)) if html_wrap
9
+
10
+ super(**rules)
11
+ end
12
+
13
+ def as_html(**rules)
14
+ rules[:html_wrap] = true
15
+ format(**rules).html_safe
16
+ end
17
+
18
+ private
19
+
20
+ def html_wrap(str)
21
+ "<span class=\"money #{direction_class}\">#{str}</span>"
22
+ end
23
+
24
+ def direction_class
25
+ if cents > 0
26
+ 'positive'
27
+ elsif cents < 0
28
+ 'negative'
29
+ else
30
+ 'zero'
31
+ end
32
+ end
33
+ end
34
+
35
+ class Money
36
+ prepend HtmlFormat
37
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Integer
4
+ # Returns self as a money (treated as cents)
5
+ def total_money
6
+ zero? ? ::Money.new(0) : ::Money.new(self)
7
+ end
8
+ end
@@ -1,5 +1,6 @@
1
- module MoneyField
1
+ # frozen_string_literal: true
2
2
 
3
+ module MoneyField
3
4
  def self.included(base)
4
5
  base.extend(ClassMethods)
5
6
  end
@@ -23,12 +24,10 @@ module MoneyField
23
24
  METHOD
24
25
  end
25
26
 
26
-
27
27
  def money_fields(*attributes)
28
- attributes.each {|a| self.money_field(a)}
28
+ attributes.each { |a| money_field(a) }
29
29
  end
30
30
 
31
-
32
31
  def money(*fields)
33
32
  fields.each do |field|
34
33
  class_eval <<-METHOD
@@ -38,7 +37,5 @@ module MoneyField
38
37
  METHOD
39
38
  end
40
39
  end
41
-
42
40
  end
43
-
44
- end
41
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric
2
4
  # Converts this numeric to a Money object in the default currency. It
3
5
  # multiplies the numeric value by 100 and treats that as cents.
@@ -11,6 +13,6 @@ class Numeric
11
13
  # require 'bigdecimal'
12
14
  # BigDecimal.new('100').to_money => #<Money @cents=10000>
13
15
  def to_money(currency = nil)
14
- ::Money.new((self * 100).round, currency)
16
+ ::Money.new((self * 100).round, currency || Money.default_currency)
15
17
  end
16
- end
18
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitBetween
4
+ # Override division -- should not do it, but use split_between
5
+ def /(*_params)
6
+ raise "Division of money NOT allowed - use 'split_between' to avoid rounding errors"
7
+ end
8
+
9
+ # Split the money between the specified number - and return an array of money
10
+ # Remainder in splits are given to the highest value e.g.
11
+ # $2.00 splits [40, 81, 40] into [49, 102, 49]
12
+ # $1.01 splits [ 1, 1, 1] into [35, 33, 33]
13
+ def split_between(params)
14
+ # if just a number is passed in, then money is split equally
15
+ if params.is_a?(Integer)
16
+ divisor = params
17
+ raise ArgumentError, 'Can only split up over a positive number' if divisor < 1
18
+
19
+ rounded_split = lossy_divide(divisor)
20
+ results = Array.new(divisor, rounded_split) # Create with 'divisor' num elements
21
+
22
+ # if an array of monies is passed in, then split in proportions
23
+ elsif params.is_a?(Array)
24
+
25
+ raise ArgumentError, 'Can only split up over at least one ration' if params.empty? && !zero?
26
+
27
+ results = params.map { |p| p.is_a?(::Money) ? p.cents : p }
28
+
29
+ total = results.inject(:+)
30
+ if total.zero?
31
+ return Array.new(results.size, ::Money.new(0)) if zero?
32
+
33
+ raise ArgumentError, "Total of ratios should not be zero! You sent in: #{params.inspect}"
34
+ end
35
+
36
+ results.map! do |ratio|
37
+ ::Money.new((cents * (ratio.to_f / total)).round)
38
+ end
39
+ else
40
+ raise 'Either a Integer or array has to be passed in for splitting money'
41
+ end
42
+
43
+ # Distribute rounding to max absolute to avoid a $0 amount getting the rounding
44
+ biggest_value_index = results.index(results.max_by(&:abs))
45
+ results[biggest_value_index] += self - results.total_money
46
+
47
+ results
48
+ end
49
+ end
50
+
51
+ class Money
52
+ alias lossy_divide /
53
+ include SplitBetween
54
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Converts this string to a float and then to a Money object in the default currency.
3
5
  # It multiplies the converted numeric value by 100 and treats that as cents.
@@ -9,6 +11,6 @@ class String
9
11
  # '100'.to_money => #<Money @cents=10000>
10
12
  # '100.37'.to_money => #<Money @cents=10037>
11
13
  def to_money(currency = nil)
12
- Money.new((self.to_f * 100).round, currency)
14
+ Money.new((to_f * 100).round, currency)
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MoneyExtensions
2
- VERSION = '0.0.2'
4
+ VERSION = '1.2.0'
3
5
  end
@@ -1,9 +1,9 @@
1
1
  module MoneyExtensions
2
2
  require 'money'
3
3
  require 'money_extensions/array'
4
- require 'money_extensions/big_decimal'
5
- require 'money_extensions/fixnum'
6
- require 'money_extensions/extensions'
4
+ require 'money_extensions/integer'
5
+ require 'money_extensions/split_between'
6
+ require 'money_extensions/html_format'
7
7
  require 'money_extensions/money_field'
8
8
  require 'money_extensions/numeric'
9
9
  require 'money_extensions/string'
@@ -14,4 +14,3 @@ module MoneyExtensions
14
14
  end
15
15
 
16
16
  end
17
-
@@ -19,13 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency 'money', '>= 3.0.0', '< 6.0.0'
22
+ spec.add_dependency 'money', '>= 6.0.0'
23
+ spec.add_dependency 'activesupport', '>= 6'
24
+
23
25
  spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'rubocop'
24
27
  spec.add_development_dependency 'rspec'
25
- spec.add_development_dependency 'simplecov'
26
- spec.add_development_dependency 'simplecov-rcov'
27
- spec.add_development_dependency 'coveralls'
28
+ spec.add_development_dependency 'coverage-kit'
28
29
  spec.add_development_dependency 'sqlite3'
29
30
  spec.add_development_dependency 'activerecord'
30
- spec.add_development_dependency 'travis'
31
+ spec.add_development_dependency 'pry-byebug'
31
32
  end
@@ -3,15 +3,15 @@ require 'spec_helper'
3
3
  describe BigDecimal do
4
4
 
5
5
  it "should allow verifying if it's a positive value" do
6
- expect(BigDecimal.new('-1')).to_not be_positive
7
- expect(BigDecimal.new('0')).to_not be_positive
8
- expect(BigDecimal.new('1')).to be_positive
6
+ expect(BigDecimal('-1')).to_not be_positive
7
+ expect(BigDecimal('0')).to_not be_positive
8
+ expect(BigDecimal('1')).to be_positive
9
9
  end
10
10
 
11
11
  it "should allow verifying if it's a negative value" do
12
- expect(BigDecimal.new('-1')).to be_negative
13
- expect(BigDecimal.new('0')).to_not be_negative
14
- expect(BigDecimal.new('1')).to_not be_negative
12
+ expect(BigDecimal('-1')).to be_negative
13
+ expect(BigDecimal('0')).to_not be_negative
14
+ expect(BigDecimal('1')).to_not be_negative
15
15
  end
16
16
 
17
17
  end
@@ -0,0 +1,48 @@
1
+ require 'money'
2
+ require 'money_extensions/string'
3
+ require 'money_extensions/html_format'
4
+
5
+ RSpec.describe Money do
6
+ before { Money.locale_backend = nil }
7
+ after { Money.locale_backend = :legacy }
8
+
9
+ let(:money_positive) { Money.new(100) }
10
+ let(:money_negative) { Money.new(-100) }
11
+ let(:money_zero) { Money.new(0) }
12
+
13
+ subject { money_positive.format(*rules) }
14
+
15
+ it "should format the output correctly" do
16
+ expect(money_negative.format(html_wrap: true, sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
17
+ expect(money_positive.format(html_wrap: true)).to eq "<span class=\"money positive\">$1.00</span>"
18
+ expect(money_zero.format(html_wrap: true)).to eq "<span class=\"money zero\">$0.00</span>"
19
+
20
+ expect(money_positive.format(html_wrap: true)).to eq "<span class=\"money positive\">$1.00</span>"
21
+ expect(money_negative.format(html_wrap: true, sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
22
+ expect(money_zero.format(html_wrap: true)).to eq "<span class=\"money zero\">$0.00</span>"
23
+
24
+ expect(money_positive.format(signed: true, sign_positive: true, sign_before_symbol: true)).to eq "+$1.00"
25
+ expect(money_negative.format(signed: true, sign_before_symbol: true)).to eq "-$1.00"
26
+ expect(money_zero.format(signed: true)).to eq "$0.00"
27
+
28
+ expect(money_positive.format(separator: '~')).to eq "$1~00"
29
+ end
30
+
31
+ it 'should work with as_html' do
32
+ expect(money_negative.as_html(sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
33
+ expect(money_positive.as_html).to eq "<span class=\"money positive\">$1.00</span>"
34
+ expect(money_zero.as_html).to eq "<span class=\"money zero\">$0.00</span>"
35
+
36
+ expect(money_positive.as_html).to eq "<span class=\"money positive\">$1.00</span>"
37
+ expect(money_negative.as_html(sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
38
+ expect(money_zero.as_html).to eq "<span class=\"money zero\">$0.00</span>"
39
+ end
40
+
41
+ it 'should format cents where appropriate' do
42
+ expect('1.50'.to_money.format(no_cents: true)).to eq '$1'
43
+ expect('1.00'.to_money.format(no_cents: true)).to eq '$1'
44
+
45
+ expect('1.50'.to_money.format(no_cents_if_whole: true)).to eq '$1.50'
46
+ expect('1.00'.to_money.format(no_cents_if_whole: true)).to eq '$1'
47
+ end
48
+ end
data/spec/money_spec.rb CHANGED
@@ -1,23 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Money do
4
- it "should get correct direction class" do
5
- expect(Money.new(-1).direction_class).to eq 'negative'
6
- expect(Money.new(0).direction_class).to eq 'zero'
7
- expect(Money.new(1).direction_class).to eq 'positive'
8
- end
9
-
10
- it "should round correctly" do
11
- money = Money.new(511)
12
- expect(money.round.cents).to eq 500
13
- expect(money.round(10).cents).to eq 510
14
- expect(money.round(1).cents).to eq 511
15
-
16
- expect(money.round(100, 'up').cents).to eq 600
17
- expect(money.round(100, 'down').cents).to eq 500
18
- expect(money.round(100, 'nearest').cents).to eq 500
19
- end
20
-
21
4
  it "should deny division of money (to prevent rounding errors)" do
22
5
  expect { Money.new(50)/10 }.to raise_error(RuntimeError)
23
6
  end
@@ -38,7 +21,7 @@ describe Money do
38
21
  expect(money.split_between([1,2])).to eq [33,67].map{ |i| Money.new(i)}
39
22
 
40
23
  money_negative = Money.new(-100)
41
- expect(money_negative.split_between(3)).to eq [-32,-34,-34].map{ |i| Money.new(i)}
24
+ expect(money_negative.split_between(3)).to eq [-34,-33,-33].map{ |i| Money.new(i)}
42
25
  expect(money_negative.split_between([1,2,2,5])).to eq [-10,-20,-20,-50].map{ |i| Money.new(i)}
43
26
  expect(money_negative.split_between([1,2])).to eq [-33,-67].map{ |i| Money.new(i)}
44
27
 
@@ -60,14 +43,14 @@ describe Money do
60
43
 
61
44
  it "should return a nice, Big Decimal if so converted" do
62
45
  money = Money.new(1428)
63
- bigdecimal = BigDecimal.new("14.28")
46
+ bigdecimal = BigDecimal("14.28")
64
47
  expect(money.to_d).to eq bigdecimal
65
48
  end
66
49
 
67
50
  it "should be createable from strings and numbers" do
68
51
  money = Money.new(100)
69
52
  expect("1".to_money.cents).to eq money.cents
70
- expect(BigDecimal.new('1').to_money.cents).to eq money.cents
53
+ expect(BigDecimal('1').to_money.cents).to eq money.cents
71
54
  expect(100.total_money.cents).to eq money.cents
72
55
  end
73
56
 
@@ -89,29 +72,4 @@ describe Money do
89
72
  expect(money_negative.abs).to eq money_positive
90
73
  expect(money_zero.abs).to eq money_zero
91
74
  end
92
-
93
- it "should format the output correctly" do
94
- expect(money_positive.format).to eq "<span class=\"money positive\">$1.00</span>"
95
- expect(money_negative.format).to eq "<span class=\"money negative\">-$1.00</span>"
96
- expect(money_zero.format).to eq "<span class=\"money zero\">$0.00</span>"
97
-
98
- expect(money_positive.format(:html)).to eq "<span class=\"money positive\">$1.00</span>"
99
- expect(money_negative.format(:html)).to eq "<span class=\"money negative\">-$1.00</span>"
100
- expect(money_zero.format(:html)).to eq "<span class=\"money zero\">$0.00</span>"
101
-
102
- expect(money_positive.format(:signed)).to eq "+$1.00"
103
- expect(money_negative.format(:signed)).to eq "-$1.00"
104
- expect(money_zero.format(:signed)).to eq "$0.00"
105
-
106
- expect("1.50".to_money.format(:separator => '~')).to eq "$1~50"
107
- end
108
-
109
- it 'should format cents where appropriate' do
110
- expect('1.50'.to_money.format(:no_cents)).to eq '$1'
111
- expect('1.00'.to_money.format(:no_cents)).to eq '$1'
112
-
113
- expect('1.50'.to_money.format(:hide_zero_cents)).to eq '$1.50'
114
- expect('1.00'.to_money.format(:hide_zero_cents)).to eq '$1'
115
- end
116
-
117
75
  end
@@ -1,26 +1,3 @@
1
- MINIMUM_COVERAGE = 80
1
+ require 'coverage/kit'
2
2
 
3
- unless ENV['COVERAGE'] == 'off'
4
- require 'simplecov'
5
- require 'simplecov-rcov'
6
- require 'coveralls'
7
- Coveralls.wear!
8
-
9
- SimpleCov.formatters = [
10
- SimpleCov::Formatter::RcovFormatter,
11
- Coveralls::SimpleCov::Formatter
12
- ]
13
- SimpleCov.start do
14
- add_filter '/vendor/'
15
- add_filter '/spec/'
16
- add_group 'lib', 'lib'
17
- end
18
- SimpleCov.at_exit do
19
- SimpleCov.result.format!
20
- percent = SimpleCov.result.covered_percent
21
- unless percent >= MINIMUM_COVERAGE
22
- puts "Coverage must be above #{MINIMUM_COVERAGE}%. It is #{"%.2f" % percent}%"
23
- Kernel.exit(1)
24
- end
25
- end
26
- end
3
+ Coverage::Kit.setup(minimum_coverage: 86.6)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Noack
@@ -9,16 +9,13 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-02-03 00:00:00.000000000 Z
12
+ date: 2022-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - ">="
19
- - !ruby/object:Gem::Version
20
- version: 3.0.0
21
- - - "<"
22
19
  - !ruby/object:Gem::Version
23
20
  version: 6.0.0
24
21
  type: :runtime
@@ -26,27 +23,24 @@ dependencies:
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
25
  - - ">="
29
- - !ruby/object:Gem::Version
30
- version: 3.0.0
31
- - - "<"
32
26
  - !ruby/object:Gem::Version
33
27
  version: 6.0.0
34
28
  - !ruby/object:Gem::Dependency
35
- name: rake
29
+ name: activesupport
36
30
  requirement: !ruby/object:Gem::Requirement
37
31
  requirements:
38
32
  - - ">="
39
33
  - !ruby/object:Gem::Version
40
- version: '0'
41
- type: :development
34
+ version: '6'
35
+ type: :runtime
42
36
  prerelease: false
43
37
  version_requirements: !ruby/object:Gem::Requirement
44
38
  requirements:
45
39
  - - ">="
46
40
  - !ruby/object:Gem::Version
47
- version: '0'
41
+ version: '6'
48
42
  - !ruby/object:Gem::Dependency
49
- name: rspec
43
+ name: rake
50
44
  requirement: !ruby/object:Gem::Requirement
51
45
  requirements:
52
46
  - - ">="
@@ -60,7 +54,7 @@ dependencies:
60
54
  - !ruby/object:Gem::Version
61
55
  version: '0'
62
56
  - !ruby/object:Gem::Dependency
63
- name: simplecov
57
+ name: rubocop
64
58
  requirement: !ruby/object:Gem::Requirement
65
59
  requirements:
66
60
  - - ">="
@@ -74,7 +68,7 @@ dependencies:
74
68
  - !ruby/object:Gem::Version
75
69
  version: '0'
76
70
  - !ruby/object:Gem::Dependency
77
- name: simplecov-rcov
71
+ name: rspec
78
72
  requirement: !ruby/object:Gem::Requirement
79
73
  requirements:
80
74
  - - ">="
@@ -88,7 +82,7 @@ dependencies:
88
82
  - !ruby/object:Gem::Version
89
83
  version: '0'
90
84
  - !ruby/object:Gem::Dependency
91
- name: coveralls
85
+ name: coverage-kit
92
86
  requirement: !ruby/object:Gem::Requirement
93
87
  requirements:
94
88
  - - ">="
@@ -130,7 +124,7 @@ dependencies:
130
124
  - !ruby/object:Gem::Version
131
125
  version: '0'
132
126
  - !ruby/object:Gem::Dependency
133
- name: travis
127
+ name: pry-byebug
134
128
  requirement: !ruby/object:Gem::Requirement
135
129
  requirements:
136
130
  - - ">="
@@ -149,29 +143,34 @@ executables: []
149
143
  extensions: []
150
144
  extra_rdoc_files: []
151
145
  files:
146
+ - ".github/dependabot.yml"
147
+ - ".github/workflows/release.yml"
148
+ - ".github/workflows/ruby.yml"
152
149
  - ".gitignore"
153
150
  - ".rspec"
154
- - ".travis.yml"
151
+ - ".ruby-version"
152
+ - CHANGELOG.md
155
153
  - Gemfile
156
154
  - LICENSE
157
155
  - README.md
158
156
  - Rakefile
159
- - gemfiles/rails2.gemfile
160
- - gemfiles/rails3.gemfile
161
- - gemfiles/rails4.gemfile
157
+ - gemfiles/rails60.gemfile
158
+ - gemfiles/rails61.gemfile
159
+ - gemfiles/rails70.gemfile
162
160
  - lib/money_extensions.rb
163
161
  - lib/money_extensions/active_record/extensions.rb
164
162
  - lib/money_extensions/array.rb
165
- - lib/money_extensions/big_decimal.rb
166
- - lib/money_extensions/extensions.rb
167
- - lib/money_extensions/fixnum.rb
163
+ - lib/money_extensions/html_format.rb
164
+ - lib/money_extensions/integer.rb
168
165
  - lib/money_extensions/money_field.rb
169
166
  - lib/money_extensions/numeric.rb
167
+ - lib/money_extensions/split_between.rb
170
168
  - lib/money_extensions/string.rb
171
169
  - lib/money_extensions/version.rb
172
170
  - money_extensions.gemspec
173
171
  - rails/init.rb
174
172
  - spec/big_decimal_spec.rb
173
+ - spec/html_format_spec.rb
175
174
  - spec/money_field_spec.rb
176
175
  - spec/money_spec.rb
177
176
  - spec/schema.rb
@@ -196,13 +195,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
195
  - !ruby/object:Gem::Version
197
196
  version: '0'
198
197
  requirements: []
199
- rubyforge_project:
200
- rubygems_version: 2.4.8
198
+ rubygems_version: 3.3.3
201
199
  signing_key:
202
200
  specification_version: 4
203
201
  summary: Set of extensions to the money gem used by TravelLink Technology.
204
202
  test_files:
205
203
  - spec/big_decimal_spec.rb
204
+ - spec/html_format_spec.rb
206
205
  - spec/money_field_spec.rb
207
206
  - spec/money_spec.rb
208
207
  - spec/schema.rb
data/.travis.yml DELETED
@@ -1,30 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9
4
- - 2.0
5
- - 2.1
6
- - 2.2
7
- gemfile:
8
- - gemfiles/rails2.gemfile
9
- - gemfiles/rails3.gemfile
10
- - gemfiles/rails4.gemfile
11
- matrix:
12
- exclude:
13
- - rvm: 1.9
14
- gemfile: gemfiles/rails4.gemfile
15
- - rvm: 1.9
16
- gemfile: gemfiles/rails2.gemfile
17
- - rvm: 2.0
18
- gemfile: gemfiles/rails2.gemfile
19
- - rvm: 2.1
20
- gemfile: gemfiles/rails2.gemfile
21
- - rvm: 2.2
22
- gemfile: gemfiles/rails2.gemfile
23
- script: "bundle exec rake spec"
24
- notifications:
25
- email:
26
- - support@travellink.com.au
27
- flowdock:
28
- secure: A0Fr9j0kvKPEWuPbJu/DPMYPvx98UI8k43adKN9UjTB6FRVAQM3kXmKJIL3A495scc2Civrg2KHDkbwNwVThY+HdLeU7q71Bm6obP6ZkCe43MIoc9NiVJymCNguku6+tLEyusdWIceFiBW7P5p/sU1QU66GFj1t4wNTpVq9A4Kw=
29
- sudo: false
30
- cache: bundler
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => "../"
3
-
4
- gem 'money', '< 5.1', :platform => :ruby_18
5
-
6
- group :development, :test do
7
- gem 'activerecord', '~> 2.3.0'
8
- end
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => "../"
3
-
4
- gem 'money', '< 5.1', :platform => :ruby_18
5
-
6
- group :development, :test do
7
- gem 'activerecord', '~> 3.2.0'
8
- end
@@ -1,12 +0,0 @@
1
- class BigDecimal
2
-
3
- def negative?
4
- self < BigDecimal.new('0')
5
- end
6
-
7
- def positive?
8
- self > BigDecimal.new('0')
9
- end
10
-
11
- end
12
-
@@ -1,189 +0,0 @@
1
- require 'money'
2
-
3
- module Extensions
4
-
5
- def self.included(base)
6
- base.class_eval do
7
- alias_method :to_s_without_currency_hack, :to_s
8
- alias_method :to_s, :to_s_with_currency_hack
9
- alias_method :to_d_without_currency_hack, :to_d
10
- alias_method :to_d, :to_d_with_currency_hack
11
- end
12
- end
13
-
14
- # Override division -- should not do it, but use split_between
15
- def /(*params)
16
- raise "Division of money NOT allowed - use 'split_between' to avoid rounding errors"
17
- end
18
-
19
- def to_d_with_currency_hack
20
- BigDecimal.new("#{cents/100.0}")
21
- end
22
-
23
- # Split the money between the specified number - and return an array of money
24
- # Remainder in splits are given to the highest value e.g.
25
- # $2.00 splits [40, 81, 40] into [49, 102, 49]
26
- # $1.01 splits [ 1, 1, 1] into [35, 33, 33]
27
- def split_between(params)
28
- #if just a number is passed in, then money is split equally
29
- if params.is_a?(Fixnum)
30
- divisor = params
31
- raise ArgumentError, "Can only split up over a positive number" if divisor < 1
32
-
33
- rounded_split = self.lossy_divide(divisor)
34
- results = Array.new(divisor, rounded_split) # Create with 'divisor' num elements
35
-
36
- #if an array of monies is passed in, then split in proportions
37
- elsif params.is_a?(Array)
38
-
39
- raise ArgumentError, "Can only split up over at least one ration" if params.empty? && !self.zero?
40
-
41
-
42
- results = params.map { |p| p.is_a?(::Money) ? p.cents : p }
43
-
44
- total = results.inject(:+)
45
- if total.zero?
46
- return Array.new(results.size, ::Money.new(0)) if self.zero?
47
- raise ArgumentError, "Total of ratios should not be zero! You sent in: #{params.inspect}"
48
- end
49
-
50
- results.map! do |ratio|
51
- ::Money.new((self.cents * (ratio.to_f / total)).round)
52
- end
53
- else
54
- raise "Either a fixnum or array has to be passed in for splitting money"
55
- end
56
-
57
- # Distribute rounding to max absolute to avoid a $0 amount getting the rounding
58
- biggest_value_index = results.index(results.max_by(&:abs))
59
- results[biggest_value_index] += self - results.total_money
60
-
61
- return results
62
- end
63
-
64
-
65
- DEFAULT_FORMAT_RULES = [:html]
66
- # HACK COZ WE ARE PRETENDING WE DON'T HAVE CURRENCY!!!
67
- #
68
- # TODO: Make this not a hack...
69
- def to_s_with_currency_hack
70
- sprintf("%.2f", cents.to_f / 100) #currency.subunit_to_unit)
71
- end
72
-
73
- def inspect
74
- inbuilt_inspect_style_id = '%x' % (object_id << 1)
75
- "\#<Money:0x#{inbuilt_inspect_style_id} $#{self}>"
76
- end
77
-
78
- # Money's default formatted is not flexible enought.
79
- # - we don't want it to say 'free' when 0 (not correct for 'discounts' and such)
80
- def format(*rules)
81
- rules = rules.empty? ? DEFAULT_FORMAT_RULES.dup : rules.flatten
82
-
83
- options = {}
84
- rules.each do |rule|
85
- if rule.is_a? Hash
86
- options = rule
87
- end
88
- end
89
-
90
- html_wrap = rules.include?(:html)
91
-
92
- options[:delimiter] ||= ','
93
- options[:separator] ||= '.'
94
-
95
- ''.tap do |formatted|
96
- formatted << "<span class=\"money #{direction_class}\">" if html_wrap
97
-
98
- rules << :signed if cents < 0
99
-
100
- if rules.include?(:signed)
101
- formatted << if cents > 0
102
- '+'
103
- elsif cents < 0
104
- '-'
105
- else
106
- ''
107
- end
108
- end
109
-
110
- no_cents = rules.include?(:no_cents) ||
111
- (rules.include?(:hide_zero_cents) && cents % 100 == 0)
112
- format_string = no_cents ? "$%d" : "$%.2f"
113
- amount = format_string % (cents.abs.to_f / 100)
114
- amount.gsub!('.', options[:separator])
115
- amount.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
116
- formatted << amount
117
-
118
- formatted << "</span>" if html_wrap
119
- end
120
- end
121
-
122
- def direction_class
123
- if cents > 0
124
- 'positive'
125
- elsif cents < 0
126
- 'negative'
127
- else
128
- 'zero'
129
- end
130
- end
131
-
132
- def mark_up(mark_up_definition)
133
- mark_up_cents = mark_up_definition.cents || 0
134
- rounding_direction = mark_up_definition.rounding_direction.try(:to_sym)
135
- multiplier = ((100 + mark_up_definition.percent)/100.0)
136
- (self * multiplier).round(mark_up_definition.rounding_cents, rounding_direction) + ::Money.new(mark_up_cents)
137
- end
138
-
139
- # money = Money.new(501)
140
- # money.round
141
- # => 500
142
- # money.round(10)
143
- # => 510
144
- # money.round(1)
145
- # => 511
146
-
147
- # money.round(100, 'up')
148
- # => 600
149
- # money.round(100, 'down')
150
- # => 500
151
- # money.round(100, 'nearest')
152
- # => 500
153
- def round(round_to_cents = 100, direction = :nearest)
154
- round_to_cents = 100 if round_to_cents.nil?
155
- case direction.to_sym
156
- when :nearest
157
- rounded_cents = (cents + round_to_cents/2) / round_to_cents * round_to_cents
158
- when :up
159
- rounded_cents = (cents + round_to_cents) / round_to_cents * round_to_cents
160
- when :down
161
- rounded_cents = (cents) / round_to_cents * round_to_cents
162
- else
163
- end
164
- ::Money.new(rounded_cents)
165
- end
166
-
167
- def abs
168
- if cents >= 0
169
- self.clone
170
- else
171
- ::Money.new(0 - cents)
172
- end
173
- end
174
-
175
- def positive?
176
- cents > 0
177
- end
178
-
179
- def negative?
180
- cents < 0
181
- end
182
-
183
- end
184
-
185
- ::Money.class_eval do
186
- alias_method :lossy_divide, :/
187
- end
188
-
189
- ::Money.send(:include, Extensions)
@@ -1,6 +0,0 @@
1
- class Fixnum
2
- #Returns self as a money (treated as cents)
3
- def total_money
4
- zero? ? ::Money.new(0) : ::Money.new(self)
5
- end
6
- end