foraneus 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZWMwYTU4OWRiZmI3YWMyYzVjYTc3OTc1YzJiOTUzZDM4YmU5YzZjNw==
5
- data.tar.gz: !binary |-
6
- Mjc1YzUwODZhMTRiZmFhNTcxZjljYTQ3YzY1Nzk3NDA3Y2YyOTkyZQ==
2
+ SHA1:
3
+ metadata.gz: 9cc94a9dc63702c1d2b3c8cbfb61fb4df4c0184c
4
+ data.tar.gz: a17c6451c968d63a195d242c95633aa9a10430d2
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MjY2MmFlYmQ2MzhlMzBhOWM0MTE0ZWQ1N2ZmZDI4MmVhMzkxMzA5Nzg0NmY4
10
- MzM1YjJmNzNiNzQ0YWU4MTY4ZDcxNTkzNjMzZTdjMjY5ZTdiNDY4ODJlYjdh
11
- YWRhOWZmNTY0NTBmMDhiMTIyNjk4ZTU4M2ZmODI2NjMwM2ZhZDM=
12
- data.tar.gz: !binary |-
13
- ZmRmZGI3NjFiODYzOGU1NDNjMGUwMTQ1NTkxODUzNGYwZmYzNzQxZWY0ZTY2
14
- NjA4NjZmMjQxYTY5ZGJkNzQwOWYyMGYxN2UxNmVhYzgzYzQ5MzI4ZTZlNTA3
15
- YTZhNTUyYWUwZjAwODE4YzBiZThkM2M3NWI1NWNkODg4YjAxMzk=
6
+ metadata.gz: 72d2b1d0693b01fe09d794b3cfc25f3316ff732e2df92fcfe5316645a5f6063c8c1e8fadae7b2827050297295d4c2c82415d16ce60c33b0a7fac56656ae179e8
7
+ data.tar.gz: 707019d7e8a43204dea773430eada124306bda384fcff69664b393ac4db9372379cfa11fc1cc61874bcc4e0436c1321d2539d29ab445670a0a75b43c594c102b
data/README.md CHANGED
@@ -91,11 +91,13 @@ Converters have two interrelated responsibilities:
91
91
  - Parse data, like the string `"3,000"`, into an object, `like 3_000`.
92
92
  - Serialize data, like integer `3_000`, into string `"3,000"`
93
93
 
94
- A converter is simply an object that responds to `#parse(s)` and `#raw(v)` methods.
94
+ A converter is simply an object that responds to `#parse(s)`, `#raw(v)`, and `#opts` methods.
95
95
 
96
96
  When `#parse(s)` raises a StandardError exception, or any of its descendants, the exception is
97
97
  rescued and a Foraneus::Error instance is added to `Foraneus#errors` map.
98
98
 
99
+ `#opts` should return the opts hash used to instantiate the converter.
100
+
99
101
  Built-in converters:
100
102
 
101
103
  - Boolean
@@ -8,6 +8,12 @@ class Foraneus
8
8
  # When converting to a raw value, a true value => 'true', a false value => 'false'.
9
9
  class Boolean
10
10
 
11
+ attr_reader :opts
12
+
13
+ def initialize(opts = {})
14
+ @opts = opts
15
+ end
16
+
11
17
  # @return [Boolean]
12
18
  def parse(s)
13
19
  if s == 'true'
@@ -7,9 +7,12 @@ class Foraneus
7
7
 
8
8
  DEFAULT_FORMAT = '%Y-%m-%d'
9
9
 
10
+ attr_reader :opts
11
+
10
12
  # @param [Hash] opts
11
13
  # @option opts [String] format Date format.
12
14
  def initialize(opts = {})
15
+ @opts = opts
13
16
  @format = opts[:format] || DEFAULT_FORMAT
14
17
  end
15
18
 
@@ -1,34 +1,14 @@
1
1
  require 'bigdecimal'
2
+ require 'foraneus/converters/float'
2
3
 
3
4
  class Foraneus
4
5
  module Converters
5
6
 
6
- class Decimal
7
- DEFAULT_SEPARATOR = '.'
8
-
9
- DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
10
-
11
- # @param [Hash] opts
12
- # @option opts [String] delimiter Thousands delimiter.
13
- # @option opts [String] separator Decimal separator.
14
- # @option opts [Integer] precision Minimum precision.
15
- def initialize(opts = {})
16
- @delimiter = opts[:delimiter]
17
- @precision = opts[:precision]
18
- @separator = opts[:separator] || DEFAULT_SEPARATOR
19
- end
7
+ class Decimal < Foraneus::Converters::Float
20
8
 
