smart_properties 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -6
- data/Gemfile +0 -5
- data/lib/smart_properties.rb +98 -15
- data/smart_properties.gemspec +2 -3
- data/spec/smart_properties_spec.rb +187 -80
- data/spec/support/smart_property_matcher.rb +3 -2
- metadata +16 -31
- data/Guardfile +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc4ce42b18d87c6229dea25608b8ce54644c8636
|
4
|
+
data.tar.gz: b61cfb33f7f076cd850b52fb897d17df583d5edf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58e549c46b5df6313e6ee70f8580d66aeeb394d3994cf0f2f6ea04461610fe24d861cd8a6c0476eef59bfebfd8bb79f7610784548d45874eb133c9b774d7e1b0
|
7
|
+
data.tar.gz: c0ec2fa2fdcb86cc1ac57b8e6cd3b3343af2333b2c66672172c4297e18f290ba15661d5772ea48379ff7f15daed8d75eae23d01670daa9b2c0d3f7df6b7e4f0d
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/lib/smart_properties.rb
CHANGED
@@ -21,10 +21,95 @@
|
|
21
21
|
# :required => true
|
22
22
|
#
|
23
23
|
module SmartProperties
|
24
|
+
VERSION = "1.5.0"
|
24
25
|
|
25
|
-
|
26
|
+
class Error < ::ArgumentError; end
|
27
|
+
class ConfigurationError < Error; end
|
28
|
+
|
29
|
+
class AssignmentError < Error
|
30
|
+
attr_accessor :sender
|
31
|
+
attr_accessor :property
|
32
|
+
|
33
|
+
def initialize(sender, property, message)
|
34
|
+
@sender = sender
|
35
|
+
@property = property
|
36
|
+
super(message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class MissingValueError < AssignmentError
|
41
|
+
def initialize(sender, property)
|
42
|
+
super(
|
43
|
+
sender,
|
44
|
+
property,
|
45
|
+
"%s requires the property %s to be set" % [
|
46
|
+
sender.class.name,
|
47
|
+
property.name
|
48
|
+
]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_hash
|
53
|
+
Hash[property.name, "must be set"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class InvalidValueError < AssignmentError
|
58
|
+
attr_accessor :value
|
59
|
+
|
60
|
+
def initialize(sender, property, value)
|
61
|
+
@value = value
|
62
|
+
super(
|
63
|
+
sender,
|
64
|
+
property,
|
65
|
+
"%s does not accept %p as value for the property %s" % [
|
66
|
+
sender.class.name,
|
67
|
+
value,
|
68
|
+
property.name
|
69
|
+
]
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_hash
|
74
|
+
Hash[property.name, "does not accept %p as value" % value]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class InitializationError < Error
|
79
|
+
attr_accessor :sender
|
80
|
+
attr_accessor :properties
|
81
|
+
|
82
|
+
def initialize(sender, properties)
|
83
|
+
@sender = sender
|
84
|
+
@properties = properties
|
85
|
+
super(
|
86
|
+
"%s requires the following properties to be set: %s" % [
|
87
|
+
sender.class.name,
|
88
|
+
properties.map(&:name).sort.join(', ')
|
89
|
+
]
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_hash
|
94
|
+
properties.each_with_object({}) { |property, errors| errors[property.name] = "must be set" }
|
95
|
+
end
|
96
|
+
end
|
26
97
|
|
27
98
|
class Property
|
99
|
+
# Defines the two index methods #[] and #[]=. This module will be included
|
100
|
+
# in the SmartProperties method scope.
|
101
|
+
module IndexMethods
|
102
|
+
def [](name)
|
103
|
+
return if name.nil?
|
104
|
+
name &&= name.to_sym
|
105
|
+
public_send(name) if self.class.properties.key?(name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def []=(name, value)
|
109
|
+
return if name.nil?
|
110
|
+
public_send(:"#{name.to_sym}=", value) if self.class.properties.key?(name)
|
111
|
+
end
|
112
|
+
end
|
28
113
|
|
29
114
|
attr_reader :name
|
30
115
|
attr_reader :converter
|
@@ -40,7 +125,7 @@ module SmartProperties
|
|
40
125
|
@required = attrs.delete(:required)
|
41
126
|
|
42
127
|
unless attrs.empty?
|
43
|
-
raise
|
128
|
+
raise ConfigurationError, "SmartProperties do not support the following configuration options: #{attrs.keys.map { |m| m.to_s }.sort.join(', ')}."
|
44
129
|
end
|
45
130
|
end
|
46
131
|
|
@@ -69,16 +154,9 @@ module SmartProperties
|
|
69
154
|
end
|
70
155
|
|
71
156
|
def prepare(value, scope)
|
72
|
-
if required?(scope) && value.nil?
|
73
|
-
raise ArgumentError, "#{scope.class.name} requires the property #{self.name} to be set"
|
74
|
-
end
|
75
|
-
|
157
|
+
raise MissingValueError.new(scope, self) if required?(scope) && value.nil?
|
76
158
|
value = convert(value, scope) unless value.nil?
|
77
|
-
|
78
|
-
unless accepts?(value, scope)
|
79
|
-
raise ArgumentError, "#{scope.class.name} does not accept #{value.inspect} as value for the property #{self.name}"
|
80
|
-
end
|
81
|
-
|
159
|
+
raise InvalidValueError.new(scope, self, value) unless accepts?(value, scope)
|
82
160
|
value
|
83
161
|
end
|
84
162
|
|
@@ -86,7 +164,7 @@ module SmartProperties
|
|
86
164
|
property = self
|
87
165
|
|
88
166
|
scope = klass.instance_variable_get(:"@_smart_properties_method_scope") || begin
|
89
|
-
m = Module.new
|
167
|
+
m = Module.new { include IndexMethods }
|
90
168
|
klass.send(:include, m)
|
91
169
|
klass.instance_variable_set(:"@_smart_properties_method_scope", m)
|
92
170
|
m
|
@@ -119,6 +197,10 @@ module SmartProperties
|
|
119
197
|
collection_with_parent_collection[name]
|
120
198
|
end
|
121
199
|
|
200
|
+
def key?(name)
|
201
|
+
collection_with_parent_collection.key?(name)
|
202
|
+
end
|
203
|
+
|
122
204
|
def each(&block)
|
123
205
|
collection_with_parent_collection.each(&block)
|
124
206
|
end
|
@@ -244,10 +326,11 @@ module SmartProperties
|
|
244
326
|
block.call(self) if block
|
245
327
|
|
246
328
|
# Check presence of all required properties
|
247
|
-
faulty_properties =
|
329
|
+
faulty_properties =
|
330
|
+
properties.select { |_, property| property.required?(self) && send(property.name).nil? }.map(&:last)
|
248
331
|
unless faulty_properties.empty?
|
249
|
-
|
332
|
+
error = SmartProperties::InitializationError.new(self, faulty_properties)
|
333
|
+
raise error
|
250
334
|
end
|
251
335
|
end
|
252
|
-
|
253
336
|
end
|
data/smart_properties.gemspec
CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
gem.version = SmartProperties::VERSION
|
21
21
|
|
22
|
-
gem.add_development_dependency "rspec", "~>
|
23
|
-
gem.add_development_dependency "rake", "~> 0
|
24
|
-
gem.add_development_dependency "guard-rspec", "~> 0.7"
|
22
|
+
gem.add_development_dependency "rspec", "~> 3.0"
|
23
|
+
gem.add_development_dependency "rake", "~> 10.0"
|
25
24
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SmartProperties do
|
4
|
-
|
5
4
|
context "when extending an other class" do
|
6
5
|
subject(:klass) do
|
7
6
|
Class.new.tap do |c|
|
@@ -10,7 +9,7 @@ describe SmartProperties do
|
|
10
9
|
end
|
11
10
|
|
12
11
|
it "should add a .property method" do
|
13
|
-
klass.respond_to?(:property, true).
|
12
|
+
expect(klass.respond_to?(:property, true)).to be_truthy
|
14
13
|
end
|
15
14
|
|
16
15
|
context "and defining a property with invalid configuration options" do
|
@@ -21,7 +20,7 @@ describe SmartProperties do
|
|
21
20
|
property :title, :invalid_option => 'boom'
|
22
21
|
end
|
23
22
|
end
|
24
|
-
}.to raise_error(
|
23
|
+
}.to raise_error(SmartProperties::ConfigurationError, "SmartProperties do not support the following configuration options: invalid_option.")
|
25
24
|
end
|
26
25
|
|
27
26
|
it "should raise an error reporting three invalid options when three invalid options were given" do
|
@@ -31,7 +30,7 @@ describe SmartProperties do
|
|
31
30
|
property :title, :invalid_option_1 => 'boom', :invalid_option_2 => 'boom', :invalid_option_3 => 'boom'
|
32
31
|
end
|
33
32
|
end
|
34
|
-
}.to raise_error(
|
33
|
+
}.to raise_error(SmartProperties::ConfigurationError, "SmartProperties do not support the following configuration options: invalid_option_1, invalid_option_2, invalid_option_3.")
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
@@ -59,25 +58,36 @@ describe SmartProperties do
|
|
59
58
|
|
60
59
|
let(:superklass) { klass }
|
61
60
|
|
62
|
-
it {
|
61
|
+
it { is_expected.to have_smart_property(:title) }
|
63
62
|
|
64
63
|
context "instances of this class" do
|
65
64
|
subject(:instance) { klass.new }
|
66
65
|
|
67
|
-
it {
|
68
|
-
it {
|
66
|
+
it { is_expected.to respond_to(:title) }
|
67
|
+
it { is_expected.to respond_to(:title=) }
|
68
|
+
|
69
|
+
it "should have 'chunky' as default value for title when accessed using the #title method" do
|
70
|
+
expect(instance.title).to eq('chunky')
|
71
|
+
end
|
69
72
|
|
70
|
-
it "should have '
|
71
|
-
instance
|
73
|
+
it "should have 'chunky' as default value for title when accessed using the #[] method" do
|
74
|
+
expect(instance[:title]).to eq('chunky')
|
72
75
|
end
|
73
76
|
|
74
|
-
it "should convert all values that are assigned to title into strings" do
|
77
|
+
it "should convert all values that are assigned to title into strings when using the #title= method" do
|
75
78
|
instance.title = double(:to_title => 'bacon')
|
76
|
-
instance.title.
|
79
|
+
expect(instance.title).to eq('bacon')
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should convert all values that are assigned to title into strings when using the #[]= method" do
|
83
|
+
instance[:title] = double(:to_title => 'bacon')
|
84
|
+
expect(instance.title).to eq('bacon')
|
77
85
|
end
|
78
86
|
|
79
87
|
it "should not allow to set nil as title" do
|
80
|
-
expect { instance.title = nil }.to raise_error(
|
88
|
+
expect { instance.title = nil }.to raise_error(SmartProperties::MissingValueError, "TestDummy requires the property title to be set") {|error|
|
89
|
+
expect(error.to_hash[:title]).to eq('must be set')
|
90
|
+
}
|
81
91
|
end
|
82
92
|
|
83
93
|
it "should not allow to set objects as title that do not respond to #to_title" do
|
@@ -87,8 +97,8 @@ describe SmartProperties do
|
|
87
97
|
it "should not influence other instances that have been initialized with different attributes" do
|
88
98
|
other_instance = klass.new :title => double(:to_title => 'Lorem ipsum')
|
89
99
|
|
90
|
-
instance.title.
|
91
|
-
other_instance.title.
|
100
|
+
expect(instance.title).to eq('chunky')
|
101
|
+
expect(other_instance.title).to eq('Lorem ipsum')
|
92
102
|
end
|
93
103
|
|
94
104
|
context "when initialized with a block" do
|
@@ -99,7 +109,7 @@ describe SmartProperties do
|
|
99
109
|
end
|
100
110
|
|
101
111
|
it "should have the title specified in the block" do
|
102
|
-
instance.title.
|
112
|
+
expect(instance.title).to eq('bacon')
|
103
113
|
end
|
104
114
|
end
|
105
115
|
end
|
@@ -107,20 +117,20 @@ describe SmartProperties do
|
|
107
117
|
context "when subclassed" do
|
108
118
|
subject(:subklass) { Class.new(superklass) }
|
109
119
|
|
110
|
-
it {
|
120
|
+
it { is_expected.to have_smart_property(:title) }
|
111
121
|
|
112
122
|
context "instances of this subclass" do
|
113
123
|
subject(:instance) { subklass.new }
|
114
124
|
|
115
|
-
it {
|
116
|
-
it {
|
125
|
+
it { is_expected.to respond_to(:title) }
|
126
|
+
it { is_expected.to respond_to(:title=) }
|
117
127
|
end
|
118
128
|
|
119
129
|
context "instances of this subclass that have been intialized from a set of attributes" do
|
120
130
|
subject(:instance) { subklass.new :title => double(:to_title => 'Message') }
|
121
131
|
|
122
132
|
it "should have the correct title" do
|
123
|
-
instance.title.
|
133
|
+
expect(instance.title).to eq('Message')
|
124
134
|
end
|
125
135
|
end
|
126
136
|
end
|
@@ -134,31 +144,38 @@ describe SmartProperties do
|
|
134
144
|
end
|
135
145
|
end
|
136
146
|
|
137
|
-
it {
|
138
|
-
it {
|
147
|
+
it { is_expected.to have_smart_property(:title) }
|
148
|
+
it { is_expected.to have_smart_property(:text) }
|
139
149
|
|
140
150
|
context "instances of this subclass" do
|
141
151
|
subject(:instance) { subklass.new }
|
142
152
|
|
143
|
-
it {
|
144
|
-
it {
|
145
|
-
it {
|
146
|
-
it {
|
153
|
+
it { is_expected.to respond_to(:title) }
|
154
|
+
it { is_expected.to respond_to(:title=) }
|
155
|
+
it { is_expected.to respond_to(:text) }
|
156
|
+
it { is_expected.to respond_to(:text=) }
|
147
157
|
end
|
148
158
|
|
149
159
|
context "instances of the super class" do
|
150
160
|
subject(:instance) { superklass.new }
|
151
161
|
|
152
|
-
it {
|
153
|
-
it {
|
162
|
+
it { is_expected.not_to respond_to(:text) }
|
163
|
+
it { is_expected.not_to respond_to(:text=) }
|
154
164
|
end
|
155
165
|
|
156
166
|
context "instances of this subclass" do
|
157
167
|
context "when initialized with a set of attributes" do
|
158
168
|
subject(:instance) { subklass.new :title => double(:to_title => 'Message'), :text => "Hello" }
|
159
169
|
|
160
|
-
|
161
|
-
|
170
|
+
context "when properties are accessed using the dedicated instance methods" do
|
171
|
+
it("should have the correct title") { expect(instance.title).to eq('Message') }
|
172
|
+
it("should have the correct text") { expect(instance.text).to eq('Hello') }
|
173
|
+
end
|
174
|
+
|
175
|
+
context "when properties are accessed using the index methods" do
|
176
|
+
it("should have the correct title") { expect(instance[:title]).to eq('Message') }
|
177
|
+
it("should have the correct text") { expect(instance[:text]).to eq('Hello') }
|
178
|
+
end
|
162
179
|
end
|
163
180
|
|
164
181
|
context "when initialized with a block" do
|
@@ -169,8 +186,8 @@ describe SmartProperties do
|
|
169
186
|
end
|
170
187
|
end
|
171
188
|
|
172
|
-
it("should have the correct title") { instance.title.
|
173
|
-
it("should have the correct text") { instance.text.
|
189
|
+
it("should have the correct title") { expect(instance.title).to eq('Message') }
|
190
|
+
it("should have the correct text") { expect(instance.text).to eq('Hello') }
|
174
191
|
end
|
175
192
|
end
|
176
193
|
end
|
@@ -184,14 +201,14 @@ describe SmartProperties do
|
|
184
201
|
end
|
185
202
|
end
|
186
203
|
|
187
|
-
it {
|
188
|
-
it {
|
204
|
+
it { is_expected.to have_smart_property(:title) }
|
205
|
+
it { is_expected.to have_smart_property(:type) }
|
189
206
|
|
190
207
|
context "instances of this class" do
|
191
208
|
subject(:instance) { superklass.new :title => double(:to_title => 'Lorem ipsum') }
|
192
209
|
|
193
|
-
it {
|
194
|
-
it {
|
210
|
+
it { is_expected.to respond_to(:type) }
|
211
|
+
it { is_expected.to respond_to(:type=) }
|
195
212
|
end
|
196
213
|
|
197
214
|
context "when subclassing this class" do
|
@@ -200,10 +217,10 @@ describe SmartProperties do
|
|
200
217
|
context "instances of this class" do
|
201
218
|
subject(:instance) { subclass.new :title => double(:to_title => 'Lorem ipsum') }
|
202
219
|
|
203
|
-
it {
|
204
|
-
it {
|
205
|
-
it {
|
206
|
-
it {
|
220
|
+
it { is_expected.to respond_to :title }
|
221
|
+
it { is_expected.to respond_to :title= }
|
222
|
+
it { is_expected.to respond_to :type }
|
223
|
+
it { is_expected.to respond_to :type= }
|
207
224
|
end
|
208
225
|
end
|
209
226
|
end
|
@@ -224,7 +241,7 @@ describe SmartProperties do
|
|
224
241
|
|
225
242
|
it "should convert the property title as specified the lambda statement" do
|
226
243
|
instance.title = "Lorem ipsum"
|
227
|
-
instance.title.
|
244
|
+
expect(instance.title).to eq("<title>Lorem ipsum</title>")
|
228
245
|
end
|
229
246
|
end
|
230
247
|
end
|
@@ -250,7 +267,7 @@ describe SmartProperties do
|
|
250
267
|
|
251
268
|
it "should convert the property title as specified the lambda statement" do
|
252
269
|
instance.title = "Lorem ipsum"
|
253
|
-
instance.title.
|
270
|
+
expect(instance.title).to eq("<title>Lorem ipsum</title>")
|
254
271
|
end
|
255
272
|
end
|
256
273
|
end
|
@@ -271,16 +288,36 @@ describe SmartProperties do
|
|
271
288
|
context "instances of this class" do
|
272
289
|
subject(:instance) { klass.new }
|
273
290
|
|
274
|
-
|
275
|
-
|
276
|
-
|
291
|
+
context "when properties are accessed using the dedicated instance methods" do
|
292
|
+
it "should allow to set true as value for visible" do
|
293
|
+
expect { instance.visible = true }.to_not raise_error
|
294
|
+
end
|
277
295
|
|
278
|
-
|
279
|
-
|
296
|
+
it "should allow to set false as value for visible" do
|
297
|
+
expect { instance.visible = false }.to_not raise_error
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should not allow to set :maybe as value for visible" do
|
301
|
+
expect { instance.visible = :maybe }.to raise_error(SmartProperties::InvalidValueError, "TestDummy does not accept :maybe as value for the property visible") {|error|
|
302
|
+
expect(error.to_hash[:visible]).to eq('does not accept :maybe as value')
|
303
|
+
}
|
304
|
+
end
|
280
305
|
end
|
281
306
|
|
282
|
-
|
283
|
-
|
307
|
+
context "when properties are accessed using the index methods" do
|
308
|
+
it "should allow to set true as value for visible" do
|
309
|
+
expect { instance[:visible] = true }.to_not raise_error
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should allow to set false as value for visible" do
|
313
|
+
expect { instance[:visible] = false }.to_not raise_error
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should not allow to set :maybe as value for visible" do
|
317
|
+
expect { instance[:visible] = :maybe }.to raise_error(SmartProperties::InvalidValueError, "TestDummy does not accept :maybe as value for the property visible") {|error|
|
318
|
+
expect(error.to_hash[:visible]).to eq('does not accept :maybe as value')
|
319
|
+
}
|
320
|
+
end
|
284
321
|
end
|
285
322
|
end
|
286
323
|
end
|
@@ -298,12 +335,24 @@ describe SmartProperties do
|
|
298
335
|
context "intance of this class" do
|
299
336
|
subject(:instance) { klass.new }
|
300
337
|
|
301
|
-
|
302
|
-
|
338
|
+
context "when properties are accessed using the dedicated instance methods" do
|
339
|
+
it "should accept a String as title" do
|
340
|
+
expect { subject.title = "Test" }.to_not raise_error
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should accept a Symbol as title" do
|
344
|
+
expect { subject.title = :test }.to_not raise_error
|
345
|
+
end
|
303
346
|
end
|
304
347
|
|
305
|
-
|
306
|
-
|
348
|
+
context "when properties are accessed using the index methods" do
|
349
|
+
it "should accept a String as title" do
|
350
|
+
expect { subject[:title] = "Test" }.to_not raise_error
|
351
|
+
end
|
352
|
+
|
353
|
+
it "should accept a Symbol as title" do
|
354
|
+
expect { subject[:title] = :test }.to_not raise_error
|
355
|
+
end
|
307
356
|
end
|
308
357
|
end
|
309
358
|
end
|
@@ -324,12 +373,26 @@ describe SmartProperties do
|
|
324
373
|
context 'instances of this class' do
|
325
374
|
subject(:instance) { klass.new }
|
326
375
|
|
327
|
-
|
328
|
-
|
376
|
+
context "when properties are accessed using the dedicated instance methods" do
|
377
|
+
it 'should not a accept "invalid" as value for license_plate' do
|
378
|
+
expect { instance.license_plate = "invalid" }.to raise_error(SmartProperties::InvalidValueError, 'TestDummy does not accept "invalid" as value for the property license_plate') {|error|
|
379
|
+
expect(error.to_hash[:license_plate]).to eq('does not accept "invalid" as value')
|
380
|
+
}
|
381
|
+
end
|
382
|
+
|
383
|
+
it 'should accept "NE RD 1337" as license plate' do
|
384
|
+
expect { instance.license_plate = "NE RD 1337" }.to_not raise_error
|
385
|
+
end
|
329
386
|
end
|
330
387
|
|
331
|
-
|
332
|
-
|
388
|
+
context "when properties are accessed using the index methods" do
|
389
|
+
it 'should not a accept "invalid" as value for license_plate' do
|
390
|
+
expect { instance[:license_plate] = "invalid" }.to raise_error(ArgumentError, 'TestDummy does not accept "invalid" as value for the property license_plate')
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'should accept "NE RD 1337" as license plate' do
|
394
|
+
expect { instance[:license_plate] = "NE RD 1337" }.to_not raise_error
|
395
|
+
end
|
333
396
|
end
|
334
397
|
end
|
335
398
|
end
|
@@ -354,8 +417,16 @@ describe SmartProperties do
|
|
354
417
|
context "instances of this class" do
|
355
418
|
subject(:instance) { klass.new }
|
356
419
|
|
357
|
-
|
358
|
-
|
420
|
+
context "when properties are accessed using the dedicated instance methods" do
|
421
|
+
it "should return the accepted value for the property called :text" do
|
422
|
+
expect(instance.text).to eq('<em>Hello</em>')
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context "when properties are accessed using the index methods" do
|
427
|
+
it "should return the accepted value for the property called :text" do
|
428
|
+
expect(instance[:text]).to eq('<em>Hello</em>')
|
429
|
+
end
|
359
430
|
end
|
360
431
|
end
|
361
432
|
end
|
@@ -387,7 +458,7 @@ describe SmartProperties do
|
|
387
458
|
first_instance = klass.new
|
388
459
|
second_instance = klass.new
|
389
460
|
|
390
|
-
(second_instance.id - first_instance.id).
|
461
|
+
expect(second_instance.id - first_instance.id).to eq(1)
|
391
462
|
end
|
392
463
|
end
|
393
464
|
end
|
@@ -415,16 +486,16 @@ describe SmartProperties do
|
|
415
486
|
context "the class" do
|
416
487
|
subject { klass }
|
417
488
|
|
418
|
-
it {
|
419
|
-
it {
|
489
|
+
it { is_expected.to have_smart_property(:title) }
|
490
|
+
it { is_expected.to have_smart_property(:priority) }
|
420
491
|
end
|
421
492
|
|
422
493
|
context 'the subclass' do
|
423
494
|
subject { subklass }
|
424
495
|
|
425
|
-
it {
|
426
|
-
it {
|
427
|
-
it {
|
496
|
+
it { is_expected.to have_smart_property(:title) }
|
497
|
+
it { is_expected.to have_smart_property(:body) }
|
498
|
+
it { is_expected.to have_smart_property(:priority) }
|
428
499
|
|
429
500
|
it "should be initializable using a block" do
|
430
501
|
configuration_instructions = lambda do |s|
|
@@ -461,23 +532,39 @@ describe SmartProperties do
|
|
461
532
|
subject(:instance) { klass.new :title => nil }
|
462
533
|
|
463
534
|
it "should have no title" do
|
464
|
-
instance.title.
|
535
|
+
expect(instance.title).to be_nil
|
465
536
|
end
|
466
537
|
end
|
467
538
|
|
468
539
|
context 'when created without any arguments' do
|
469
540
|
subject(:instance) { klass.new }
|
470
541
|
|
471
|
-
|
472
|
-
|
542
|
+
context "when properties are accessed using the index methods" do
|
543
|
+
it "should have the default title" do
|
544
|
+
expect(instance.title).to eq('Lorem Ipsum')
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
context "when properties are accessed using the index methods" do
|
549
|
+
it "should have the default title" do
|
550
|
+
expect(instance[:title]).to eq('Lorem Ipsum')
|
551
|
+
end
|
473
552
|
end
|
474
553
|
end
|
475
554
|
|
476
555
|
context 'when created with an empty block' do
|
477
556
|
subject(:instance) { klass.new {} }
|
478
557
|
|
479
|
-
|
480
|
-
|
558
|
+
context "when properties are accessed using the index methods" do
|
559
|
+
it "should have the default title" do
|
560
|
+
expect(instance.title).to eq('Lorem Ipsum')
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
context "when properties are accessed using the index methods" do
|
565
|
+
it "should have the default title" do
|
566
|
+
expect(instance[:title]).to eq('Lorem Ipsum')
|
567
|
+
end
|
481
568
|
end
|
482
569
|
end
|
483
570
|
end
|
@@ -494,11 +581,11 @@ describe SmartProperties do
|
|
494
581
|
end
|
495
582
|
|
496
583
|
context 'instances of that class' do
|
497
|
-
context 'when created with a set of attributes that
|
584
|
+
context 'when created with a set of attributes that contains a title' do
|
498
585
|
subject(:instance) { klass.new :title => 'Lorem Ipsum' }
|
499
586
|
|
500
|
-
it "should have
|
501
|
-
instance.title.
|
587
|
+
it "should have the correct title" do
|
588
|
+
expect(instance.title).to eq('Lorem Ipsum')
|
502
589
|
end
|
503
590
|
end
|
504
591
|
|
@@ -506,13 +593,15 @@ describe SmartProperties do
|
|
506
593
|
subject(:instance) { klass.new { |i| i.title = 'Lorem Ipsum' } }
|
507
594
|
|
508
595
|
it "should have the default title" do
|
509
|
-
instance.title.
|
596
|
+
expect(instance.title).to eq('Lorem Ipsum')
|
510
597
|
end
|
511
598
|
end
|
512
599
|
|
513
600
|
context "when created with no arguments" do
|
514
601
|
it "should raise an error stating that required properties are missing" do
|
515
|
-
expect { klass.new }.to raise_error(
|
602
|
+
expect { klass.new }.to raise_error(SmartProperties::InitializationError, "Dummy requires the following properties to be set: title") {|error|
|
603
|
+
expect(error.to_hash[:title]).to eq('must be set')
|
604
|
+
}
|
516
605
|
end
|
517
606
|
end
|
518
607
|
end
|
@@ -538,7 +627,9 @@ describe SmartProperties do
|
|
538
627
|
|
539
628
|
context "when created with no name and anonymous being set to false" do
|
540
629
|
it "should raise an error indicating that a required property was not specified" do
|
541
|
-
expect { klass.new anonymous: false }.to raise_error(
|
630
|
+
expect { klass.new anonymous: false }.to raise_error(SmartProperties::InitializationError, "Dummy requires the following properties to be set: name") {|error|
|
631
|
+
expect(error.to_hash[:name]).to eq("must be set")
|
632
|
+
}
|
542
633
|
end
|
543
634
|
end
|
544
635
|
|
@@ -564,23 +655,39 @@ describe SmartProperties do
|
|
564
655
|
subject(:instance) { klass.new :flag => true }
|
565
656
|
|
566
657
|
it "should have no title" do
|
567
|
-
instance.flag.
|
658
|
+
expect(instance.flag).to be_truthy
|
568
659
|
end
|
569
660
|
end
|
570
661
|
|
571
662
|
context 'when created with an block specifying that property' do
|
572
663
|
subject(:instance) { klass.new { |i| i.flag = true } }
|
573
664
|
|
574
|
-
|
575
|
-
|
665
|
+
context "when properties are accessed using the dedicated instance methods" do
|
666
|
+
it "should have the default title" do
|
667
|
+
expect(instance.flag).to be(true)
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
context "when properties are accessed using the index methods" do
|
672
|
+
it "should have the default title" do
|
673
|
+
expect(instance[:flag]).to be(true)
|
674
|
+
end
|
576
675
|
end
|
577
676
|
end
|
578
677
|
|
579
678
|
context "when created with no arguments" do
|
580
679
|
subject(:instance) { klass.new }
|
581
680
|
|
582
|
-
|
583
|
-
|
681
|
+
context "when properties are accessed using the dedicated instance methods" do
|
682
|
+
it "should have false as default flag" do
|
683
|
+
expect(instance.flag).to be(false)
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
context "when properties are accessed using the index methods" do
|
688
|
+
it "should have false as default flag" do
|
689
|
+
expect(instance[:flag]).to be(false)
|
690
|
+
end
|
584
691
|
end
|
585
692
|
end
|
586
693
|
end
|
@@ -18,9 +18,10 @@ module Matchers
|
|
18
18
|
return "expected #{instance.class.name} to be smart property enabled"
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def failure_message_when_negated
|
22
22
|
"expected #{instance.class.name} to not have a property named #{property_name}"
|
23
23
|
end
|
24
|
+
alias negative_failure_message failure_message_when_negated
|
24
25
|
|
25
26
|
private
|
26
27
|
|
@@ -43,4 +44,4 @@ end
|
|
43
44
|
|
44
45
|
RSpec.configure do |spec|
|
45
46
|
spec.include(Matchers)
|
46
|
-
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_properties
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Tennhard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: guard-rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ~>
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.7'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0.7'
|
40
|
+
version: '10.0'
|
55
41
|
description: |2
|
56
42
|
SmartProperties are a more flexible and feature-rich alternative to
|
57
43
|
traditional Ruby accessors. They provide support for input conversion,
|
@@ -62,11 +48,10 @@ executables: []
|
|
62
48
|
extensions: []
|
63
49
|
extra_rdoc_files: []
|
64
50
|
files:
|
65
|
-
- .gitignore
|
66
|
-
- .travis.yml
|
67
|
-
- .yardopts
|
51
|
+
- ".gitignore"
|
52
|
+
- ".travis.yml"
|
53
|
+
- ".yardopts"
|
68
54
|
- Gemfile
|
69
|
-
- Guardfile
|
70
55
|
- LICENSE
|
71
56
|
- README.md
|
72
57
|
- Rakefile
|
@@ -84,17 +69,17 @@ require_paths:
|
|
84
69
|
- lib
|
85
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
71
|
requirements:
|
87
|
-
- -
|
72
|
+
- - ">="
|
88
73
|
- !ruby/object:Gem::Version
|
89
74
|
version: '0'
|
90
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
76
|
requirements:
|
92
|
-
- -
|
77
|
+
- - ">="
|
93
78
|
- !ruby/object:Gem::Version
|
94
79
|
version: '0'
|
95
80
|
requirements: []
|
96
81
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
82
|
+
rubygems_version: 2.2.2
|
98
83
|
signing_key:
|
99
84
|
specification_version: 4
|
100
85
|
summary: SmartProperties – Ruby accessors on steroids
|
data/Guardfile
DELETED