smart_properties 1.15.0 → 1.16.3
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/.github/workflows/testing.yml +24 -0
- data/.ruby-version +1 -1
- data/README.md +1 -1
- data/lib/smart_properties/property.rb +14 -7
- data/lib/smart_properties/property_collection.rb +8 -7
- data/lib/smart_properties/version.rb +1 -1
- data/lib/smart_properties.rb +8 -0
- data/smart_properties.gemspec +5 -1
- data/spec/configuration_error_spec.rb +19 -0
- data/spec/inheritance_spec.rb +82 -0
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cab5fbc87f1af758c2b385feaed5c43cf2f7555f2f55322e1bbbfe47771a42d
|
4
|
+
data.tar.gz: a79f9fd570f548895fcd3cc4d65e7f6ba614692f0671e09ce70be6704b49428a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42c3abfd70e12c52f185a49d6ccb2bfe4429a52eab2d18e8613058bc5687d6c525ac3ad3d5eaab75c1cbe092536673bb2c675d5adc2e26759a8a824e0ff4a096
|
7
|
+
data.tar.gz: 21eb0b7ab6ab434f512525f5a36fbf07c0a79ce53173c4c417ee379b52de737a4db1baf226019bc4d0eb813e2f7e6a502101f6674d6ba5703bc671bee1fd385c
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: Testing
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
workflow_dispatch:
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.6
|
21
|
+
- name: Install dependencies
|
22
|
+
run: bundle install
|
23
|
+
- name: Run tests
|
24
|
+
run: bundle exec rake
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6.
|
1
|
+
2.6.6
|
data/README.md
CHANGED
@@ -177,7 +177,7 @@ often. These validations can be found in the `SmartProperties::Validations` modu
|
|
177
177
|
|
178
178
|
```ruby
|
179
179
|
class Article
|
180
|
-
property :view_count, accepts: Ancestor.must_be(Number)
|
180
|
+
property :view_count, accepts: Ancestor.must_be(type: Number)
|
181
181
|
end
|
182
182
|
```
|
183
183
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module SmartProperties
|
2
2
|
class Property
|
3
3
|
MODULE_REFERENCE = :"@_smart_properties_method_scope"
|
4
|
-
ALLOWED_DEFAULT_CLASSES = [Proc, Numeric, String, Range, TrueClass, FalseClass, NilClass, Symbol].freeze
|
4
|
+
ALLOWED_DEFAULT_CLASSES = [Proc, Numeric, String, Range, TrueClass, FalseClass, NilClass, Symbol, Module].freeze
|
5
5
|
|
6
6
|
attr_reader :name
|
7
7
|
attr_reader :converter
|
@@ -157,12 +157,19 @@ module SmartProperties
|
|
157
157
|
rescue NoMethodError => error
|
158
158
|
# BasicObject does not respond to #nil? by default, so we need to double
|
159
159
|
# check if somebody implemented it and it fails internally or if the
|
160
|
-
# error occured because the method is actually not present.
|
161
|
-
|
162
|
-
#
|
163
|
-
|
164
|
-
|
165
|
-
|
160
|
+
# error occured because the method is actually not present.
|
161
|
+
|
162
|
+
# This is a workaround for the fact that #singleton_class is defined on Object, but not BasicObject.
|
163
|
+
the_singleton_class = (class << object; self; end)
|
164
|
+
|
165
|
+
if the_singleton_class.public_instance_methods.include?(:nil?)
|
166
|
+
# object defines #nil?, but it raised NoMethodError,
|
167
|
+
# something is wrong with the implementation, so raise the exception.
|
168
|
+
raise error
|
169
|
+
else
|
170
|
+
# treat the object as truthy because we don't know better.
|
171
|
+
false
|
172
|
+
end
|
166
173
|
end
|
167
174
|
end
|
168
175
|
end
|
@@ -5,18 +5,19 @@ module SmartProperties
|
|
5
5
|
attr_reader :parent
|
6
6
|
|
7
7
|
def self.for(scope)
|
8
|
-
|
8
|
+
parents = scope.ancestors[1..-1].select do |ancestor|
|
9
9
|
ancestor.ancestors.include?(SmartProperties) &&
|
10
10
|
ancestor != scope &&
|
11
11
|
ancestor != SmartProperties
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
parent.properties.register(collection
|
18
|
-
collection
|
14
|
+
collection = new
|
15
|
+
|
16
|
+
parents.reverse.each do |parent|
|
17
|
+
parent.properties.register(collection)
|
19
18
|
end
|
19
|
+
|
20
|
+
collection
|
20
21
|
end
|
21
22
|
|
22
23
|
def initialize
|
@@ -75,7 +76,7 @@ module SmartProperties
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def refresh(parent_collection)
|
78
|
-
@collection_with_parent_collection
|
79
|
+
@collection_with_parent_collection.merge!(parent_collection)
|
79
80
|
notify_children
|
80
81
|
nil
|
81
82
|
end
|
data/lib/smart_properties.rb
CHANGED
@@ -91,6 +91,13 @@ module SmartProperties
|
|
91
91
|
protected :property!
|
92
92
|
end
|
93
93
|
|
94
|
+
module ModuleMethods
|
95
|
+
def included(target)
|
96
|
+
super
|
97
|
+
target.include(SmartProperties)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
94
101
|
class << self
|
95
102
|
private
|
96
103
|
|
@@ -102,6 +109,7 @@ module SmartProperties
|
|
102
109
|
#
|
103
110
|
def included(base)
|
104
111
|
base.extend(ClassMethods)
|
112
|
+
base.extend(ModuleMethods) unless base.is_a?(Class)
|
105
113
|
end
|
106
114
|
end
|
107
115
|
|
data/smart_properties.gemspec
CHANGED
@@ -12,6 +12,10 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.summary = %q{SmartProperties – Ruby accessors on steroids}
|
13
13
|
gem.homepage = ""
|
14
14
|
|
15
|
+
gem.metadata = {
|
16
|
+
"source_code_uri" => "https://github.com/t6d/smart_properties"
|
17
|
+
}
|
18
|
+
|
15
19
|
gem.files = `git ls-files`.split($\)
|
16
20
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
21
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -20,6 +24,6 @@ Gem::Specification.new do |gem|
|
|
20
24
|
gem.version = SmartProperties::VERSION
|
21
25
|
|
22
26
|
gem.add_development_dependency "rspec", "~> 3.0"
|
23
|
-
gem.add_development_dependency "rake", "~>
|
27
|
+
gem.add_development_dependency "rake", "~> 13.0"
|
24
28
|
gem.add_development_dependency "pry"
|
25
29
|
end
|
@@ -14,6 +14,25 @@ RSpec.describe SmartProperties, 'configuration error' do
|
|
14
14
|
expect(&invalid_property_definition).to raise_error(SmartProperties::ConfigurationError, "SmartProperties do not support the following configuration options: invalid_option_1, invalid_option_2, invalid_option_3.")
|
15
15
|
end
|
16
16
|
|
17
|
+
it "should accept default values that can't be mutated" do
|
18
|
+
valid_property_definition = lambda do
|
19
|
+
klass.class_eval do
|
20
|
+
property :proc, default: -> { }
|
21
|
+
property :numeric_float, default: 1.23
|
22
|
+
property :numeric_int, default: 456
|
23
|
+
property :string, default: "abc"
|
24
|
+
property :range, default: 123...456
|
25
|
+
property :bool_true, default: true
|
26
|
+
property :bool_false, default: false
|
27
|
+
property :nil, default: nil
|
28
|
+
property :symbol, default: :abc
|
29
|
+
property :module, default: Integer
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
expect(&valid_property_definition).not_to raise_error
|
34
|
+
end
|
35
|
+
|
17
36
|
it "should not accept default values that may be mutated" do
|
18
37
|
invalid_property_definition = lambda do
|
19
38
|
klass.class_eval do
|
data/spec/inheritance_spec.rb
CHANGED
@@ -225,4 +225,86 @@ RSpec.describe SmartProperties, 'intheritance' do
|
|
225
225
|
end
|
226
226
|
end
|
227
227
|
end
|
228
|
+
|
229
|
+
context "through modules" do
|
230
|
+
let(:m) do
|
231
|
+
m = Module.new do
|
232
|
+
include SmartProperties
|
233
|
+
property :m, default: 1
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
let(:n) do
|
238
|
+
n = Module.new do
|
239
|
+
include SmartProperties
|
240
|
+
property :n, default: 2
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
it "is supported" do
|
245
|
+
n = self.n
|
246
|
+
m = self.m
|
247
|
+
o = Module.new {}
|
248
|
+
|
249
|
+
klass = Class.new do
|
250
|
+
include m
|
251
|
+
include o
|
252
|
+
include n
|
253
|
+
end
|
254
|
+
|
255
|
+
n.module_eval do
|
256
|
+
property :p, default: 3
|
257
|
+
end
|
258
|
+
|
259
|
+
instance = klass.new
|
260
|
+
|
261
|
+
expect(instance.m).to eq(1)
|
262
|
+
expect(instance.n).to eq(2)
|
263
|
+
expect(instance.p).to eq(3)
|
264
|
+
|
265
|
+
expect { klass.new(m: 4, n: 5, p: 6) }.to_not raise_error
|
266
|
+
end
|
267
|
+
|
268
|
+
it "always extends module with ModuleMethods but never classes" do
|
269
|
+
n = self.n
|
270
|
+
|
271
|
+
klass = Class.new do
|
272
|
+
include n
|
273
|
+
end
|
274
|
+
|
275
|
+
module_singleton_class_ancestors = n.singleton_class.ancestors
|
276
|
+
|
277
|
+
expect(module_singleton_class_ancestors).to include(SmartProperties::ClassMethods)
|
278
|
+
expect(module_singleton_class_ancestors).to include(SmartProperties::ModuleMethods)
|
279
|
+
|
280
|
+
singleton_class_ancestors = klass.singleton_class.ancestors
|
281
|
+
|
282
|
+
expect(singleton_class_ancestors).to include(SmartProperties::ClassMethods)
|
283
|
+
expect(singleton_class_ancestors).not_to include(SmartProperties::ModuleMethods)
|
284
|
+
end
|
285
|
+
|
286
|
+
it "yields properly ordered properties – child properties have higher precedence than parent properties" do
|
287
|
+
n = self.n
|
288
|
+
m = self.m
|
289
|
+
|
290
|
+
parent = Class.new do
|
291
|
+
include m
|
292
|
+
include n
|
293
|
+
end
|
294
|
+
expect(parent.new.m).to eq(1)
|
295
|
+
|
296
|
+
child = Class.new(parent) do
|
297
|
+
property :m, default: 0
|
298
|
+
end
|
299
|
+
expect(child.new.m).to eq(0)
|
300
|
+
|
301
|
+
grandchild = Class.new(child)
|
302
|
+
expect(grandchild.new.m).to eq(0)
|
303
|
+
|
304
|
+
grandgrandchild = Class.new(grandchild) do
|
305
|
+
property :m, default: 1000
|
306
|
+
end
|
307
|
+
expect(grandgrandchild.new.m).to eq(1000)
|
308
|
+
end
|
309
|
+
end
|
228
310
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_properties
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.16.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Tennhard
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.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: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -62,6 +62,7 @@ executables: []
|
|
62
62
|
extensions: []
|
63
63
|
extra_rdoc_files: []
|
64
64
|
files:
|
65
|
+
- ".github/workflows/testing.yml"
|
65
66
|
- ".gitignore"
|
66
67
|
- ".ruby-version"
|
67
68
|
- ".yardopts"
|
@@ -95,8 +96,9 @@ files:
|
|
95
96
|
- spec/writable_spec.rb
|
96
97
|
homepage: ''
|
97
98
|
licenses: []
|
98
|
-
metadata:
|
99
|
-
|
99
|
+
metadata:
|
100
|
+
source_code_uri: https://github.com/t6d/smart_properties
|
101
|
+
post_install_message:
|
100
102
|
rdoc_options: []
|
101
103
|
require_paths:
|
102
104
|
- lib
|
@@ -111,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
113
|
- !ruby/object:Gem::Version
|
112
114
|
version: '0'
|
113
115
|
requirements: []
|
114
|
-
rubygems_version: 3.
|
115
|
-
signing_key:
|
116
|
+
rubygems_version: 3.2.20
|
117
|
+
signing_key:
|
116
118
|
specification_version: 4
|
117
119
|
summary: SmartProperties – Ruby accessors on steroids
|
118
120
|
test_files:
|