valuable 0.8.2 → 0.8.4
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/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
|