smart_properties 1.15.0 → 1.16.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0466754454ac7feba9fa836c5b84ffaf04d2502084d6b385b6756f44cb119b34
4
- data.tar.gz: 47c46bfcce7352943062ac9be2f25a04ce1c3adbeb86d251a5b0aa20f012ddfa
3
+ metadata.gz: 4cab5fbc87f1af758c2b385feaed5c43cf2f7555f2f55322e1bbbfe47771a42d
4
+ data.tar.gz: a79f9fd570f548895fcd3cc4d65e7f6ba614692f0671e09ce70be6704b49428a
5
5
  SHA512:
6
- metadata.gz: 38f90027d577a4f7eca3e799980408aa6cb179af1d221f9b7c3212ba4385fa636057cfd620e4908c2f3c116c0475f04d9763a3fc00d2fd7a5349468b517f0095
7
- data.tar.gz: 3c4feb78a07b067ce593822861afa858ea29003354b8427c8bab12a2782de51f54a5027393b51c1817785a6b8ba57a2afa5dac54381dc58e7756d10e3bd7a3ad
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.2
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. In the former
161
- # case, we want to raise the exception because there is something wrong
162
- # with the implementation of object#nil?. In the latter case we treat the
163
- # object as truthy because we don't know better.
164
- raise error if (class << object; self; end).public_instance_methods.include?(:nil?)
165
- false
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
- parent = scope.ancestors[1..-1].find do |ancestor|
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
- if parent.nil?
15
- new
16
- else
17
- parent.properties.register(collection = new)
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 = parent_collection.merge(collection)
79
+ @collection_with_parent_collection.merge!(parent_collection)
79
80
  notify_children
80
81
  nil
81
82
  end
@@ -1,3 +1,3 @@
1
1
  module SmartProperties
2
- VERSION = "1.15.0"
2
+ VERSION = "1.16.3"
3
3
  end
@@ -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
 
@@ -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", "~> 10.0"
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
@@ -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.15.0
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: 2019-07-02 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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
- post_install_message:
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.0.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: