bollettino 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CHANGELOG.md +6 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +77 -0
  9. data/Rakefile +6 -0
  10. data/assets/slip.png +0 -0
  11. data/bollettino.gemspec +28 -0
  12. data/example-slip.png +0 -0
  13. data/lib/bollettino/generator.rb +13 -0
  14. data/lib/bollettino/models/address.rb +7 -0
  15. data/lib/bollettino/models/payee.rb +6 -0
  16. data/lib/bollettino/models/payer.rb +6 -0
  17. data/lib/bollettino/models/payment_order.rb +9 -0
  18. data/lib/bollettino/models/slip.rb +7 -0
  19. data/lib/bollettino/renderer.rb +26 -0
  20. data/lib/bollettino/renderers/address_renderer.rb +24 -0
  21. data/lib/bollettino/renderers/payee_renderer.rb +26 -0
  22. data/lib/bollettino/renderers/payer_renderer.rb +20 -0
  23. data/lib/bollettino/renderers/payment_order_renderer.rb +37 -0
  24. data/lib/bollettino/renderers/slip_renderer.rb +21 -0
  25. data/lib/bollettino/version.rb +3 -0
  26. data/lib/bollettino.rb +23 -0
  27. data/spec/integration/generation_spec.rb +50 -0
  28. data/spec/spec_helper.rb +82 -0
  29. data/spec/unit/bollettino/generator_spec.rb +50 -0
  30. data/spec/unit/bollettino/models/address_spec.rb +12 -0
  31. data/spec/unit/bollettino/models/payee_spec.rb +10 -0
  32. data/spec/unit/bollettino/models/payer_spec.rb +12 -0
  33. data/spec/unit/bollettino/models/payment_order_spec.rb +11 -0
  34. data/spec/unit/bollettino/models/slip_spec.rb +15 -0
  35. data/spec/unit/bollettino/renderers/address_renderer_spec.rb +23 -0
  36. data/spec/unit/bollettino/renderers/payee_renderer_spec.rb +37 -0
  37. data/spec/unit/bollettino/renderers/payer_renderer_spec.rb +27 -0
  38. data/spec/unit/bollettino/renderers/payment_order_renderer_spec.rb +39 -0
  39. data/spec/unit/bollettino/renderers/slip_renderer_spec.rb +34 -0
  40. data/tmp/.keep +0 -0
  41. metadata +181 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fcb4a547cf48a198870007c60f5f9ce9053745d8
