foraneus 0.0.12 → 0.0.13

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
2
  SHA1:
3
- metadata.gz: 5dd151153010e57f4108ce2e054238b10b2d0b46
4
- data.tar.gz: b582478fbb77f95ef5f924b1e7ae2b5bb492c15b
3
+ metadata.gz: f3f668a304ebd112cf2651006dc871679cac85db
4
+ data.tar.gz: 607492a6bd176a001eca2f2f0971e2f6f6dca73f
5
5
  SHA512:
6
- metadata.gz: 6a0c78292a5a51eb6d59dbb6000bed04e4669b95e0b3a78b09e84a9d4c302db1a426930a141166291cab1d2b34279a5837625932655f29270e25b7c82abef74f
7
- data.tar.gz: c9385cc3522459024a4d68f148dbb08200411099b3d809e85f54d4c51d4ab99bc8a2965466f278b960d093d15e9d0fe929bd687dffd75e5c4e0f24d7a2a1135d
6
+ metadata.gz: 1954c53b5f18b2099d55a2e4c0d92dc09cb6cfca491e0db191b220a997cb8abedd580392edcb70c8ab3d80363d97b938fee4d6e99531d2fe13436b0074eb1f8c
7
+ data.tar.gz: 8689562a31c5c06aade9b290f663539f0e8f042bddb1a71638b92a70f24944f853ee48fa3458b7310cfac8dc304b0d09db019023bded19bb9d6fd694b8d415f3
data/README.md CHANGED
@@ -62,16 +62,16 @@ Declare source classes by inheriting from `Foraneus` base class.
62
62
  end
63
63
  ```
64
64
 
65
- Fields are declared in two ways:
65
+ Fields are declared by two ways:
66
66
 
67
67
  - calling `.field`
68
68
  - calling a shortcut method, like `.float`
69
69
 
70
70
 
71
- There are handy methods for any of the built-in converters: boolean, date, decimal, float, integer,
71
+ There are shortcut methods for any of the built-in converters: boolean, date, decimal, float, integer,
72
72
  noop, and string.
73
73
 
74
- When no converter is passed to `.field`, Foraneus::Converters::Noop is assigned to the declared
74
+ When no converter is passed to `.field`, `Foraneus::Converters::Noop` is assigned to the declared
75
75
  field.
76
76
 
77
77
  ## Instantiation
@@ -91,10 +91,10 @@ 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)`, `#raw(v)`, and `#opts` methods.
94
+ A converter is 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
- rescued and a Foraneus::Error instance is added to `Foraneus#errors` map.
97
+ rescued and a `Foraneus::Error` instance is added to `Foraneus#errors` map.
98
98
 
99
99
  `#opts` should return the opts hash used to instantiate the converter.
100
100
 
@@ -119,7 +119,7 @@ Valid instance:
119
119
 
120
120
  ``` ruby
121
121
  form.valid? # => true
122
- form[:errors] # => {}
122
+ form.errors # => {}
123
123
  ```
124
124
 
125
125
  Invalid one:
@@ -129,15 +129,15 @@ Invalid one:
129
129
 
130
130
  form.valid? # => false
131
131
 
132
- form[:errors][:delay].key # => 'ArgumentError'
133
- form[:errors][:delay].message # => 'invalid value for Integer(): "INVALID"'
132
+ form.errors[:delay].key # => 'ArgumentError'
133
+ form.errors[:delay].message # => 'invalid value for Integer(): "INVALID"'
134
134
  ```
135
135
 
136
136
  `#errors` is a map in which keys correspond to field names, and values are instances of
137
137
  `Foraneus::Error`.
138
138
 
139
139
  The name of the exception raised by `#parse` is the error's `key` attribute, and the exception's
140
- message is added to the error's `message` attribute.
140
+ message is set to the error's `message` attribute.
141
141
 
142
142
  Data coming from the inside is assumed to be valid, so `.raw` won't return an instance having
143
143
  errors neither being invalid.
