valuable 0.8.2 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/valuable.rb +72 -12
- data/test/alias_test.rb +5 -0
- data/test/bad_attributes_test.rb +17 -1
- metadata +25 -8
data/lib/valuable.rb
CHANGED
@@ -42,13 +42,41 @@ class Valuable
|
|
42
42
|
# accepts an optional hash that will be used to populate the
|
43
43
|
# predefined attributes for this class.
|
44
44
|
def initialize(atts = nil)
|
45
|
-
atts
|
45
|
+
self.update_attributes(atts || {})
|
46
|
+
end
|
47
|
+
|
48
|
+
# mass assign attributes. This method will not clear any existing attributes.
|
49
|
+
#
|
50
|
+
# class Shoe
|
51
|
+
# has_value :size
|
52
|
+
# has_value :owner
|
53
|
+
# has_value :color, :default => 'red'
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# >> shoe = Shoe.new
|
57
|
+
# >> shoe.update_attributes(:size => 16, :owner => 'MJ')
|
58
|
+
# >> shoe.attributes
|
59
|
+
# => {:size => 16, :owner => 'MJ', :color => 'red'}
|
60
|
+
def update_attributes(atts)
|
61
|
+
atts.each{|name, value| __send__("#{name}=", value )}
|
46
62
|
end
|
47
63
|
|
48
64
|
def deep_duplicate_of(value)
|
49
65
|
Marshal.load(Marshal.dump(value))
|
50
66
|
end
|
51
67
|
|
68
|
+
def permissive?
|
69
|
+
self.class.permissive_constructor?
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(method_name, *args)
|
73
|
+
if method_name.to_s =~ /(\w+)=/
|
74
|
+
raise( ArgumentError, "#{self.class.to_s} does not have an attribute or alias '#{$1}'", caller) unless self.permissive?
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
52
80
|
class << self
|
53
81
|
|
54
82
|
# Returns an array of the attributes available on this object.
|
@@ -76,9 +104,7 @@ class Valuable
|
|
76
104
|
# :klass - light weight type casting. Use :integer, :string or
|
77
105
|
# :boolean. Alternately, supply a class.
|
78
106
|
#
|
79
|
-
# :alias - creates
|
80
|
-
# allows you to accept information from some other party using their
|
81
|
-
# vocabulary. Alias does not currently create a getter.
|
107
|
+
# :alias - creates an alias for getter and setter with the new name.
|
82
108
|
#
|
83
109
|
# When a :klassified attribute is set to some new value, if the value
|
84
110
|
# is not nil and is not already of that class, the value will be cast
|
@@ -107,8 +133,10 @@ class Valuable
|
|
107
133
|
create_question_for(name) if options[:klass] == :boolean
|
108
134
|
create_negative_question_for(name, options[:negative]) if options[:klass] == :boolean && options[:negative]
|
109
135
|
|
110
|
-
create_setter_for(name,
|
111
|
-
|
136
|
+
create_setter_for(name, options[:klass])
|
137
|
+
|
138
|
+
alias_method options[:alias], name if options[:alias]
|
139
|
+
alias_method "#{options[:alias]}=", "#{name}=" if options[:alias]
|
112
140
|
|
113
141
|
check_options_validity(name, options)
|
114
142
|
end
|
@@ -117,38 +145,39 @@ class Valuable
|
|
117
145
|
# is called both by the constructor. The constructor handles type
|
118
146
|
# casting. Setting values via the attributes hash avoids the method
|
119
147
|
# defined here.
|
120
|
-
def create_setter_for(attribute,
|
148
|
+
def create_setter_for(attribute, klass)
|
149
|
+
setter_method = "#{attribute}="
|
121
150
|
|
122
151
|
case klass
|
123
152
|
when NilClass
|
124
153
|
|
125
|
-
define_method
|
154
|
+
define_method setter_method do |value|
|
126
155
|
attributes[attribute] = value
|
127
156
|
end
|
128
157
|
|
129
158
|
when :integer
|
130
159
|
|
131
|
-
define_method
|
160
|
+
define_method setter_method do |value|
|
132
161
|
value_as_integer = value && value.to_i
|
133
162
|
attributes[attribute] = value_as_integer
|
134
163
|
end
|
135
164
|
|
136
165
|
when :string
|
137
166
|
|
138
|
-
define_method
|
167
|
+
define_method setter_method do |value|
|
139
168
|
value_as_string = value && value.to_s
|
140
169
|
attributes[attribute] = value_as_string
|
141
170
|
end
|
142
171
|
|
143
172
|
when :boolean
|
144
173
|
|
145
|
-
define_method
|
174
|
+
define_method setter_method do |value|
|
146
175
|
attributes[attribute] = value == '0' ? false : !!value
|
147
176
|
end
|
148
177
|
|
149
178
|
else
|
150
179
|
|
151
|
-
define_method
|
180
|
+
define_method setter_method do |value|
|
152
181
|
if value.nil?
|
153
182
|
attributes[attribute] = nil
|
154
183
|
elsif value.is_a? klass
|
@@ -215,6 +244,37 @@ class Valuable
|
|
215
244
|
has_value(name, :default => [] )
|
216
245
|
end
|
217
246
|
|
247
|
+
# Instructs the class NOT to complain if any attributes are set
|
248
|
+
# that haven't been declared.
|
249
|
+
#
|
250
|
+
# class Sphere < Valuable
|
251
|
+
# has_value :material
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# >> Sphere.new(:radius => 3, :material => 'water')
|
255
|
+
# EXCEPTION! OH NOS!
|
256
|
+
#
|
257
|
+
# class Box < Valuable
|
258
|
+
# acts_as_permissive
|
259
|
+
#
|
260
|
+
# has_value :material
|
261
|
+
# end
|
262
|
+
#
|
263
|
+
# >> box = Box.new(:material => 'wood', :size => '36 x 40')
|
264
|
+
# >> box.attributes
|
265
|
+
# => {:material => 'wood'}
|
266
|
+
def acts_as_permissive
|
267
|
+
self.permissive_constructor=true
|
268
|
+
end
|
269
|
+
|
270
|
+
def permissive_constructor=(value)
|
271
|
+
@_permissive_constructor = value
|
272
|
+
end
|
273
|
+
|
274
|
+
def permissive_constructor?
|
275
|
+
!!(@_permissive_constructor ||= false)
|
276
|
+
end
|
277
|
+
|
218
278
|
private
|
219
279
|
|
220
280
|
def inherited(child)
|
data/test/alias_test.rb
CHANGED
@@ -19,4 +19,9 @@ class AliasTest < Test::Unit::TestCase
|
|
19
19
|
software = Software.new('EnterpriseNamespace' => 'Enterprisey')
|
20
20
|
assert_equal 'Enterprisey', software.enterprise_namespace
|
21
21
|
end
|
22
|
+
|
23
|
+
def test_that_aliases_work_for_getters
|
24
|
+
software = Software.new(:title => 'ObtrusiveJavascriptComponent')
|
25
|
+
assert_equal 'ObtrusiveJavascriptComponent', software.name
|
26
|
+
end
|
22
27
|
end
|
data/test/bad_attributes_test.rb
CHANGED
@@ -2,7 +2,6 @@ $: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'valuable.rb'
|
5
|
-
require 'mocha'
|
6
5
|
|
7
6
|
class Infrastructure < Valuable
|
8
7
|
end
|
@@ -20,4 +19,21 @@ class BadAttributesTest < Test::Unit::TestCase
|
|
20
19
|
Infrastructure.has_value :bar, :klass => Integer
|
21
20
|
end
|
22
21
|
end
|
22
|
+
|
23
|
+
def test_that_invalid_attributes_raise
|
24
|
+
assert_raises ArgumentError do
|
25
|
+
model = Class.new(Valuable)
|
26
|
+
model.new(:invalid => 'should not be allowed')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_that_invalid_attributes_can_be_ignored
|
31
|
+
assert_nothing_raised do
|
32
|
+
model = Class.new(Valuable) do
|
33
|
+
acts_as_permissive
|
34
|
+
end
|
35
|
+
model.new(:invalid => 'should be ignored')
|
36
|
+
end
|
37
|
+
end
|
23
38
|
end
|
39
|
+
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valuable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 55
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 4
|
10
|
+
version: 0.8.4
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Johnathon Wright
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-10-06 00:00:00 -05:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -25,6 +31,11 @@ files:
|
|
25
31
|
- lib/valuable.rb
|
26
32
|
- README.markdown
|
27
33
|
- rakefile.rb
|
34
|
+
- test/bad_attributes_test.rb
|
35
|
+
- test/alias_test.rb
|
36
|
+
- test/inheritance_test.rb
|
37
|
+
- test/deprecated_test.rb
|
38
|
+
- test/valuable_test.rb
|
28
39
|
has_rdoc: true
|
29
40
|
homepage: http://valuable.mustmodify.com
|
30
41
|
licenses: []
|
@@ -35,27 +46,33 @@ rdoc_options: []
|
|
35
46
|
require_paths:
|
36
47
|
- lib
|
37
48
|
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
38
50
|
requirements:
|
39
51
|
- - ">="
|
40
52
|
- !ruby/object:Gem::Version
|
53
|
+
hash: 3
|
54
|
+
segments:
|
55
|
+
- 0
|
41
56
|
version: "0"
|
42
|
-
version:
|
43
57
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
44
59
|
requirements:
|
45
60
|
- - ">="
|
46
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
47
65
|
version: "0"
|
48
|
-
version:
|
49
66
|
requirements: []
|
50
67
|
|
51
68
|
rubyforge_project: valuable
|
52
|
-
rubygems_version: 1.3.
|
69
|
+
rubygems_version: 1.3.7
|
53
70
|
signing_key:
|
54
71
|
specification_version: 3
|
55
72
|
summary: attr_accessor on steroids with defaults, constructor, and light casting.
|
56
73
|
test_files:
|
57
|
-
- test/inheritance_test.rb
|
58
|
-
- test/valuable_test.rb
|
59
74
|
- test/bad_attributes_test.rb
|
60
|
-
- test/deprecated_test.rb
|
61
75
|
- test/alias_test.rb
|
76
|
+
- test/inheritance_test.rb
|
77
|
+
- test/deprecated_test.rb
|
78
|
+
- test/valuable_test.rb
|