4
+ data.tar.gz: 460f4967b8cb0f276591dabe5056bc7a22fdd3ba
5
+ SHA512:
6
+ metadata.gz: 2cfdc508fae66d3757bf95ca6da9e6f93c8723ae4b143d0274d22ad3933266f6ae5a5f5f776fe50f4a0a89bea050e35467ddf4773ad615deba6f33b715070502
7
+ data.tar.gz: a47e95ddaddb0508e5f01a20b7a37e3a8c36eba9605b106b196ce6390148e2ccb76ae9b3910759b9b1ce0d0c1a4b3e97d18ecb0834eb4b3297cefec5a0d34cfb
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/*
10
+ !/tmp/.keep
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
16
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+ - 2.0.0
5
+ - 1.9.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ Changelog
2
+ =========
3
+
4
+ 0.1.0
5
+ -----
6
+ - First working version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bollettino.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alessandro Desantis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Bollettino
2
+
3
+ [![Build Status](https://travis-ci.org/interconn-isp/bollettino.svg?branch=master)](https://travis-ci.org/interconn-isp/bollettino)
4
+ [![Dependency Status](https://gemnasium.com/interconn-isp/bollettino.svg)](https://gemnasium.com/interconn-isp/bollettino)
5
+ [![Code Climate](https://codeclimate.com/github/interconn-isp/bollettino/badges/gpa.svg)](https://codeclimate.com/github/interconn-isp/bollettino)
6
+
7
+ Bollettino is a tool for generating Italian postal payment slips.
8
+
9
+ Don't know what a postal payment slip is? Then you probably don't need this
10
+ library. But here's an example anyway:
11
+
12
+ ![Postal payment slip](https://raw.githubusercontent.com/interconn-isp/bollettino/master/example-slip.png)
13
+
14
+ See all those blank spaces? Bollettino takes care of filling them. All you need
15
+ is the data.
16
+
17
+ Bollettino is the successor to [Postino](https://github.com/interconn-isp/postino),
18
+ which used the now abandoned [prawn-templates](https://github.com/prawnpdf/prawn-templates).
19
+
20
+ ## Installation
21
+
22
+ Bollettino depends on [ImageMagick](http://www.imagemagick.org/). Sorry, guys.
23
+
24
+ Add this line to your application's `Gemfile`:
25
+
26
+ ```ruby
27
+ gem 'bollettino'
28
+ ```
29
+
30
+ And then execute:
31
+
32
+ $ bundle
33
+
34
+ Or install it yourself as:
35
+
36
+ $ gem install bollettino
37
+
38
+ ## Usage
39
+
40
+ ```ruby
41
+ payee = Bollettino::Payee.new(
42
+ account_number: '0123456789',
43
+ name: 'Acme Inc.'
44
+ )
45
+
46
+ payer = Bollettino::Payer.new(
47
+ name: 'John Doe',
48
+ address: Bollettino::Address.new(
49
+ street: '3681 Foggy Moor',
50
+ zip: '19147-0834',
51
+ location: 'Grayson'
52
+ )
53
+ )
54
+
55
+ payment_order = Bollettino::PaymentOrder.new(
56
+ numeric_amount: 54.31,
57
+ text_amount: 'Cinquantaquattro/31',
58
+ reason: 'Invoice INV-1391'
59
+ )
60
+
61
+ slip = Bollettino::Slip.new(
62
+ payee: payee,
63
+ payer: payer,
64
+ payment_order: payment_order
65
+ )
66
+
67
+ generator = Bollettino::Generator.new
68
+ generator.generate!(slip, 'slip.png')
69
+ ```
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it (https://github.com/interconn-isp/bollettino/fork)
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/assets/slip.png ADDED
Binary file
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bollettino/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'bollettino'
8
+ spec.version = Bollettino::VERSION
9
+ spec.authors = ['Alessandro Desantis']
10
+ spec.email = ['desa.alessandro@gmail.com']
11
+ spec.summary = 'Bollettino is a tool for generating Italian postal payment slips.'
12
+ spec.description = 'Bollettino is a tool for generating postal payment slips in the Italian format.'
13
+ spec.homepage = 'https://github.com/interconn-isp/bollettino'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake', '~> 10.3'
23
+ spec.add_development_dependency 'rspec', '~> 3.1'
24
+ spec.add_development_dependency 'mocha', '~> 1.1'
25
+
26
+ spec.add_runtime_dependency 'virtus', '~> 1.0'
27
+ spec.add_runtime_dependency 'mini_magick', '~> 4.0'
28
+ end
data/example-slip.png ADDED
Binary file
@@ -0,0 +1,13 @@
1
+ class Bollettino::Generator
2
+ attr_reader :options
3
+
4
+ def initialize(options = {})
5
+ @options = options
6
+ end
7
+
8
+ def generate!(slip, path)
9
+ image = MiniMagick::Image.open(File.expand_path('../../../assets/slip.png', __FILE__))
10
+ Bollettino::Renderer::SlipRenderer.render(image, slip)
11
+ image.write path
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ class Bollettino::Address
2
+ include Virtus.model
3
+
4
+ attribute :street, String
5
+ attribute :zip, String
6
+ attribute :location, String
7
+ end
@@ -0,0 +1,6 @@
1
+ class Bollettino::Payee
2
+ include Virtus.model
3
+
4
+ attribute :account_number, String
5
+ attribute :name, String
6
+ end
@@ -0,0 +1,6 @@
1
+ class Bollettino::Payer
2
+ include Virtus.model
3
+
4
+ attribute :name, String
5
+ attribute :address, Bollettino::Address
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'virtus'
2
+
3
+ class Bollettino::PaymentOrder
4
+ include Virtus.model
5
+
6
+ attribute :numeric_amount, Float
7
+ attribute :text_amount, String
8
+ attribute :reason, String
9
+ end
@@ -0,0 +1,7 @@
1
+ class Bollettino::Slip
2
+ include Virtus.model
3
+
4
+ attribute :payee, Bollettino::Payee
5
+ attribute :payer, Bollettino::Payer
6
+ attribute :payment_order, Bollettino::PaymentOrder
7
+ end
@@ -0,0 +1,26 @@
1
+ class Bollettino::Renderer
2
+ KERNING_NORMAL = 1
3
+
4
+ KERNING_BOX = 17.5
5
+ KERNING_BOX_SMALLER = 17
6
+ KERNING_BOX_SMALLEST = 16
7
+
8
+ FONT_SIZE_NORMAL = 30
9
+ FONT_SIZE_SMALL = 25
10
+
11
+ protected
12
+
13
+ def self.write_text(image, coords, text, kerning = KERNING_NORMAL, font_size = FONT_SIZE_NORMAL)
14
+ image.combine_options do |c|
15
+ c.font 'courier'
16
+ c.fill 'black'
17
+ c.pointsize font_size
18
+ c.gravity 'southwest'
19
+ c.kerning kerning
20
+ c.draw %Q[text #{coords.join(',')} "#{text.to_s.upcase.gsub('"', '\"')}"]
21
+ end
22
+ end
23
+
24
+ class RenderingError < StandardError
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ class Bollettino::Renderer::AddressRenderer < Bollettino::Renderer
2
+ def self.render(image, address)
3
+ render_street(image, address)
4
+ render_zip(image, address)
5
+ render_location(image, address)
6
+ end
7
+
8
+ private
9
+
10
+ def self.render_street(image, address)
11
+ write_text(image, [85, 267], address.street[0..29], KERNING_NORMAL, FONT_SIZE_SMALL)
12
+ write_text(image, [1508, 267], address.street[0..22], KERNING_BOX_SMALLEST)
13
+ end
14
+
15
+ def self.render_zip(image, address)
16
+ write_text(image, [85, 223], address.zip[0..29], KERNING_NORMAL, FONT_SIZE_SMALL)
17
+ write_text(image, [1508, 200], address.zip[0..4], KERNING_BOX_SMALLEST)
18
+ end
19
+
20
+ def self.render_location(image, address)
21
+ write_text(image, [85, 180], address.location[0..29], KERNING_NORMAL, FONT_SIZE_SMALL)
22
+ write_text(image, [1713, 200], address.location[0..16], KERNING_BOX_SMALLEST)
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ class Bollettino::Renderer::PayeeRenderer < Bollettino::Renderer
2
+ def self.render(image, payee)
3
+ render_account_number(image, payee)
4
+ render_name(image, payee)
5
+ end
6
+
7
+ private
8
+
9
+ def self.render_account_number(image, payee)
10
+ if payee.account_number.length > 10
11
+ raise RenderingError, "Account number can't be longer than 10 characters"
12
+ end
13
+
14
+ [[265, 695], [1310, 695]].each do |coords|
15
+ write_text(image, coords, payee.account_number, KERNING_BOX)
16
+ end
17
+ end
18
+
19
+ def self.render_name(image, payee)
20
+ write_text(image, [90, 585], payee.name[0..46])
21
+ write_text(image, [90, 545], payee.name[47..93])
22
+
23
+ write_text(image, [1105, 590], payee.name[0..33], KERNING_BOX_SMALLER)
24
+ write_text(image, [1105, 545], payee.name[34..67], KERNING_BOX_SMALLER)
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ class Bollettino::Renderer::PayerRenderer < Bollettino::Renderer
2
+ def self.render(image, payer)
3
+ render_name(image, payer)
4
+ render_address(image, payer)
5
+ end
6
+
7
+ private
8
+
9
+ def self.render_name(image, payer)
10
+ write_text(image, [85, 360], payer.name[0..24])
11
+ write_text(image, [85, 315], payer.name[25..49])
12
+
13
+ write_text(image, [1508, 375], payer.name[0..22], KERNING_BOX_SMALLEST)
14
+ write_text(image, [1508, 330], payer.name[22..44], KERNING_BOX_SMALLEST)
15
+ end
16
+
17
+ def self.render_address(image, payer)
18
+ Bollettino::Renderer::AddressRenderer.render(image, payer.address)
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ class Bollettino::Renderer::PaymentOrderRenderer < Bollettino::Renderer
2
+ def self.render(image, payment_order)
3
+ render_numeric_amount(image, payment_order)
4
+ render_text_amount(image, payment_order)
5
+ render_reason(image, payment_order)
6
+ end
7
+
8
+ private
9
+
10
+ def self.render_numeric_amount(image, payment_order)
11
+ numeric_amount = payment_order.numeric_amount
12
+ numeric_amount = ('%.2f' % numeric_amount).to_s.gsub('.', '')
13
+
14
+ if numeric_amount.length > 7
15
+ raise RenderingError, "Numeric amount can't be longer than 7 total digits"
16
+ end
17
+
18
+ numeric_amount_x = 1000 - 35 * numeric_amount.length.to_i
19
+
20
+ [[numeric_amount_x, 690], [numeric_amount_x + 1315, 690]].each do |coords|
21
+ write_text(image, coords, numeric_amount, KERNING_BOX)
22
+ end
23
+ end
24
+
25
+ def self.render_reason(image, payment_order)
26
+ write_text(image, [90, 475], payment_order.reason[0..46])
27
+ write_text(image, [90, 435], payment_order.reason[47..93])
28
+
29
+ write_text(image, [1110, 475], payment_order.reason[0..60])
30
+ write_text(image, [1110, 435], payment_order.reason[61..121])
31
+ end
32
+
33
+ def self.render_text_amount(image, payment_order)
34
+ write_text(image, [245, 650], payment_order.text_amount[0..38])
35
+ write_text(image, [1435, 650], payment_order.text_amount[0..44])
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ class Bollettino::Renderer::SlipRenderer < Bollettino::Renderer
2
+ def self.render(image, slip)
3
+ render_payment_order(image, slip)
4
+ render_payee(image, slip)
5
+ render_payer(image, slip)
6
+ end
7
+
8
+ private
9
+
10
+ def self.render_payment_order(image, slip)
11
+ Bollettino::Renderer::PaymentOrderRenderer.render(image, slip.payment_order)
12
+ end
13
+
14
+ def self.render_payee(image, slip)
15
+ Bollettino::Renderer::PayeeRenderer.render(image, slip.payee)
16
+ end
17
+
18
+ def self.render_payer(image, slip)
19
+ Bollettino::Renderer::PayerRenderer.render(image, slip.payer)
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Bollettino
2
+ VERSION = '0.1.0'
3
+ end
data/lib/bollettino.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'virtus'
2
+ require 'mini_magick'
3
+
4
+ require 'bollettino/version'
5
+
6
+ require 'bollettino/models/address'
7
+ require 'bollettino/models/payee'
8
+ require 'bollettino/models/payer'
9
+ require 'bollettino/models/payment_order'
10
+ require 'bollettino/models/slip'
11
+
12
+ require 'bollettino/renderer'
13
+
14
+ require 'bollettino/renderers/address_renderer'
15
+ require 'bollettino/renderers/payer_renderer'
16
+ require 'bollettino/renderers/payee_renderer'
17
+ require 'bollettino/renderers/payment_order_renderer'
18
+ require 'bollettino/renderers/slip_renderer'
19
+
20
+ require 'bollettino/generator'
21
+
22
+ module Bollettino
23
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'The generation' do
4
+ let(:payee) do
5
+ Bollettino::Payee.new(
6
+ account_number: '0123456789',
7
+ name: 'Acme Inc.'
8
+ )
9
+ end
10
+
11
+ let(:payer) do
12
+ Bollettino::Payer.new(
13
+ name: 'John Doe',
14
+ address: Bollettino::Address.new(
15
+ street: '3681 Foggy Moor',
16
+ zip: '19147-0834',
17
+ location: 'Grayson'
18
+ )
19
+ )
20
+ end
21
+
22
+ let(:payment_order) do
23
+ Bollettino::PaymentOrder.new(
24
+ numeric_amount: 54.31,
25
+ text_amount: 'Cinquantaquattro/31',
26
+ reason: 'Invoice INV-1391'
27
+ )
28
+
29
+ end
30
+
31
+ let(:slip) do
32
+ Bollettino::Slip.new(
33
+ payee: payee,
34
+ payer: payer,
35
+ payment_order: payment_order
36
+ )
37
+ end
38
+
39
+ let(:slip_path) { File.expand_path('../../../tmp/slip.png', __FILE__) }
40
+
41
+ before(:each) do
42
+ FileUtils.rm(slip_path) if File.exist?(slip_path)
43
+ end
44
+
45
+ it 'creates the slip' do
46
+ expect {
47
+ Bollettino::Generator.new.generate!(slip, slip_path)
48
+ }.to change{File.exist?(slip_path)}.from(false).to(true)
49
+ end
50
+ end
@@ -0,0 +1,82 @@
1
+ require 'bollettino'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
6
+ # file to always be loaded, without a need to explicitly require it in any files.
7
+ #
8
+ # Given that it is always loaded, you are encouraged to keep this file as
9
+ # light-weight as possible. Requiring heavyweight dependencies from this file
10
+ # will add to the boot time of your test suite on EVERY test run, even for an
11
+ # individual file that may not need all of that loaded. Instead, consider making
12
+ # a separate helper file that requires the additional dependencies and performs
13
+ # the additional setup, and require it from the spec files that actually need it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.expect_with :rspec do |expectations|
24
+ # This option will default to `true` in RSpec 4. It makes the `description`
25
+ # and `failure_message` of custom matchers include text for helper methods
26
+ # defined using `chain`, e.g.:
27
+ # be_bigger_than(2).and_smaller_than(4).description
28
+ # # => "be bigger than 2 and smaller than 4"
29
+ # ...rather than:
30
+ # # => "be bigger than 2"
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ end
33
+
34
+ # rspec-mocks config goes here. You can use an alternate test double
35
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
36
+ config.mock_with :mocha
37
+
38
+ # These two settings work together to allow you to limit a spec run
39
+ # to individual examples or groups you care about by tagging them with
40
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
41
+ # get run.
42
+ config.filter_run :focus
43
+ config.run_all_when_everything_filtered = true
44
+
45
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
46
+ # For more details, see:
47
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
48
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
49
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
50
+ config.disable_monkey_patching!
51
+
52
+ # This setting enables warnings. It's recommended, but in some cases may
53
+ # be too noisy due to issues in dependencies.
54
+ config.warnings = false
55
+
56
+ # Many RSpec users commonly either run the entire suite or an individual
57
+ # file, and it's useful to allow more verbose output when running an
58
+ # individual spec file.
59
+ if config.files_to_run.one?
60
+ # Use the documentation formatter for detailed output,
61
+ # unless a formatter has already been configured
62
+ # (e.g. via a command-line flag).
63
+ config.default_formatter = 'doc'
64
+ end
65
+
66
+ # Print the 10 slowest examples and example groups at the
67
+ # end of the spec run, to help surface which specs are running
68
+ # particularly slow.
69
+ config.profile_examples = false
70
+
71
+ # Run specs in random order to surface order dependencies. If you find an
72
+ # order dependency and want to debug it, you can fix the order by providing
73
+ # the seed, which is printed after each run.
74
+ # --seed 1234
75
+ config.order = :random
76
+
77
+ # Seed global randomization in this process using the `--seed` CLI option.
78
+ # Setting this allows you to use `--seed` to deterministically reproduce
79
+ # test failures related to randomization by passing the same `--seed` value
80
+ # as the one that triggered the failure.
81
+ Kernel.srand config.seed
82
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Generator do
4
+ subject { described_class.new }
5
+
6
+ describe '#generate!' do
7
+ let(:slip) do
8
+ rs = (('A'..'Z').to_a * 10).join('')
9
+
10
+ stub(
11
+ payee: stub(
12
+ account_number: '0123456789',
13
+ name: rs
14
+ ),
15
+ payment_order: stub(
16
+ numeric_amount: 1,
17
+ text_amount: rs,
18
+ reason: rs
19
+ ),
20
+ payer: stub(
21
+ name: rs,
22
+ address: stub(
23
+ street: rs,
24
+ location: rs,
25
+ zip: rs
26
+ )
27
+ )
28
+ )
29
+ end
30
+
31
+ it 'writes the image' do
32
+ image = mock()
33
+ image
34
+ .expects(:write)
35
+ .with('slip.png')
36
+ .once
37
+
38
+ MiniMagick::Image
39
+ .expects(:open)
40
+ .once
41
+ .returns(image)
42
+
43
+ Bollettino::Renderer::SlipRenderer
44
+ .expects(:render)
45
+ .once
46
+
47
+ subject.generate!(slip, 'slip.png')
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Address do
4
+ it 'is instantiated correctly' do
5
+ described_class.new(
6
+ street: '3681 Foggy Moor',
7
+ zip: '19147-0834',
8
+ city: 'Grayson',
9
+ state: 'Pennsylvania'
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Payee do
4
+ it 'is instantiated correctly' do
5
+ described_class.new(
6
+ account_number: '0123456789',
7
+ name: 'Acme Inc.'
8
+ )
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Payer do
4
+ it 'is instantiated correctly' do
5
+ address = Bollettino::Address.new
6
+
7
+ described_class.new(
8
+ name: 'John Doe',
9
+ address: address
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Payee do
4
+ it 'is instantiated correctly' do
5
+ described_class.new(
6
+ numeric_amount: 54.31,
7
+ text_amount: 'Cinquantaquattro/31',
8
+ reason: 'Invoice INV-1391'
9
+ )
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Slip do
4
+ it 'is instantiated correctly' do
5
+ payee = Bollettino::Payee.new
6
+ payer = Bollettino::Payer.new
7
+ payment_order = Bollettino::PaymentOrder.new
8
+
9
+ described_class.new(
10
+ payee: payee,
11
+ payer: payer,
12
+ payment_order: payment_order
13
+ )
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Renderer::AddressRenderer do
4
+ subject { described_class }
5
+
6
+ describe '.render' do
7
+ it 'renders the address' do
8
+ address = stub(
9
+ street: 'Via Fasulla, 123',
10
+ location: 'Roma',
11
+ zip: '00100'
12
+ )
13
+
14
+ image = stub()
15
+
16
+ subject
17
+ .expects(:write_text)
18
+ .times(6)
19
+
20
+ subject.render image, address
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Renderer::PayeeRenderer do
4
+ subject { described_class }
5
+
6
+ describe '.render' do
7
+ it 'renders the payee' do
8
+ payee = stub(
9
+ account_number: '0123456789',
10
+ name: 'Acme Inc.'
11
+ )
12
+
13
+ image = stub()
14
+
15
+ subject
16
+ .expects(:write_text)
17
+ .times(6)
18
+
19
+ subject.render image, payee
20
+ end
21
+
22
+ context 'when account_number is longer than 10 characters' do
23
+ it 'raises an error' do
24
+ payee = stub(
25
+ account_number: '01234567891',
26
+ name: 'Acme Inc.'
27
+ )
28
+
29
+ image = stub()
30
+
31
+ expect {
32
+ subject.render image, payee
33
+ }.to raise_error(Bollettino::Renderer::RenderingError)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Renderer::PayerRenderer do
4
+ subject { described_class }
5
+
6
+ describe '.render' do
7
+ it 'renders the payer' do
8
+ payer = stub(
9
+ name: 'Acme Inc.',
10
+ address: stub()
11
+ )
12
+
13
+ image = stub()
14
+
15
+ Bollettino::Renderer::AddressRenderer
16
+ .expects(:render)
17
+ .with(image, payer.address)
18
+ .once
19
+
20
+ subject
21
+ .expects(:write_text)
22
+ .times(4)
23
+
24
+ subject.render image, payer
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Renderer::PaymentOrderRenderer do
4
+ subject { described_class }
5
+
6
+ describe '.render' do
7
+ it 'renders the payment_order' do
8
+ payment_order = stub(
9
+ text_amount: 'Millecentociquanta/25',
10
+ numeric_amount: 1150.25,
11
+ reason: 'Invoce INV-1234'
12
+ )
13
+
14
+ image = stub()
15
+
16
+ subject
17
+ .expects(:write_text)
18
+ .times(8)
19
+
20
+ subject.render image, payment_order
21
+ end
22
+
23
+ context 'when numeric_amount is longer than 7 digits' do
24
+ it 'raises an error' do
25
+ payment_order = stub(
26
+ text_amount: 'Millecentociquanta/25',
27
+ numeric_amount: 123456.78,
28
+ reason: 'Invoce INV-1234'
29
+ )
30
+
31
+ image = stub()
32
+
33
+ expect {
34
+ subject.render image, payment_order
35
+ }.to raise_error(Bollettino::Renderer::RenderingError)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Bollettino::Renderer::SlipRenderer do
4
+ subject { described_class }
5
+
6
+ describe '.render' do
7
+ it 'renders the slip' do
8
+ slip = stub(
9
+ payee: stub(),
10
+ payer: stub(),
11
+ payment_order: stub()
12
+ )
13
+
14
+ image = stub()
15
+
16
+ Bollettino::Renderer::PayeeRenderer
17
+ .expects(:render)
18
+ .with(image, slip.payee)
19
+ .once
20
+
21
+ Bollettino::Renderer::PayerRenderer
22
+ .expects(:render)
23
+ .with(image, slip.payer)
24
+ .once
25
+
26
+ Bollettino::Renderer::PaymentOrderRenderer
27
+ .expects(:render)
28
+ .with(image, slip.payment_order)
29
+ .once
30
+
31
+ subject.render image, slip
32
+ end
33
+ end
34
+ end
data/tmp/.keep ADDED
File without changes
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bollettino
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alessandro Desantis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: virtus
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mini_magick
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.0'
97
+ description: Bollettino is a tool for generating postal payment slips in the Italian
98
+ format.
99
+ email:
100
+ - desa.alessandro@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".travis.yml"
108
+ - CHANGELOG.md
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - assets/slip.png
114
+ - bollettino.gemspec
115
+ - example-slip.png
116
+ - lib/bollettino.rb
117
+ - lib/bollettino/generator.rb
118
+ - lib/bollettino/models/address.rb
119
+ - lib/bollettino/models/payee.rb
120
+ - lib/bollettino/models/payer.rb
121
+ - lib/bollettino/models/payment_order.rb
122
+ - lib/bollettino/models/slip.rb
123
+ - lib/bollettino/renderer.rb
124
+ - lib/bollettino/renderers/address_renderer.rb
125
+ - lib/bollettino/renderers/payee_renderer.rb
126
+ - lib/bollettino/renderers/payer_renderer.rb
127
+ - lib/bollettino/renderers/payment_order_renderer.rb
128
+ - lib/bollettino/renderers/slip_renderer.rb
129
+ - lib/bollettino/version.rb
130
+ - spec/integration/generation_spec.rb
131
+ - spec/spec_helper.rb
132
+ - spec/unit/bollettino/generator_spec.rb
133
+ - spec/unit/bollettino/models/address_spec.rb
134
+ - spec/unit/bollettino/models/payee_spec.rb
135
+ - spec/unit/bollettino/models/payer_spec.rb
136
+ - spec/unit/bollettino/models/payment_order_spec.rb
137
+ - spec/unit/bollettino/models/slip_spec.rb
138
+ - spec/unit/bollettino/renderers/address_renderer_spec.rb
139
+ - spec/unit/bollettino/renderers/payee_renderer_spec.rb
140
+ - spec/unit/bollettino/renderers/payer_renderer_spec.rb
141
+ - spec/unit/bollettino/renderers/payment_order_renderer_spec.rb
142
+ - spec/unit/bollettino/renderers/slip_renderer_spec.rb
143
+ - tmp/.keep
144
+ homepage: https://github.com/interconn-isp/bollettino
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.4.3
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Bollettino is a tool for generating Italian postal payment slips.
168
+ test_files:
169
+ - spec/integration/generation_spec.rb
170
+ - spec/spec_helper.rb
171
+ - spec/unit/bollettino/generator_spec.rb
172
+ - spec/unit/bollettino/models/address_spec.rb
173
+ - spec/unit/bollettino/models/payee_spec.rb
174
+ - spec/unit/bollettino/models/payer_spec.rb
175
+ - spec/unit/bollettino/models/payment_order_spec.rb
176
+ - spec/unit/bollettino/models/slip_spec.rb
177
+ - spec/unit/bollettino/renderers/address_renderer_spec.rb
178
+ - spec/unit/bollettino/renderers/payee_renderer_spec.rb
179
+ - spec/unit/bollettino/renderers/payer_renderer_spec.rb
180
+ - spec/unit/bollettino/renderers/payment_order_renderer_spec.rb
181
+ - spec/unit/bollettino/renderers/slip_renderer_spec.rb