@@ -152,15 +152,15 @@ Fields can be declared as required.
152
152
  end
153
153
  ```
154
154
 
155
- If an external value is not fed into a required field, an error with key 'KeyError' will be assigned.
155
+ If an external value is not fed into a required field, an error with key `KeyError` will be assigned.
156
156
 
157
157
  ``` ruby
158
158
  form = MyForm.parse
159
159
 
160
160
  form.valid? # => false
161
161
 
162
- form[:errors][:delay].key # => 'KeyError'
163
- form[:errors][:delay].message # => 'required parameter not found: "delay"'
162
+ form.errors[:delay].key # => 'KeyError'
163
+ form.errors[:delay].message # => 'required parameter not found: "delay"'
164
164
  ```
165
165
 
166
166
  ## Blank values
@@ -197,7 +197,8 @@ Parse data from the ouside:
197
197
  form = MyForm.parse
198
198
 
199
199
  form.name # => 'Alice'
200
- form[:name] # => nil, data from the outside don't include any value
200
+ form[:name] # => nil, because data from the outside
201
+ # don't include any value
201
202
  ```
202
203
 
203
204
  Convert values back from the inside:
@@ -206,7 +207,32 @@ Convert values back from the inside:
206
207
  form = MyForm.raw
207
208
 
208
209
  form[:name] # => 'Alice'
209
- form.name # => nil, data from the inside don't include any value
210
+ form.name # => nil, because data from the inside
211
+ # don't include any value
212
+ ```
213
+
214
+ ## Prevent name clashes
215
+
216
+ It is possible to rename methods `#errors` and `#data` so it will not conflict with defined fields.
217
+
218
+ ``` ruby
219
+ MyForm = Class.new(Foraneus) {
220
+ field :errors
221
+ field :data
222
+
223
+ accessors[:errors] = :non_clashing_errors
224
+ accessors[:data] = :non_clashing_data
225
+ }
226
+ ```
227
+
228
+ ``` ruby
229
+ form = MyForm.parse(:errors => 'some errors', :data => 'some data')
230
+
231
+ form.errors # => 'some errors'
232
+ form.data # => 'some data'
233
+
234
+ form.non_clashing_errors # []
235
+ form.non_clashing_data # { :errors => 'some errors', :data => 'some data' }
210
236
  ```
211
237
 
212
238
  ## Installation
@@ -219,10 +245,16 @@ Convert values back from the inside:
219
245
 
220
246
  ## Running tests
221
247
 
222
- Tests are written in RSpec. To run them all just execute the following from your command line:
248
+ Tests are written in MiniTest. To run them all just execute the following from your command line:
249
+
250
+ ``` shell
251
+ ruby spec/runner.rb
252
+ ```
253
+
254
+ To run a specific test case:
223
255
 
224
256
  ``` shell
225
- rspec
257
+ ruby -Ispec -Ilib spec/lib/foraneus_spec.rb
226
258
  ```
227
259
 
228
260
  ## Code documentation
@@ -11,15 +11,9 @@ require_relative 'foraneus/errors'
11
11
  class Foraneus
12
12
 
13
13
 
14
- # @return [Hash] Parsed data.
15
- attr_accessor :data
16
-
17
14
  # @api private
18
15
  def initialize
19
- @data = {}
20
- @raw_data = {}
21
-
22
- @errors = {}
16
+ @_ = {}
23
17
  end
24
18
 
25
19
  # Declares a boolean field.
@@ -102,13 +96,38 @@ class Foraneus
102
96
  @fields ||= {}
103
97
  end
104
98
 
