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 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,13 @@
1
+ module MultiparameterAttributesHandler
2
+ VERSION = "0.0.1"
3
+ end
4
+
5
+ # History
6
+ # =======
7
+ #
8
+ # 0.0.1: First gem
9
+ # ----------------
10
+ #
11
+ # Released for testing and review of functionality.
12
+ #
13
+
@@ -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
@@ -0,0 +1,16 @@
1
+ require_relative '../lib/multiparameter_attributes_handler'
2
+
3
+ class Parent
4
+ attr_accessor :attributes
5
+ end
6
+
7
+
8
+ class Thing < Parent
9
+
10
+ include MultiparameterAttributesHandler
11
+
12
+ def initialize
13
+
14
+ end
15
+ end
16
+
@@ -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