21
9
  # @return [BigDecimal]
22
10
  def parse(s)
23
- parts = s.split(@separator)
24
-
25
- integer_part = (parts[0] || '0')
26
-
27
- if @delimiter
28
- integer_part.gsub!(@delimiter, '')
29
- end
30
-
31
- fractional_part = parts[1] || '0'
11
+ integer_part, fractional_part = split(s)
32
12
 
33
13
  BigDecimal.new("#{integer_part}.#{fractional_part}")
34
14
  end
@@ -36,15 +16,7 @@ class Foraneus
36
16
  def raw(v)
37
17
  left, right = v.to_s('F').split('.')
38
18
 
39
- if @precision && right.length < @precision
40
- right = add_trailing_zeros(right, @precision - right.length)
41
- end
42
-
43
- if @delimiter
44
- left.gsub!(DELIMITED_REGEX) { "#{$1}#{@delimiter}" }
45
- end
46
-
47
- "#{left}#{@separator}#{right}"
19
+ join(left, right)
48
20
  end
49
21
 
50
22
  private
@@ -7,11 +7,15 @@ class Foraneus
7
7
 
8
8
  DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
9
9
 
10
+ attr_reader :opts
11
+
10
12
  # @param [Hash] opts
11
13
  # @option opts [String] delimiter Thousands delimiter.
12
14
  # @option opts [String] separator Decimal separator.
13
15
  # @option opts [Integer] precision Minimum precision.
14
16
  def initialize(opts = {})
17
+ @opts = opts
18
+
15
19
  @delimiter = opts[:delimiter]
16
20
  @precision = opts[:precision]
17
21
  @separator = opts[:separator] || DEFAULT_SEPARATOR
@@ -19,19 +23,7 @@ class Foraneus
19
23
 
20
24
  # @return [Float]
21
25
  def parse(s)
22
- if s == ''
23
- raise ArgumentError, 'invalid value for Float(): ""'
24
- end
25
-
26
- parts = s.split(@separator)
27
-
28
- integer_part = parts[0] || '0'
29
-
30
- if @delimiter
31
- integer_part.gsub!(@delimiter, '')
32
- end
33
-
34
- fractional_part = parts[1] || '0'
26
+ integer_part, fractional_part = split(s)
35
27
 
36
28
  Kernel.Float("#{integer_part}.#{fractional_part}")
37
29
  end
@@ -39,6 +31,19 @@ class Foraneus
39
31
  def raw(v)
40
32
  left, right = v.to_s.split('.')
41
33
 
34
+ join(left, right)
35
+ end
36
+
37
+ protected
38
+ # Joins both integer and fractional parts.
39
+ #
40
+ # It adds trailing zeros according to the current precision.
41
+ #
42
+ # @param [Integer] left Integer part
43
+ # @param [Integer] right Fractional part
44
+ #
45
+ # @return [String]
46
+ def join(left, right)
42
47
  if @precision && right.length < @precision
43
48
  right = add_trailing_zeros(right, @precision - right.length)
44
49
  end
@@ -50,6 +55,25 @@ class Foraneus
50
55
  "#{left}#{@separator}#{right}"
51
56
  end
52
57
 
58
+ # Splits a float representation into its integer and fractional parts.
59
+ #
60
+ # @param [String] s
61
+ #
62
+ # @return [Array [integer_part, fractional_part] ]
63
+ def split(s)
64
+ parts = s.split(@separator)
65
+
66
+ integer_part = parts[0] || '0'
67
+
68
+ if @delimiter
69
+ integer_part.gsub!(@delimiter, '')
70
+ end
71
+
72
+ fractional_part = parts[1] || '0'
73
+
74
+ [integer_part, fractional_part]
75
+ end
76
+
53
77
  private
54
78
  def add_trailing_zeros(s, n)
55
79
  zeros = '0' * n
@@ -4,9 +4,12 @@ class Foraneus
4
4
  class Integer
5
5
  DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
6
6
 
7
+ attr_reader :opts
8
+
7
9
  # @param [Hash] opts
8
10
  # @option opts [String] delimiter Thousands delimiter.