99
+ def self.accessors
100
+ @accessors ||= {
101
+ :data => :data,
102
+ :errors => :errors
103
+ }
104
+ end
105
+
106
+ def self.create_instance
107
+ instance = self.new
108
+ spec = self
109
+
110
+ instance.singleton_class.send(:attr_reader, self.accessors[:data])
111
+
112
+ instance.instance_exec do
113
+ instance.instance_variable_set(:"@#{spec.accessors[:data]}", {})
114
+ end
115
+
116
+ instance.singleton_class.send(:attr_reader, self.accessors[:errors])
117
+ instance.instance_exec do
118
+ instance.instance_variable_set(:"@#{spec.accessors[:errors]}", {})
119
+ end
120
+
121
+ instance
122
+ end
123
+
105
124
  # Parses data coming from an external source.
106
125
  #
107
126
  # @param [Hash<Symbol, String>] data External data.
108
127
  #
109
128
  # @return [Foraneus] An instance of a form.
110
129
  def self.parse(data = {})
111
- instance = self.new
130
+ instance = self.create_instance
112
131
 
113
132
  parsed_keys = []
114
133
 
@@ -138,7 +157,7 @@ class Foraneus
138
157
  #
139
158
  # @return [Foraneus] An instance of a form.
140
159
  def self.raw(data = {})
141
- instance = self.new
160
+ instance = self.create_instance
142
161
 
143
162
  fields.each do |field, converter|
144
163
  given_key = field
@@ -161,7 +180,7 @@ class Foraneus
161
180
  end
162
181
 
163
182
  instance[given_key] = s
164
- instance.data[given_key] = v
183
+ instance.send(self.accessors[:data])[given_key] = v
165
184
  end
166
185
 
167
186
  instance
@@ -171,13 +190,11 @@ class Foraneus
171
190
  # @return [Array<Error>] errors when m == :errors.
172
191
  # @return [String] raw data value for the field m.
173
192
  def [](m = nil)
174
- if m == :errors
175
- @errors
176
- elsif m.nil?
177
- @raw_data
193
+ if m.nil?
194
+ @_
178
195
  else
179
- @raw_data.fetch(m) do
180
- @raw_data[m.to_s]
196
+ @_.fetch(m) do
197
+ @_[m.to_s]
181
198
  end
182
199
  end
183
200
  end
@@ -189,7 +206,10 @@ class Foraneus
189
206
  # @param [Symbol] k Field name.
190
207
  # @param [String] v Raw value.
191
208
  def []=(k, v)
192
- @raw_data[k] = v
209
+ #raw_data = @_
210
+
211
+ #raw_data[k] = v
212
+ @_[k] = v
193
213
  end
194
214
 
195
215
  # Returns true if no conversion errors occurred. false otherwise.
@@ -225,11 +245,11 @@ class Foraneus
225
245
  end
226
246
 
227
247
  foraneus.send("#{field}=", v)
228
- foraneus.data[k] = v
248
+ foraneus.send(self.accessors[:data])[k] = v
229
249
 
230
250
  rescue
231
251
  error = Foraneus::Error.new($!.class.name, $!.message)
232
- foraneus.instance_variable_get(:@errors)[k] = error
252
+ foraneus.send(self.accessors[:errors])[k] = error
233
253
  end
234
254
  private_class_method :__parse_raw_datum
235
255
 
@@ -16,7 +16,10 @@ class Foraneus
16
16
  @format = opts[:format] || DEFAULT_FORMAT
17
17
  end
18
18
 
19
- # return [Date]
19
+
20
+ # @raise [ArgumentError] with message 'invalid date'
21
+ #
22
+ # @return [Date]
20
23
  def parse(s)
21
24
  ::Date.strptime(s, @format)
22
25
  end
@@ -21,6 +21,8 @@ class Foraneus
21
21
  @separator = opts[:separator] || DEFAULT_SEPARATOR
22
22
  end
23
23
 
24
+ # @raise [ArgumentError] with message 'invalid value for Float(): ...'
25
+ #
24
26
  # @return [Float]
25
27
  def parse(s)
26
28
  integer_part, fractional_part = split(s)
@@ -13,6 +13,8 @@ class Foraneus
13
13
  @delimiter = opts[:delimiter]
14
14
  end
15
15
 
