multiparameter_attributes_handler 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +85 -0
- data/Rakefile +18 -0
- data/lib/multiparameter_attributes_handler.rb +9 -0
- data/lib/multiparameter_attributes_handler/manipulator.rb +120 -0
- data/lib/multiparameter_attributes_handler/multiparameter_attributes_handler_error.rb +29 -0
- data/lib/multiparameter_attributes_handler/version.rb +13 -0
- data/test/multiparameter_attributes_handler/manipulator_test.rb +85 -0
- data/test/multiparameter_attributes_handler/multiparameter_attributes_handler_error_test.rb +28 -0
- data/test/thing.rb +16 -0
- data/test/thing_test.rb +183 -0
- metadata +62 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Rob Nichols
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
== Multiparameter Attributes Handler
|
2
|
+
|
3
|
+
=== Background
|
4
|
+
|
5
|
+
Rails form helpers for time, datetime and date return multiparameter attributes
|
6
|
+
that ActiveRecord objects are able to convert into parent attributes.
|
7
|
+
|
8
|
+
For example
|
9
|
+
|
10
|
+
date_select(:thing, :last_read)
|
11
|
+
|
12
|
+
when set to 24th June 2004, will generate
|
13
|
+
|
14
|
+
'thing' => {
|
15
|
+
"last_read(1i)" => "2004",
|
16
|
+
"last_read(2i)" => "6",
|
17
|
+
"last_read(3i)" => "24"
|
18
|
+
}
|
19
|
+
|
20
|
+
ActiveRecord understands this and converts these key/value pairs into a date
|
21
|
+
object that is passed to thing.last_record=
|
22
|
+
|
23
|
+
=== A solution without ActiveRecord
|
24
|
+
|
25
|
+
Multiparameter Attributes Handler allows other objects to do the same. In
|
26
|
+
particular, ActiveResource models.
|
27
|
+
|
28
|
+
It does this by modifying the way attributes= works. So for the above example,
|
29
|
+
the values passed down the attributes= chain gets converted to:
|
30
|
+
|
31
|
+
'thing' => {
|
32
|
+
"last_read(1i)" => "2004",
|
33
|
+
"last_read(2i)" => "6",
|
34
|
+
"last_read(3i)" => "24",
|
35
|
+
"last_read" => Time.local('2004', '6', '24')
|
36
|
+
}
|
37
|
+
|
38
|
+
So for a ActiveResource Thing, this functionality is added like this:
|
39
|
+
|
40
|
+
class Thing < ActiveResource::Base
|
41
|
+
include MultiparameterAttributesHandler
|
42
|
+
end
|
43
|
+
|
44
|
+
=== Only setter affected
|
45
|
+
|
46
|
+
Note that this gem provides handling of the parameters received from the form
|
47
|
+
submission. For the form helpers to work, they need to passed a date or time
|
48
|
+
to the form.
|
49
|
+
|
50
|
+
One solution is to over-ride the getter in the model. So for the Thing example
|
51
|
+
above, the complete solution would look like this:
|
52
|
+
|
53
|
+
require 'date'
|
54
|
+
class Thing < ActiveResource::Base
|
55
|
+
include MultiparameterAttributesHandler
|
56
|
+
|
57
|
+
def last_read
|
58
|
+
Date.parse(super)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Rails form date helpers will then work for last_read:
|
63
|
+
|
64
|
+
date_select(:thing, :last_read)
|
65
|
+
|
66
|
+
And in the controller's create and update methods:
|
67
|
+
|
68
|
+
thing.attributes = params[:thing]
|
69
|
+
|
70
|
+
Or
|
71
|
+
|
72
|
+
Thing.new(params[:thing])
|
73
|
+
|
74
|
+
Or
|
75
|
+
|
76
|
+
thing.update_attributes(params[:thing])
|
77
|
+
|
78
|
+
|
79
|
+
=== Installation
|
80
|
+
|
81
|
+
This functionality is made available via the multiparameter_attributes_handler
|
82
|
+
gem. So add this to your gemfile:
|
83
|
+
|
84
|
+
gem 'multiparameter_attributes_handler'
|
85
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'rake/testtask'
|
6
|
+
|
7
|
+
Rake::RDocTask.new do |rdoc|
|
8
|
+
files =['README.rdoc', 'MIT-LICENSE', 'lib/**/*.rb']
|
9
|
+
rdoc.rdoc_files.add(files)
|
10
|
+
rdoc.main = "README.rdoc" # page to start on
|
11
|
+
rdoc.title = "MultiparameterAttributesHandler Docs"
|
12
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
13
|
+
rdoc.options << '--line-numbers'
|
14
|
+
end
|
15
|
+
|
16
|
+
Rake::TestTask.new do |t|
|
17
|
+
t.test_files = FileList['test/**/*.rb']
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative 'multiparameter_attributes_handler/manipulator'
|
2
|
+
require_relative 'multiparameter_attributes_handler/multiparameter_attributes_handler_error'
|
3
|
+
module MultiparameterAttributesHandler
|
4
|
+
|
5
|
+
def attributes=(new_attributes)
|
6
|
+
super Manipulator.new(new_attributes).output
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module MultiparameterAttributesHandler
|
2
|
+
class Manipulator
|
3
|
+
|
4
|
+
attr_accessor :hash
|
5
|
+
|
6
|
+
def initialize(hash)
|
7
|
+
@hash = hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def multiparameters
|
11
|
+
keys = multiparameter_keys.collect do |k|
|
12
|
+
k.gsub(ends_with_number_letter_in_brackets, "")
|
13
|
+
end
|
14
|
+
keys.uniq!
|
15
|
+
keys.delete_if{|k| empty_date_values_for? k}
|
16
|
+
return keys
|
17
|
+
end
|
18
|
+
|
19
|
+
def values_for(multiparameter)
|
20
|
+
return hash[multiparameter] unless multiparameters.include? multiparameter
|
21
|
+
keys_for(multiparameter).collect{|k| hash[k]}
|
22
|
+
end
|
23
|
+
|
24
|
+
def value_of(multiparameter)
|
25
|
+
values = values_for(multiparameter)
|
26
|
+
return values unless values.kind_of? Array
|
27
|
+
convert_to_time(multiparameter, values)
|
28
|
+
end
|
29
|
+
|
30
|
+
def output
|
31
|
+
begin
|
32
|
+
multiparameters.each do |multiparameter|
|
33
|
+
hash[multiparameter] = value_of(multiparameter)
|
34
|
+
end
|
35
|
+
rescue => e
|
36
|
+
errors << e
|
37
|
+
end
|
38
|
+
return hash if errors.empty?
|
39
|
+
raise_combined_error(errors)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def convert_to_time(multiparameter, values)
|
44
|
+
begin
|
45
|
+
Time.local(*values)
|
46
|
+
rescue => e
|
47
|
+
msg = "Error determining value_of #{multiparameter} from #{values} (#{e.message})"
|
48
|
+
raise_assignment_errors(multiparameter, values, msg, e)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def multiparameter_keys
|
53
|
+
hash.keys.select{|k| k =~ ends_with_number_letter_in_brackets}
|
54
|
+
end
|
55
|
+
|
56
|
+
def ends_with_number_letter_in_brackets
|
57
|
+
/\(\d+\w+\)$/
|
58
|
+
end
|
59
|
+
|
60
|
+
def keys_for(multiparameter)
|
61
|
+
keys = multiparameter_keys.select{|k| /^#{multiparameter}\(/ =~ k}
|
62
|
+
add_missing_keys_for(multiparameter, keys)
|
63
|
+
return keys.sort if sequence_starting_at_one?(keys)
|
64
|
+
|
65
|
+
raise_assignment_errors(
|
66
|
+
multiparameter,
|
67
|
+
keys,
|
68
|
+
"key number sequence incomplete or not starting at one"
|
69
|
+
)
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_missing_keys_for(multiparameter, keys)
|
74
|
+
postscript = characters_after_sequence_number(keys.first)
|
75
|
+
numbers = sequence_numbers(keys)
|
76
|
+
(1..numbers.last).each do |number|
|
77
|
+
next if number < 3 # don't replace missing date keys
|
78
|
+
next if numbers.include? number
|
79
|
+
key = "#{multiparameter}(#{number}#{postscript})"
|
80
|
+
hash[key] = '00'
|
81
|
+
keys << key
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def characters_after_sequence_number(sample_key)
|
86
|
+
match = sample_key.match(/\(\d+(\w*)\)/)
|
87
|
+
match ? match[1] : ""
|
88
|
+
end
|
89
|
+
|
90
|
+
def empty_date_values_for?(multiparameter)
|
91
|
+
keys = keys_for(multiparameter)[0..2].select{|p| hash[p].empty?}
|
92
|
+
!keys.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def sequence_starting_at_one?(keys)
|
96
|
+
numbers = sequence_numbers(keys)
|
97
|
+
expected = (1..10).to_a
|
98
|
+
numbers == expected[0..(numbers.length - 1)]
|
99
|
+
end
|
100
|
+
|
101
|
+
def sequence_numbers(keys)
|
102
|
+
keys.collect{|k| m = k.match(/\((\d+)\w+\)/); m ? m[1].to_i : nil}.sort
|
103
|
+
end
|
104
|
+
|
105
|
+
def errors
|
106
|
+
@errors ||= []
|
107
|
+
end
|
108
|
+
|
109
|
+
def raise_assignment_errors(multiparameter, values, message, error = StandardError)
|
110
|
+
msg = "Error determining value_of #{multiparameter} from #{values} (#{message})"
|
111
|
+
raise AttributeAssignmentError.new(error, multiparameter), msg
|
112
|
+
end
|
113
|
+
|
114
|
+
def raise_combined_error(errors)
|
115
|
+
error_descriptions = errors.collect { |ex| ex.message }.join(",")
|
116
|
+
msg = "#{errors.size} error(s) on determining value of multiparameter attributes [#{error_descriptions}]"
|
117
|
+
raise MultiparameterAssignmentErrors.new(errors), msg
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module MultiparameterAttributesHandler
|
3
|
+
|
4
|
+
class MultiparameterAttributesHandlerError < StandardError
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
# Raised when an error occurred while doing a mass assignment to an attribute through the
|
9
|
+
# <tt>attributes=</tt> method. The exception has an +attribute_name+ property that is
|
10
|
+
# the name of the offending attribute.
|
11
|
+
class AttributeAssignmentError < MultiparameterAttributesHandlerError
|
12
|
+
attr_reader :exception_raised, :attribute_name
|
13
|
+
def initialize(exception_raised, attribute_name)
|
14
|
+
@exception_raised = exception_raised
|
15
|
+
@attribute_name = attribute_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Raised when there are multiple errors while doing a mass assignment through the +attributes+
|
20
|
+
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
|
21
|
+
# objects, each corresponding to the error while assigning to an attribute.
|
22
|
+
class MultiparameterAssignmentErrors < MultiparameterAttributesHandlerError
|
23
|
+
attr_reader :errors
|
24
|
+
def initialize(errors)
|
25
|
+
@errors = errors
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require_relative '../../lib/multiparameter_attributes_handler'
|
8
|
+
|
9
|
+
module MultiparameterAttributesHandler
|
10
|
+
class ManipulatorTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@hash = {
|
14
|
+
"last_read(1i)" => "2004",
|
15
|
+
"last_read(2i)" => "6",
|
16
|
+
"last_read(3i)" => "24",
|
17
|
+
"other(1i)" => "2012",
|
18
|
+
"other(2i)" => "2",
|
19
|
+
"other(3i)" => "2",
|
20
|
+
"other(4i)" => "11",
|
21
|
+
"other(5i)" => "35",
|
22
|
+
"foo" => 'bar',
|
23
|
+
"something" => 'ho',
|
24
|
+
"something_else" => 'hum'
|
25
|
+
}
|
26
|
+
@original = @hash.clone
|
27
|
+
@manipulator = Manipulator.new(@hash)
|
28
|
+
@output = @manipulator.output
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_multiparameters
|
32
|
+
assert_equal(['last_read', 'other'], @manipulator.multiparameters)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_values_for
|
36
|
+
assert_equal(@hash['foo'], @manipulator.values_for('foo'))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_values_for_multiparameter
|
40
|
+
assert_equal(['2004', '6', '24'], @manipulator.values_for('last_read'))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_value_of
|
44
|
+
assert_equal(@hash['foo'], @manipulator.value_of('foo'))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_value_of_multiparameter
|
48
|
+
assert_equal(Time.local(*@manipulator.values_for('last_read')), @manipulator.value_of('last_read'))
|
49
|
+
assert_equal(Time.local(*@manipulator.values_for('other')), @manipulator.value_of('other'))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_output_returns_original_content
|
53
|
+
@hash.each do |key, value|
|
54
|
+
assert_equal(value, @output[key])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_output_returns_multiparameter_content_and_original_content
|
59
|
+
combined_length = @original.length + @manipulator.multiparameters.length
|
60
|
+
assert_equal(combined_length, @output.length)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_output_returns_multiparameter_content
|
64
|
+
@manipulator.multiparameters.each do |multiparameter|
|
65
|
+
assert_equal(@manipulator.value_of(multiparameter), @output[multiparameter])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_output_manipulates_hash
|
70
|
+
assert_not_equal(@original, @hash)
|
71
|
+
assert_equal(@output, @hash)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_partial_multiparameters_are_ignored
|
75
|
+
[
|
76
|
+
{"last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => ""},
|
77
|
+
{"last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "24"},
|
78
|
+
{"last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "24"}
|
79
|
+
].each do |params|
|
80
|
+
assert_equal([], Manipulator.new(params).multiparameters, "#{params.inspect} should return []")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require_relative '../../lib/multiparameter_attributes_handler'
|
8
|
+
|
9
|
+
module MultiparameterAttributesHandler
|
10
|
+
class MultiparameterAttributesHandlerErrorTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def test_error
|
13
|
+
assert_raise RuntimeError do
|
14
|
+
raise "Oh yes"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_attribute_assignment_error
|
19
|
+
error = assert_raise AttributeAssignmentError do
|
20
|
+
raise AttributeAssignmentError.new('b', 'c'), 'd'
|
21
|
+
end
|
22
|
+
assert_equal('d', error.message)
|
23
|
+
assert_equal('b', error.exception_raised)
|
24
|
+
assert_equal('c', error.attribute_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/test/thing.rb
ADDED
data/test/thing_test.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'date'
|
5
|
+
require_relative 'thing'
|
6
|
+
|
7
|
+
class ThingTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@thing = Thing.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_multiparameter_attributes_on_date
|
14
|
+
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" }
|
15
|
+
@thing.attributes = attributes
|
16
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
17
|
+
# treats dates/times the same
|
18
|
+
assert_equal Time.local(2004, 6, 24), @thing.attributes['last_read']
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_multiparameter_attributes_on_date_with_empty_year
|
22
|
+
attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "24" }
|
23
|
+
@thing.attributes = attributes
|
24
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
25
|
+
# treats dates/times the same
|
26
|
+
assert_nil @thing.attributes['last_read']
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_multiparameter_attributes_on_date_with_empty_month
|
30
|
+
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "24" }
|
31
|
+
@thing.attributes = attributes
|
32
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
33
|
+
# treats dates/times the same
|
34
|
+
assert_nil @thing.attributes['last_read']
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_multiparameter_attributes_on_date_with_empty_day
|
38
|
+
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" }
|
39
|
+
@thing.attributes = attributes
|
40
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
41
|
+
# treats dates/times the same
|
42
|
+
assert_nil @thing.attributes['last_read']
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_multiparameter_attributes_on_date_with_empty_day_and_year
|
46
|
+
attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "" }
|
47
|
+
@thing.attributes = attributes
|
48
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
49
|
+
# treats dates/times the same
|
50
|
+
assert_nil @thing.attributes['last_read']
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_multiparameter_attributes_on_date_with_empty_day_and_month
|
54
|
+
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "" }
|
55
|
+
@thing.attributes = attributes
|
56
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
57
|
+
# treats dates/times the same
|
58
|
+
assert_nil @thing.attributes['last_read']
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_multiparameter_attributes_on_date_with_empty_year_and_month
|
62
|
+
attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "24" }
|
63
|
+
@thing.attributes = attributes
|
64
|
+
# note that extra #to_date call allows test to pass for Oracle, which
|
65
|
+
# treats dates/times the same
|
66
|
+
assert_nil @thing.attributes['last_read']
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_multiparameter_attributes_on_date_with_all_empty
|
70
|
+
attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "" }
|
71
|
+
@thing.attributes = attributes
|
72
|
+
assert_nil @thing.attributes['last_read']
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_multiparameter_attributes_on_time
|
76
|
+
attributes = {
|
77
|
+
"written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24",
|
78
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => "00"
|
79
|
+
}
|
80
|
+
@thing.attributes = attributes
|
81
|
+
assert_equal Time.local(2004, 6, 24, 16, 24, 0), @thing.attributes['written_on']
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_multiparameter_attributes_on_time_with_no_date
|
85
|
+
ex = assert_raise(MultiparameterAttributesHandler::MultiparameterAssignmentErrors) do
|
86
|
+
attributes = {
|
87
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => "00"
|
88
|
+
}
|
89
|
+
@thing.attributes = attributes
|
90
|
+
end
|
91
|
+
assert_equal("written_on", ex.errors[0].attribute_name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_multiparameter_attributes_on_time_with_invalid_time_params
|
95
|
+
ex = assert_raise(MultiparameterAttributesHandler::MultiparameterAssignmentErrors) do
|
96
|
+
attributes = {
|
97
|
+
"written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24",
|
98
|
+
"written_on(4i)" => "2004", "written_on(5i)" => "36", "written_on(6i)" => "64",
|
99
|
+
}
|
100
|
+
@thing.attributes = attributes
|
101
|
+
end
|
102
|
+
assert_equal("written_on", ex.errors[0].attribute_name)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_multiparameter_attributes_on_time_with_old_date
|
106
|
+
attributes = {
|
107
|
+
"written_on(1i)" => "1850", "written_on(2i)" => "6", "written_on(3i)" => "24",
|
108
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => "00"
|
109
|
+
}
|
110
|
+
@thing.attributes = attributes
|
111
|
+
# testing against to_s(:db) representation because either a Time or a DateTime might be returned, depending on platform
|
112
|
+
assert_equal "1850-06-24 16:24:00", @thing.attributes['written_on'].strftime("%Y-%m-%d %H:%M:%S")
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_multiparameter_attributes_on_time_will_raise_on_big_time_if_missing_date_parts
|
116
|
+
ex = assert_raise(MultiparameterAttributesHandler::MultiparameterAssignmentErrors) do
|
117
|
+
attributes = {
|
118
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24"
|
119
|
+
}
|
120
|
+
@thing.attributes = attributes
|
121
|
+
end
|
122
|
+
assert_equal("written_on", ex.errors[0].attribute_name)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_multiparameter_attributes_on_time_with_raise_on_small_time_if_missing_date_parts
|
126
|
+
ex = assert_raise(MultiparameterAttributesHandler::MultiparameterAssignmentErrors) do
|
127
|
+
attributes = {
|
128
|
+
"written_on(4i)" => "16", "written_on(5i)" => "12", "written_on(6i)" => "02"
|
129
|
+
}
|
130
|
+
@thing.attributes = attributes
|
131
|
+
end
|
132
|
+
assert_equal("written_on", ex.errors[0].attribute_name)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_multiparameter_attributes_on_time_will_ignore_hour_if_missing
|
136
|
+
attributes = {
|
137
|
+
"written_on(1i)" => "2004", "written_on(2i)" => "12", "written_on(3i)" => "12",
|
138
|
+
"written_on(5i)" => "12", "written_on(6i)" => "02"
|
139
|
+
}
|
140
|
+
@thing.attributes = attributes
|
141
|
+
assert_equal Time.local(2004, 12, 12, 0, 12, 2), @thing.attributes['written_on']
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_multiparameter_attributes_on_time_will_ignore_hour_if_blank
|
145
|
+
attributes = {
|
146
|
+
"written_on(1i)" => "", "written_on(2i)" => "", "written_on(3i)" => "",
|
147
|
+
"written_on(4i)" => "", "written_on(5i)" => "12", "written_on(6i)" => "02"
|
148
|
+
}
|
149
|
+
@thing.attributes = attributes
|
150
|
+
assert_nil @thing.attributes['written_on']
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_multiparameter_attributes_on_time_will_ignore_date_if_empty
|
154
|
+
attributes = {
|
155
|
+
"written_on(1i)" => "", "written_on(2i)" => "", "written_on(3i)" => "",
|
156
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24"
|
157
|
+
}
|
158
|
+
|
159
|
+
@thing.attributes = attributes
|
160
|
+
assert_nil @thing.attributes['written_on']
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_multiparameter_attributes_on_time_with_seconds_will_ignore_date_if_empty
|
164
|
+
attributes = {
|
165
|
+
"written_on(1i)" => "", "written_on(2i)" => "", "written_on(3i)" => "",
|
166
|
+
"written_on(4i)" => "16", "written_on(5i)" => "12", "written_on(6i)" => "02"
|
167
|
+
}
|
168
|
+
|
169
|
+
@thing.attributes = attributes
|
170
|
+
assert_nil @thing.attributes['written_on']
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_multiparameter_attributes_on_time_with_empty_seconds
|
174
|
+
attributes = {
|
175
|
+
"written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24",
|
176
|
+
"written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => ""
|
177
|
+
}
|
178
|
+
|
179
|
+
@thing.attributes = attributes
|
180
|
+
assert_equal Time.local(2004, 6, 24, 16, 24, 0), @thing.attributes['written_on']
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multiparameter_attributes_handler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rob Nichols
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Rails forms helpers for date and time fields generate multiparameter
|
15
|
+
params. multiparameter_attributes_handler allows objects to assign these to thier
|
16
|
+
attributes,
|
17
|
+
email:
|
18
|
+
- rob@undervale.co.uk
|
19
|
+
executables: []
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- lib/multiparameter_attributes_handler/version.rb
|
24
|
+
- lib/multiparameter_attributes_handler/manipulator.rb
|
25
|
+
- lib/multiparameter_attributes_handler/multiparameter_attributes_handler_error.rb
|
26
|
+
- lib/multiparameter_attributes_handler.rb
|
27
|
+
- MIT-LICENSE
|
28
|
+
- Rakefile
|
29
|
+
- README.rdoc
|
30
|
+
- test/thing.rb
|
31
|
+
- test/multiparameter_attributes_handler/multiparameter_attributes_handler_error_test.rb
|
32
|
+
- test/multiparameter_attributes_handler/manipulator_test.rb
|
33
|
+
- test/thing_test.rb
|
34
|
+
homepage: https://github.com/reggieb/multiparameter_attributes_handler
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.24
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Allows objects with attributes, to handle multiparameter params
|
58
|
+
test_files:
|
59
|
+
- test/thing.rb
|
60
|
+
- test/multiparameter_attributes_handler/multiparameter_attributes_handler_error_test.rb
|
61
|
+
- test/multiparameter_attributes_handler/manipulator_test.rb
|
62
|
+
- test/thing_test.rb
|