smart_properties 1.4.0 → 1.5.0
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.
- 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