16
+ # @raise [ArgumentError] with message 'invalid value for Integer(): ...'
17
+ #
16
18
  # @return [Integer]
17
19
  def parse(s)
18
20
  s = s.gsub(@delimiter, '') if @delimiter
@@ -2,35 +2,37 @@ require 'spec_helper'
2
2
 
3
3
  describe Foraneus::Converters::Boolean do
4
4
 
5
+ let(:converter) { Foraneus::Converters::Boolean.new }
6
+
5
7
  describe '#parse' do
6
8
  it 'returns true with true' do
7
- parsed = subject.parse('true')
9
+ parsed = converter.parse('true')
8
10
 
9
- parsed.should be_true
11
+ assert_equal true, parsed
10
12
  end
11
13
 
12
14
  it 'returns false with sth else' do
13
- parsed = subject.parse('false')
15
+ parsed = converter.parse('false')
14
16
 
15
- parsed.should be_false
17
+ assert_equal false, parsed
16
18
  end
17
19
  end
18
20
 
19
21
  describe '#raw' do
20
22
  it 'returns "true" with true' do
21
- subject.raw(true).should eq('true')
23
+ assert_equal 'true', converter.raw(true)
22
24
  end
23
25
 
24
26
  it 'returns "false" with false' do
25
- subject.raw(false).should eq('false')
27
+ assert_equal 'false', converter.raw(false)
26
28
  end
27
29
 
28
30
  it 'returns "false" with nil' do
29
- subject.raw(nil).should eq('false')
31
+ assert_equal 'false', converter.raw(nil)
30
32
  end
31
33
 
32
34
  it 'returns "true" with everything else' do
33
- subject.raw(:default).should eq('true')
35
+ assert_equal 'true', converter.raw(:default)
34
36
  end
35
37
  end
36
38
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Foraneus::Converters::Date do
4
4
 
5
- subject(:converter) { Foraneus::Converters::Date.new }
5
+ let(:converter) { Foraneus::Converters::Date.new }
6
6
 
7
7
  describe '#parse' do
8
8
 
@@ -11,13 +11,13 @@ describe Foraneus::Converters::Date do
11
11
 
12
12
  result = converter.parse(s)
13
13
 
14
- result.year.should eq(2012)
15
- result.month.should eq(04)
16
- result.day.should eq(13)
14
+ assert_equal 2012, result.year
15
+ assert_equal 4, result.month
16
+ assert_equal 13, result.day
17
17
  end
18
18
 