9
11
  def initialize(opts = {})
12
+ @opts = opts
10
13
  @delimiter = opts[:delimiter]
11
14
  end
12
15
 
@@ -6,6 +6,12 @@ class Foraneus
6
6
  # It does not perform any conversion at all. Useful when its needed to have a field but
7
7
  # conversion is handled at another level.
8
8
  class Noop
9
+ attr_reader :opts
10
+
11
+ def initialize(opts = {})
12
+ @opts = opts
13
+ end
14
+
9
15
  # @return [Object]
10
16
  def parse(o)
11
17
  o
@@ -3,6 +3,12 @@ class Foraneus
3
3
 
4
4
  class String
5
5
 
6
+ attr_reader :opts
7
+
8
+ def initialize(opts = {})
9
+ @opts = opts
10
+ end
11
+
6
12
  # @return [String]
7
13
  def parse(s)
8
14
  s.to_s
data/lib/foraneus.rb CHANGED
@@ -186,11 +186,15 @@ class Foraneus
186
186
  field = k.to_s
187
187
  converter = fields[field]
188
188
 
189
- return unless converter
190
-
191
189
  foraneus[k] = v
192
190
 
193
- unless v.nil?
191
+ return unless converter
192
+
193
+ if (v.nil? || v == '') && converter.opts[:required]
194
+ raise KeyError, "required parameter not found: #{field.inspect}"
195
+ elsif v.nil? || v == ''
196
+ v = nil
197
+ else
194
198
  v = converter.parse(v)
195
199
  end
196
200
 
@@ -66,22 +66,6 @@ describe Foraneus::Converters::Float do
66
66
  }.to raise_error
67
67
  end
68
68
  end
69
-
70
- context 'with empty values' do
71
- it 'raises an error' do
72
- expect {
73
- subject.parse('')
74
- }.to raise_error
75
- end
76
- end
77
-
78
- context 'with nil values' do
79
- it 'raises an error' do
80
- expect {
81
- subject.parse(nil)
82
- }.to raise_error
83
- end
84
- end
85
69
  end
86
70
 
87
71
  describe '#raw' do
@@ -16,9 +16,11 @@ describe Foraneus do
16
16
 
17
17
  its(:delay) { should eq(5) }
18
18
 
19
+ its(:data) { should include(:delay => 5) }
20
+
19
21
  its([:delay]) { should eq('5') }
20
22
 
21
- its(:data) { should include(:delay => 5) }
23
+ its(['delay']) { should be_nil }
22
24
 
23
25
  its([]) { should include(:delay => '5') }
24
26
 
@@ -37,18 +39,6 @@ describe Foraneus do
37
39
 
38
40
  its([]) { should include('delay' => '5') }
39
41
  end
40
-
41
- context 'with nil values' do
42
- subject(:form) { form_spec.parse('delay' => nil) }
43
-
44
- its(['delay']) { should eq(nil) }
45
-
46
- its([:delay]) { should eq(nil) }
47
-
48
- its(:data) { should include('delay' => nil) }
49
-
50
- its([]) { should include('delay' => nil) }
51
- end
52
42
  end
53
43
 
54
44
  context 'with non parseable data' do
@@ -80,6 +70,68 @@ describe Foraneus do
80
70
  its(:message) { should eq(converter_exception.message) }
81
71
  end
82
72
  end
73
+
74
+ context 'with unexpected data' do
75
+ subject(:form) { form_spec.parse(:position => 'north') }
76
+
77
+ it 'does not have a getter for the received param' do
78
+ expect {
79
+ form.position
80
+ }.to raise_error(NoMethodError)
81
+ end
82
+
83
+ its(:data) { should_not include(:position) }
84
+
85
+ its([:position]) { should eq('north') }
86
+
87
+ its([]) { should include(:position => 'north') }
88
+
89
+ it { should be_valid }
90
+ end
91
+
92
+ shared_examples 'an absent parameters handler' do |missing_value|
93
+ subject(:form) { form_spec.parse(:delay => missing_value) }
94
+
95
+ it { should be_valid }
96
+
97
+ its(:delay) { should be_nil }
98
+
99
+ its(:data) { should include(:delay => nil) }
100
+
101
+ its([:delay]) { should eq(missing_value) }
102
+
103
+ its([]) { should include(:delay => missing_value) }
104
+
105
+ context 'when required field' do
106
+ let(:converter) { Foraneus::Converters::Integer.new(:required => true) }
107
+
108
+ it { should_not be_valid }
109
+
110
+ its(:delay) { should be_nil }
111
+
112
+ its(:data) { should_not include(:delay) }
113
+
114
+ its([:delay]) { should eq(missing_value) }
115
+
116
+ its([]) { should include(:delay => missing_value) }
117
+
118
+ its([:errors]) { should include(:delay) }
119
+
120
+ describe 'an error' do
121
+ subject(:error) { form[:errors].values.first }
122
+
123
+ its(:key) { should eq('KeyError') }
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'with nil values' do
129
+ it_behaves_like 'an absent parameters handler', nil
130
+ end
131
+
132
+ context 'with empty values' do
133
+ it_behaves_like 'an absent parameters handler', ''
134
+ end
83
135
  end