19
- context 'when format is given' do
20
- subject(:converter) {
19
+ describe 'when format is given' do
20
+ let(:converter) {
21
21
  Foraneus::Converters::Date.new(:format => '%d/%m/%Y')
22
22
  }
23
23
 
@@ -26,32 +26,28 @@ describe Foraneus::Converters::Date do
26
26
 
27
27
  result = converter.parse(s)
28
28
 
29
- result.year.should eq(2012)
30
- result.month.should eq(04)
31
- result.day.should eq(13)
29
+ assert_equal 2012, result.year
30
+ assert_equal 4, result.month
31
+ assert_equal 13, result.day
32
32
  end
33
33
  end
34
34
  end
35
35
 
36
36
  describe '#raw' do
37
- let(:d) { Date.today }
37
+ let(:d) { Date.new(2012, 4, 13) }
38
38
 
39
39
  it 'returns a date representation' do
40
- s = d.strftime('%Y-%m-%d')
41
-
42
- converter.raw(d).should eq(s)
40
+ assert_equal '2012-04-13', converter.raw(d)
43
41
  end
44
42
 
45
- context 'when format is given' do
43
+ describe 'when format is given' do
46
44
  let(:format) { '%m/%d/%Y' }
47
- subject(:converter) {
45
+ let(:converter) {
48
46
  Foraneus::Converters::Date.new(:format => format)
49
47
  }
50
48
 
51
49
  it 'returns a date representation' do
52
- s = d.strftime(format)
53
-
54
- converter.raw(d).should eq(s)
50
+ assert_equal '04/13/2012', converter.raw(d)
55
51
  end
56
52
  end
57
53
  end
@@ -2,25 +2,25 @@ require 'spec_helper'
2
2
 
3
3
  describe Foraneus::Converters::Decimal do
4
4
 
5
- subject(:converter) { Foraneus::Converters::Decimal.new }
5
+ let(:converter) { Foraneus::Converters::Decimal.new }
6
6
 
7
7
  describe '#parse' do
8
8
  it 'parses a decimal representation' do
9
9
  s = '1234.56'
10
10
  n = BigDecimal.new('1234.56')
11
11
 
12
- converter.parse(s).should eq(n)
12
+ assert_equal n, converter.parse(s)
13
13
  end
14
14
 
15
15
  it 'parses a decimal representation when no integer part' do
16
16
  s = '.56'
17
17
  n = BigDecimal.new('0.56')
18
18
 
19
- converter.parse(s).should eq(n)
19
+ assert_equal n, converter.parse(s)
20
20
  end
21
21
 
22
- context 'when separator and delimiter are given' do
23
- subject(:converter) {
22
+ describe 'when separator and delimiter are given' do
23
+ let(:converter) {
24
24
  Foraneus::Converters::Decimal.new(:delimiter => '.', :separator => ',')
25
25
  }
26
26
 
@@ -28,14 +28,14 @@ describe Foraneus::Converters::Decimal do
28
28
  s = '1.234.567,89'
29
29
  n = BigDecimal.new('1234567.89')
30
30
 
31
- converter.parse(s).should eq(n)
31
+ assert_equal n, converter.parse(s)
32
32
  end
33
33
 
34
34
  it 'parses a decimal representation when no integer part' do
35
35
  s = ',56'
36
36
  n = BigDecimal.new('0.56')
37
37
 
38
- converter.parse(s).should eq(n)
38
+ assert_equal n, converter.parse(s)
39
39
  end
40
40
  end
41
41
  end
@@ -46,39 +46,39 @@ describe Foraneus::Converters::Decimal do
46
46
  it 'returns a decimal representation' do
47
47
  s = '1234567.89'
48
48
 
49
- converter.raw(n).should eq(s)
49
+ assert_equal s, converter.raw(n)
50
50
  end
51
51
 
52
- context 'when separator and delimiter are given' do
53
- subject(:converter) {
52
+ describe 'when separator and delimiter are given' do
53
+ let(:converter) {
54
54
  Foraneus::Converters::Decimal.new(:delimiter => '.', :separator => ',')
55
55
  }
56
56
 
57
57
  it 'returns a decimal representation' do
58
58
  s = '1.234.567,89'
59
59
 
60
- converter.raw(n).should eq(s)
60
+ assert_equal s, converter.raw(n)
61
61
  end
62
62
  end
63
63
 
64
- context 'when precision is given' do
65
- subject(:converter) {
64
+ describe 'when precision is given' do
65
+ let(:converter) {
66
66
  Foraneus::Converters::Decimal.new(:precision => 2)
67
67
  }
68
68
 
69
69
  it 'fills with zeros when value precision is smaller than converter precision' do
70
70
  n = BigDecimal.new('3.1')
71
- converter.raw(n).should eq('3.10')
71
+ assert_equal '3.10', converter.raw(n)
72
72
  end
73
73
 
74
74
  it 'does not affect the representation when precision and converter precision are both equal' do
75
75
  n = BigDecimal.new('3.14')
76
- converter.raw(n).should eq('3.14')
76
+ assert_equal '3.14', converter.raw(n)
77
77
  end
78
78
 
79
79
  it 'does not truncate the representation when precision is larger than converter precision' do
80
80
  n = BigDecimal.new('3.145')
81
- converter.raw(n).should eq('3.145')
81
+ assert_equal '3.145', converter.raw(n)
82
82
  end
83
83
  end
84
84
  end