84
136
 
85
137
  describe '.raw' do
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foraneus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gianfranco Zas
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-15 00:00:00.000000000 Z
11
+ date: 2014-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
- requirement: !ruby/object:Gem::Requirement
15
+ version_requirements: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.14.0
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
20
+ requirement: !ruby/object:Gem::Requirement
23
21
  requirements:
24
22
  - - ~>
25
23
  - !ruby/object:Gem::Version
26
24
  version: 2.14.0
25
+ prerelease: false
26
+ type: :development
27
27
  - !ruby/object:Gem::Dependency
28
- name: redcarpet
29
- requirement: !ruby/object:Gem::Requirement
28
+ name: yard-kramdown
29
+ version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
37
35
  requirements:
38
- - - ! '>='
36
+ - - '>='
39
37
  - !ruby/object:Gem::Version
40
38
  version: '0'
39
+ prerelease: false
40
+ type: :development
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: yard
43
- requirement: !ruby/object:Gem::Requirement
43
+ version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
51
49
  requirements:
52
- - - ! '>='
50
+ - - '>='
53
51
  - !ruby/object:Gem::Version
54
52
  version: '0'
53
+ prerelease: false
54
+ type: :development
55
55
  description: Provides two way transformation mechanisms to external data.
56
56
  email: snmgian@gmail.com
57
57
  executables: []
@@ -70,6 +70,7 @@ files:
70
70
  - COPYING
71
71
  - COPYING.LESSER
72
72
  - README.md
73
+ - spec/spec_helper.rb
73
74
  - spec/lib/foraneus_spec.rb
74
75
  - spec/lib/foraneus/converters/noop_converter_spec.rb
75
76
  - spec/lib/foraneus/converters/decimal_converter_spec.rb
@@ -78,32 +79,32 @@ files:
78
79
  - spec/lib/foraneus/converters/string_converter_spec.rb
79
80
  - spec/lib/foraneus/converters/float_converter_spec.rb
80
81
  - spec/lib/foraneus/converters/boolean_converter_spec.rb
81
- - spec/spec_helper.rb
82
82
  homepage: https://github.com/snmgian/foraneus
83
83
  licenses:
84
84
  - LGPL
85
85
  metadata: {}
86
- post_install_message:
86
+ post_install_message:
87
87
  rdoc_options: []
88
88
  require_paths:
89
89
  - lib
90
90
  required_ruby_version: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - ! '>='
92
+ - - '>='
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - ! '>='
97
+ - - '>='
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
100
  requirements: []
101
- rubyforge_project:
102
- rubygems_version: 2.1.5
103
- signing_key:
101
+ rubyforge_project:
102
+ rubygems_version: 2.1.9
103
+ signing_key:
104
104
  specification_version: 4
105
105
  summary: Transforms external data.
106
106
  test_files:
107
+ - spec/spec_helper.rb
107
108
  - spec/lib/foraneus_spec.rb
108
109
  - spec/lib/foraneus/converters/noop_converter_spec.rb
109
110
  - spec/lib/foraneus/converters/decimal_converter_spec.rb
@@ -112,5 +113,4 @@ test_files:
112
113
  - spec/lib/foraneus/converters/string_converter_spec.rb
113
114
  - spec/lib/foraneus/converters/float_converter_spec.rb
114
115
  - spec/lib/foraneus/converters/boolean_converter_spec.rb
115
- - spec/spec_helper.rb
116
- has_rdoc:
116
+ has_rdoc: