dumb_delegator 0.8.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63674a3e04272740045c64f5cd122fb431c333be76ffb7f5364067e28f31ef44
4
- data.tar.gz: 8b6ad9d8f119f2e8092e9fd5027ea076a41420ab76ea3555587577a12b234027
3
+ metadata.gz: 3dfd1848821cd96312119f18cd2cc09bfcdc72c2efca3f53ddca59bb6247008f
4
+ data.tar.gz: 6dfd0d7689ed6b8d83dd0029e3687e624594e021c5ed0c58ca4ce6489abd8812
5
5
  SHA512:
6
- metadata.gz: e5c94e20a372ff9fb834e9efe3b9bf922bc3539af15bab58aafa1fd5d8403a31b8de7728d7a6fdd7d8a90558333a2b326b866549156af3405049d811ac9b9bce
7
- data.tar.gz: 180f72c3eb297c0ea3e14f36dd87d9c13951316371f4d3d0c6eeb70e09812b4d7ee509fae5515e4559be3969612fced9da7adaa4cb5b2c4ea8459d9b77c179fd
6
+ metadata.gz: 72c45104a5258f109d258c6ff3268da7b7f1d2810f4a22ee916f8806d8cd5f3ca76ef01cfa6a7d2e18347158a25b4a727814e49be8ddec576a40d3b2bee6ca61
7
+ data.tar.gz: 49588ab5d55d168cf1916c7961285e9dc1c1a2f8fe0a6a097e6c671adee01424e374e99797410018e891fc6c9e09069515efbb84331fbd2f4c1cf9b486229ecd
data/.gitignore CHANGED
@@ -1,20 +1,23 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- .ruby-version
7
- Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
- coverage
11
- doc/
12
- lib/bundler/man
13
- bin
14
- pkg
15
- rdoc
16
- spec/reports
17
- test/tmp
18
- test/version_tmp
19
- tmp
20
- tags
1
+ # Ignore all logfiles and tempfiles
2
+ /tmp/
3
+ /tags
4
+
5
+ # Environment normalisation
6
+ /.env
7
+ /.rspec-local
8
+ /.yardoc
9
+ /lib/bundler/man/
10
+
11
+ # Gem packaging stuff
12
+ /*.gem
13
+ /pkg/
14
+
15
+ # Dependencies and such
16
+ /.bundle
17
+ /.ruby-version
18
+ /Gemfile.lock
19
+
20
+ # Spec and coverage housekeeping
21
+ /coverage/
22
+ /spec/rspec-status.txt
23
+ /spec/reports
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
+ --require spec_helper
2
+
1
3
  --color
2
4
  --format progress
3
- --order rand
@@ -4,20 +4,14 @@ env:
4
4
  global:
5
5
  - CC_TEST_REPORTER_ID=de7062a4090ce5638b515a2cf9f2ab619de3e3f4ff439dc6cdad025c7a8d6b76
6
6
  rvm:
7
- - 1.9.3
8
- - 2.0
9
- - 2.1
10
- - 2.2
11
- - 2.3
12
7
  - 2.4
13
8
  - 2.5
14
9
  - 2.6
15
10
  - 2.7
16
- - jruby-19mode
17
11
  - jruby
18
12
  cache: bundler
19
13
  before_install:
20
- - gem update --system --conservative || (gem i "rubygems-update:~>2.7" --no-document && update_rubygems) # see: https://github.com/rubygems/rubygems/issues/2534#issuecomment-448843746
14
+ - gem update --system --conservative
21
15
  - gem update bundler --conservative
22
16
  before_script:
23
17
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
@@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.0.0] 2020-01-27
9
+ ### Changed
10
+ - Require Ruby >= 2.4. We may still work with older Rubies, but no promises.
11
+ - Basic introspection support for a DumbDelegator instance: `#inspect`, `#method`, and `#methods`. [[13](https://github.com/stevenharman/dumb_delegator/pull/13)]
12
+
13
+ ### Added
14
+ - Optional support for using a DumbDelegator instance in a `case` statement. [[12](https://github.com/stevenharman/dumb_delegator/pull/12)]
15
+
8
16
  ## [0.8.1] 2020-01-25
9
17
  ### Changed
10
18
  - Explicitly Require Ruby >= 1.9.3
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in dumb_delegator.gemspec
4
4
  gemspec
5
5
 
6
- gem "simplecov", :group => :test, :require => nil
6
+ gem "simplecov", group: :test, require: nil
7
+ gem "pry-byebug", group: [:development, :test], platforms: [:ruby]
data/README.md CHANGED
@@ -5,11 +5,10 @@
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/b684cbe08af745cbe957/maintainability)](https://codeclimate.com/github/stevenharman/dumb_delegator/maintainability)
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/b684cbe08af745cbe957/test_coverage)](https://codeclimate.com/github/stevenharman/dumb_delegator/test_coverage)
7
7
 
8
-
9
8
  Ruby provides the `delegate` standard library.
10
9
  However, we found that it is not appropriate for cases that require nearly every call to be proxied.
11
10
 
12
- For instance, Rails uses `#class` and `#instance_of?` to introspect on model classes when generating forms and URL helpers.
11
+ For instance, Rails uses `#class` and `#instance_of?` to introspect on Model classes when generating forms and URL helpers.
13
12
  These methods are not forwarded when using `Delegator` or `SimpleDelegator`.
14
13
 
15
14
  ```ruby
@@ -42,16 +41,47 @@ d.class #=> MyAwesomeClass
42
41
  d.is_a? MyAwesomeClass #=> true
43
42
  ```
44
43
 
45
- ## Usage
44
+ ## Installation
46
45
 
47
- ### Rails Model Decorator
46
+ Add this line to your application's Gemfile:
48
47
 
49
- There are [many decorator implementations](http://robots.thoughtbot.com/post/14825364877/evaluating-alternative-decorator-implementations-in) in Ruby.
50
- One of the simplest is "`SimpleDelegator` + `super` + `__getobj__`," but it has the drawback of confusing Rails.
51
- It is necessary to redefine `#class`.
52
- We've also observed the need to redefine `#instance_of?` for URL helpers.
48
+ ```ruby
49
+ gem "dumb_delegator"
50
+ ```
51
+
52
+ And then execute:
53
+
54
+ ```bash
55
+ $ bundle
56
+ ```
57
+
58
+ Or install it yourself as:
59
+
60
+ ```bash
61
+ $ gem install dumb_delegator
62
+ ```
63
+
64
+ ### Versioning
65
+
66
+ This project adheres to [Semantic Versioning][semver].
67
+
68
+ #### Version `0.8.x`
69
+
70
+ The `0.8.0` release was downloaded 1.2MM times before the `1.0.0` work began.
71
+ Which is great.
72
+ But, we wanted to clean up some cruft, fix a few small things, and improve ergonomics.
73
+ And do all of that, while, hopefully, not breaking existing usage.
74
+
75
+ To that end, `1.0.0` dropped support for all [EoL'd Rubies][ruby-releases] and only officially supported Ruby `2.4` - `2.7` when it was released.
76
+ However, most older Rubies, _should_ still work.
77
+ Maybe… Shmaybe?
78
+ Except for Ruby 1.9, which probably _does not work_ with `DumbDelegator` `> 1.0.0`.
79
+ If you're on an EoL'd Ruby, please try the `0.8.x` versions of this gem.
80
+
81
+ ## Usage
53
82
 
54
- With `DumbDelegator`, there's not a need for this hackery because nearly every possible method is delegated:
83
+ `DumbDelegator`'s API and usage patters were inspired by Ruby stdlib's `SimpleDelegator`.
84
+ As such, the usage and ergonomics are quite similar.
55
85
 
56
86
  ```ruby
57
87
  require "dumb_delegator"
@@ -79,25 +109,73 @@ class Sugar < DumbDelegator
79
109
  end
80
110
 
81
111
  coffee = Coffee.new
82
- Sugar.new(Milk.new(coffee)).cost #=> 2.6
83
- Sugar.new(Sugar.new(coffee)).cost #=> 2.4
84
- Milk.new(coffee).origin #=> Colombia
85
- Sugar.new(Milk.new(coffee)).class #=> Coffee
112
+
113
+ cup_o_coffee = Sugar.new(Milk.new(coffee))
114
+ cup_o_coffee.origin #=> Colombia
115
+ cup_o_coffee.cost #=> 2.6
116
+
117
+ # Introspection
118
+ cup_o_coffee.class #=> Coffee
119
+ cup_o_coffee.__getobj__ #=> #<Coffee:0x00007fabed1d6910>
120
+ cup_o_coffee.inspect #=> "#<Sugar:70188197507600 obj: #<Milk:70188197507620 obj: #<Coffee:0x00007fabed1d6910>>>"
121
+ cup_o_coffee.is_a?(Coffee) #=> true
122
+ cup_o_coffee.is_a?(Milk) #=> true
123
+ cup_o_coffee.is_a?(Sugar) #=> true
86
124
  ```
87
125
 
88
- ## Installation
126
+ ### Rails Model Decorator
89
127
 
90
- Add this line to your application's Gemfile:
128
+ There are [many decorator implementations](http://robots.thoughtbot.com/post/14825364877/evaluating-alternative-decorator-implementations-in) in Ruby.
129
+ One of the simplest is "`SimpleDelegator` + `super` + `__getobj__`," but it has the drawback of confusing Rails.
130
+ It is necessary to redefine `#class`, at a minimum.
131
+ If you're relying on Rails' URL Helpers with a delegated object, you also need to redefine `#instance_of?`.
132
+ We've also observed the need to redefine other Rails-y methods to get various bits of 🧙 Rails Magic 🧙 to work as expected.
91
133
 
92
- gem "dumb_delegator"
134
+ With `DumbDelegator`, there's not a need for redefining these things because nearly every possible method is delegated.
93
135
 
94
- And then execute:
136
+ ### Optional `case` statement support
95
137
 
96
- $ bundle
138
+ Instances of `DumbDelegator` will delegate `#===` out of the box.
139
+ Meaning an instance can be used in a `case` statement so long as the `when` clauses rely on instance comparison.
140
+ For example, when using a `case` with a regular expression, range, etc...
97
141
 
98
- Or install it yourself as:
142
+ It's also common to use Class/Module in the `where` clauses.
143
+ In such usage, it's the Class/Module's `::===` method that gets called, rather than the `#===` method on the `DumbDelegator` instance.
144
+ That means we need to override each Class/Module's `::===` method, or even monkey-patch `::Module::===`.
145
+
146
+ `DumbDelegator` ships with an optional extension to override a Class/Module's `::===` method.
147
+ But you need to extend each Class/Module you use in a `where` clause.
148
+
149
+ ```ruby
150
+ def try_a_case(thing)
151
+ case thing
152
+ when MyAwesomeClass
153
+ "thing is a MyAwesomeClass."
154
+ when DumbDelegator
155
+ "thing is a DumbDelegator."
156
+ else
157
+ "Bad. This is bad."
158
+ end
159
+ end
160
+
161
+ target = MyAwesomeClass.new
162
+ dummy = DumbDelegator.new(target)
163
+
164
+ try_a_case(dummy) #=> thing is a DumbDelegator.
165
+
166
+ MyAwesomeClass.extend(DumbDelegator::TripleEqualExt)
167
+
168
+ try_a_case(dummy) #=> thing is a MyAwesomeClass.
169
+ ```
99
170
 
100
- $ gem install dumb_delegator
171
+ #### Overriding `Module::===`
172
+ If necessary, you could also override the base `Module::===`, though that's pretty invasive.
173
+
174
+ 🐲 _There be dragons!_ 🐉
175
+
176
+ ```ruby
177
+ ::Module.extend(DumbDelegator::TripleEqualExt)
178
+ ```
101
179
 
102
180
  ## Contributing
103
181
 
@@ -110,3 +188,7 @@ Or install it yourself as:
110
188
  ## Contribution Ideas/Needs
111
189
 
112
190
  1. Ruby 1.8 support (use the `blankslate` gem?)
191
+
192
+
193
+ [ruby-releases]: https://www.ruby-lang.org/en/downloads/branches/ "The current maintenance status of the various Ruby branches"
194
+ [semver]: https://semver.org/spec/v2.0.0.html "Semantic Versioning 2.0.0"
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
2
+ require "bundler/gem_tasks"
3
3
 
4
- require 'rspec/core/rake_task'
4
+ require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:spec) do |t|
6
- t.rspec_opts = '--tag ~objectspace' if RUBY_PLATFORM == 'java'
6
+ t.rspec_opts = "--tag ~objectspace" if RUBY_PLATFORM == "java"
7
7
  end
8
8
 
9
- task :default => :spec
9
+ task default: :spec
@@ -1,22 +1,31 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/dumb_delegator/version', __FILE__)
1
+ require File.expand_path("../lib/dumb_delegator/version", __FILE__)
3
2
 
4
3
  Gem::Specification.new do |gem|
5
4
  gem.name = "dumb_delegator"
6
5
  gem.version = DumbDelegator::VERSION
7
- gem.required_ruby_version = ">= 1.9.3"
8
- gem.authors = ['Andy Lindeman', 'Steven Harman']
9
- gem.email = ['alindeman@gmail.com', 'steven@harmanly.com']
10
- gem.description = %q{Delegator class that delegates ALL the things}
11
- gem.summary = <<-EOD
12
- Delegator and SimpleDelegator in Ruby's stdlib are somewhat useful, but they pull in most of Kernel. This is not appropriate for many uses; for instance, delegation to Rails models.
6
+ gem.required_ruby_version = ">= 2.4.0"
7
+ gem.authors = ["Andy Lindeman", "Steven Harman"]
8
+ gem.email = ["alindeman@gmail.com", "steven@harmanly.com"]
9
+ gem.licenses = ["MIT"]
10
+ gem.summary = "Delegator class that delegates ALL the things"
11
+ gem.description = <<~EOD
12
+ Delegator and SimpleDelegator in Ruby's stdlib are useful, but they pull in most of Kernel.
13
+ This is not appropriate for many uses; for instance, delegation to Rails Models.
14
+ DumbDelegator, on the other hand, delegates nearly everything to the wrapped object.
13
15
  EOD
14
- gem.homepage = 'https://github.com/stevenharman/dumb_delegator'
16
+ gem.homepage = "https://github.com/stevenharman/dumb_delegator"
15
17
 
16
- gem.files = `git ls-files`.split($\)
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ['lib']
18
+ gem.metadata = {
19
+ "changelog_uri" => "https://github.com/stevenharman/dumb_delegator/blob/master/CHANGELOG.md",
20
+ "documentation_uri" => "https://rubydoc.info/gems/dumb_delegator",
21
+ "source_code_uri" => "https://github.com/stevenharman/dumb_delegator",
22
+ }
19
23
 
20
- gem.add_development_dependency 'rake', '~> 10.0'
21
- gem.add_development_dependency 'rspec', '~> 3.4'
24
+ gem.files = `git ls-files`.split($\)
25
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
26
+ gem.require_paths = ["lib"]
27
+
28
+ gem.add_development_dependency "pry"
29
+ gem.add_development_dependency "rake", "~> 13.0"
30
+ gem.add_development_dependency "rspec", "~> 3.9"
22
31
  end
@@ -1,13 +1,48 @@
1
- require 'dumb_delegator/version'
1
+ require "dumb_delegator/triple_equal_ext"
2
+ require "dumb_delegator/version"
2
3
 
4
+ ##
5
+ # @example
6
+ # class Coffee
7
+ # def cost
8
+ # 2
9
+ # end
10
+ #
11
+ # def origin
12
+ # "Colombia"
13
+ # end
14
+ # end
15
+ #
16
+ # class Milk < DumbDelegator
17
+ # def cost
18
+ # super + 0.4
19
+ # end
20
+ # end
21
+ #
22
+ # class Sugar < DumbDelegator
23
+ # def cost
24
+ # super + 0.2
25
+ # end
26
+ # end
27
+ #
28
+ # coffee = Coffee.new
29
+ # Milk.new(coffee).origin #=> Colombia
30
+ # Sugar.new(Sugar.new(coffee)).cost #=> 2.4
31
+ #
32
+ # cup_o_coffee = Sugar.new(Milk.new(coffee))
33
+ # cup_o_coffee.cost #=> 2.6
34
+ # cup_o_coffee.class #=> Coffee
35
+ # cup_o_coffee.is_a?(Coffee) #=> true
36
+ # cup_o_coffee.is_a?(Milk) #=> true
37
+ # cup_o_coffee.is_a?(Sugar) #=> true
3
38
  class DumbDelegator < ::BasicObject
4
39
  (::BasicObject.instance_methods - [:equal?, :__id__, :__send__, :method_missing]).each do |method|
5
- undef_method method
40
+ undef_method(method)
6
41
  end
7
42
 
8
43
  kernel = ::Kernel.dup
9
- (kernel.instance_methods - [:dup, :clone, :respond_to?, :object_id]).each do |method|
10
- kernel.__send__ :undef_method, method
44
+ (kernel.instance_methods - [:dup, :clone, :method, :methods, :respond_to?, :object_id]).each do |method|
45
+ kernel.__send__(:undef_method, method)
11
46
  end
12
47
  include kernel
13
48
 
@@ -15,8 +50,12 @@ class DumbDelegator < ::BasicObject
15
50
  __setobj__(target)
16
51
  end
17
52
 
18
- def respond_to?(method, include_all=false)
19
- __getobj__.respond_to?(method) || super
53
+ def inspect
54
+ "#<#{(class << self; self; end).superclass}:#{object_id} obj: #{__getobj__.inspect}>"
55
+ end
56
+
57
+ def methods(all = true)
58
+ __getobj__.methods(all) | super
20
59
  end
21
60
 
22
61
  def method_missing(method, *args, &block)
@@ -27,19 +66,25 @@ class DumbDelegator < ::BasicObject
27
66
  end
28
67
  end
29
68
 
69
+ def respond_to_missing?(method, include_private = false)
70
+ __getobj__.respond_to?(method, include_private) || super
71
+ end
72
+
73
+ # @return [Object] The object calls are being delegated to
30
74
  def __getobj__
31
75
  @__dumb_target__
32
76
  end
33
77
 
78
+ # @param obj [Object] Change the object delegate to +obj+.
34
79
  def __setobj__(obj)
35
- raise ::ArgumentError, 'Delegation to self is not allowed.' if obj.__id__ == __id__
80
+ raise ::ArgumentError, "Delegation to self is not allowed." if obj.__id__ == __id__
36
81
  @__dumb_target__ = obj
37
82
  end
38
83
 
39
84
  def marshal_dump
40
85
  [
41
86
  :__v1__,
42
- __getobj__
87
+ __getobj__,
43
88
  ]
44
89
  end
45
90
 
@@ -0,0 +1,29 @@
1
+ class DumbDelegator < ::BasicObject
2
+ ##
3
+ # This optional extension enables a Class/Module to support +case+ statements.
4
+ #
5
+ # Specifically, it monkey-patches a Class/Module's +:===+ method to check if the +other+ argument is an instance of the extended Class/Module.
6
+ #
7
+ # @example Extending a Class/Module to handle class equality for a DumbDelegator instance.
8
+ #
9
+ # target = MyAwesomeClass.new
10
+ # dummy = DumbDelegator.new(target)
11
+ #
12
+ # MyAwesomeClass === dummy #=> false
13
+ # DumbDelegator === dummy #=> true
14
+ #
15
+ # MyAwesomeClass.extend(DumbDelegator::TripleEqualExt)
16
+ #
17
+ # MyAwesomeClass === dummy #=> true
18
+ # DumbDelegator === dummy #=> true
19
+ module TripleEqualExt
20
+ # Case equality for the extended Class/Module and then given +other+.
21
+ #
22
+ # @param other [Object] An instance of any Object
23
+ #
24
+ # @return [Boolean] If the +other+ is an instance of the Class/Module.
25
+ def ===(other)
26
+ super || other.is_a?(self)
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  class DumbDelegator < ::BasicObject
2
- VERSION = "0.8.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe DumbDelegator do
1
+ RSpec.describe DumbDelegator do
4
2
  subject(:dummy) { Wrapper.new(target) }
5
3
  let(:target) { Target.new }
6
4
 
@@ -55,8 +53,6 @@ describe DumbDelegator do
55
53
  end
56
54
 
57
55
  it "responds to methods defined by child classes" do
58
- expect(target).to receive(:wrapper_method).never
59
-
60
56
  expect(dummy.wrapper_method).to eq("Method only on wrapper.")
61
57
  end
62
58
 
@@ -85,51 +81,76 @@ describe DumbDelegator do
85
81
  end
86
82
 
87
83
  it "delegates object equivalence" do
88
- expect(dummy).to eql(target)
89
- expect(dummy == target).to be true
84
+ aggregate_failures do
85
+ expect(dummy).to eql(target)
86
+ expect(dummy == target).to be true
87
+ end
88
+ end
89
+
90
+ it "delegates #===" do
91
+ expect(dummy === target).to be true
90
92
  end
91
93
 
92
94
  it "delegates class checks" do
93
- expect(dummy.is_a?(Target)).to be(true)
94
- expect(dummy.kind_of?(Target)).to be(true) # rubocop:disable Style/ClassCheck
95
- expect(dummy.instance_of?(Target)).to be(true)
95
+ aggregate_failures do
96
+ expect(dummy.is_a?(Target)).to be(true)
97
+ expect(dummy.kind_of?(Target)).to be(true) # rubocop:disable Style/ClassCheck
98
+ expect(dummy.instance_of?(Target)).to be(true)
99
+ end
96
100
  end
97
101
 
98
- it "delegates ===" do
99
- pending("Implement #=== on DumbDelegator")
100
- expect(dummy === Target).to be true
102
+ it "does not delegate ::=== to the target's class" do
103
+ aggregate_failures do
104
+ expect(Target === dummy).to be false
105
+ expect(DumbDelegator === dummy).to be true
106
+ end
101
107
  end
102
108
 
103
- it 'delegates instance_eval' do
109
+ context "with a Module/Class's ::=== overridden via extension" do
110
+ let(:target) { TargetWithTripleEqualExt.new }
111
+
112
+ class TargetWithTripleEqualExt
113
+ extend DumbDelegator::TripleEqualExt
114
+ end
115
+
116
+ it "delegates ::=== to the target's class" do
117
+ aggregate_failures do
118
+ expect(TargetWithTripleEqualExt === dummy).to be true
119
+ expect(DumbDelegator === dummy).to be true
120
+ end
121
+ end
122
+ end
123
+
124
+ it "delegates instance_eval" do
104
125
  expect(target).to receive(:instance_eval)
105
126
  dummy.instance_eval { true }
106
127
  end
107
128
 
108
- it 'delegates instance_exec' do
129
+ it "delegates instance_exec" do
109
130
  expect(target).to receive(:instance_exec)
110
131
  dummy.instance_exec { true }
111
132
  end
112
133
 
113
- describe '#dup' do
114
- it 'returns a shallow of itself, the delegator (not the underlying object)', :objectspace => true do
134
+ describe "#dup" do
135
+ it "returns a shallow of itself, the delegator (not the underlying object)", objectspace: true do
115
136
  dupped = dummy.dup
116
137
 
117
138
  expect(ObjectSpace.each_object(DumbDelegator).map(&:__id__)).to include dupped.__id__
118
139
  end
119
140
  end
120
141
 
121
- describe '#clone' do
122
- it 'returns a shallow of itself, the delegator (not the underlying object)', :objectspace => true do
142
+ describe "#clone" do
143
+ it "returns a shallow of itself, the delegator (not the underlying object)", objectspace: true do
123
144
  cloned = dummy.clone
124
145
 
125
146
  expect(ObjectSpace.each_object(DumbDelegator).map(&:__id__)).to include cloned.__id__
126
147
  end
127
148
  end
128
149
 
129
- describe 'marshaling' do
150
+ describe "marshaling" do
130
151
  let(:target) { Object.new }
131
152
 
132
- it 'marshals and unmarshals itself, the delegator (not the underlying object)', :objectspace => true do
153
+ it "marshals and unmarshals itself, the delegator (not the underlying object)", objectspace: true do
133
154
  marshaled = Marshal.dump(dummy)
134
155
  unmarshaled = Marshal.load(marshaled)
135
156
 
@@ -137,7 +158,7 @@ describe DumbDelegator do
137
158
  end
138
159
  end
139
160
 
140
- describe '#respond_to?' do
161
+ describe "#respond_to?" do
141
162
  [:equal?, :__id__, :__send__, :dup, :clone, :__getobj__, :__setobj__, :marshal_dump, :marshal_load, :respond_to?].each do |method|
142
163
  it "responds to #{method}" do
143
164
  expect(dummy.respond_to?(method)).to be true
@@ -157,22 +178,53 @@ describe DumbDelegator do
157
178
  end
158
179
  end
159
180
 
160
- describe '#__setobj__' do
161
- it 'resets the target object to a different object' do
162
- expect(target).to receive(:foo).never
163
-
164
- new_target = double
165
- expect(new_target).to receive(:foo)
181
+ describe "#__setobj__" do
182
+ it "resets the target object to a different object" do
183
+ new_target = Target.new.tap do |nt|
184
+ def nt.a_new_thing
185
+ true
186
+ end
187
+ end
166
188
 
167
189
  dummy.__setobj__(new_target)
168
- dummy.foo
190
+ expect(dummy.a_new_thing).to be true
169
191
  end
170
192
 
171
- it 'cannot delegate to itself' do
193
+ it "cannot delegate to itself" do
172
194
  expect {
173
195
  dummy.__setobj__(dummy)
174
- dummy.foo
175
- }.to raise_error(ArgumentError, 'Delegation to self is not allowed.')
196
+ dummy.common_method
197
+ }.to raise_error(ArgumentError, "Delegation to self is not allowed.")
198
+ end
199
+ end
200
+
201
+ describe "introspection capabilities" do
202
+ it "provides a human-friendly representation of the delegator and wrapped object" do
203
+ expect(dummy.inspect).to match(/#<Wrapper:\w+ obj: .+Target.+>/)
204
+ end
205
+
206
+ it "reports methods defined on the target" do
207
+ expect(dummy.methods).to include(:target_method, :common_method)
208
+ end
209
+
210
+ it "reports methods defined on the wrapper" do
211
+ expect(dummy.methods).to include(:wrapper_method, :common_method)
212
+ end
213
+
214
+ it "looks up a named method on the target" do
215
+ method = dummy.method(:target_method)
216
+ aggregate_failures do
217
+ expect(method).not_to be_nil
218
+ expect(method.receiver).to eq(target)
219
+ end
220
+ end
221
+
222
+ it "looks up a named method on the wrapper" do
223
+ method = dummy.method(:wrapper_method)
224
+ aggregate_failures do
225
+ expect(method).not_to be_nil
226
+ expect(method.receiver).to equal(dummy)
227
+ end
176
228
  end
177
229
  end
178
230
  end
@@ -1,11 +1,38 @@
1
- if ENV["CODECLIMATE_REPO_TOKEN"]
1
+ if ENV["CC_TEST_REPORTER_ID"] || ENV["COVERAGE"]
2
2
  require "simplecov"
3
3
  SimpleCov.start
4
4
  end
5
5
 
6
- require File.expand_path('../lib/dumb_delegator', File.dirname(__FILE__))
6
+ require "pry"
7
+ require File.expand_path("../lib/dumb_delegator", File.dirname(__FILE__))
7
8
 
8
9
  RSpec.configure do |config|
9
- config.run_all_when_everything_filtered = true
10
- config.filter_run :focus
10
+ config.expect_with :rspec do |expectations|
11
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
12
+ end
13
+
14
+ config.mock_with :rspec do |mocks|
15
+ mocks.verify_partial_doubles = true
16
+ end
17
+
18
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
19
+ # have no way to turn it off -- the option exists only for backwards
20
+ # compatibility in RSpec 3). It causes shared context metadata to be
21
+ # inherited by the metadata hash of host groups and examples, rather than
22
+ # triggering implicit auto-inclusion in groups with matching metadata.
23
+ config.shared_context_metadata_behavior = :apply_to_host_groups
24
+
25
+ config.filter_run_when_matching :focus
26
+ config.example_status_persistence_file_path = "spec/rspec-status.txt"
27
+ config.disable_monkey_patching!
28
+ config.warnings = true
29
+
30
+ if config.files_to_run.one?
31
+ # Use the documentation formatter for detailed output,
32
+ # unless a formatter has already been configured
33
+ # (e.g. via a command-line flag).
34
+ config.default_formatter = "doc"
35
+ end
36
+ config.order = :random
37
+ Kernel.srand config.seed
11
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dumb_delegator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Lindeman
@@ -9,37 +9,54 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-01-26 00:00:00.000000000 Z
12
+ date: 2020-01-28 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: pry
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: rake
16
30
  requirement: !ruby/object:Gem::Requirement
17
31
  requirements:
18
32
  - - "~>"
19
33
  - !ruby/object:Gem::Version
20
- version: '10.0'
34
+ version: '13.0'
21
35
  type: :development
22
36
  prerelease: false
23
37
  version_requirements: !ruby/object:Gem::Requirement
24
38
  requirements:
25
39
  - - "~>"
26
40
  - !ruby/object:Gem::Version
27
- version: '10.0'
41
+ version: '13.0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: rspec
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - "~>"
33
47
  - !ruby/object:Gem::Version
34
- version: '3.4'
48
+ version: '3.9'
35
49
  type: :development
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - "~>"
40
54
  - !ruby/object:Gem::Version
41
- version: '3.4'
42
- description: Delegator class that delegates ALL the things
55
+ version: '3.9'
56
+ description: |
57
+ Delegator and SimpleDelegator in Ruby's stdlib are useful, but they pull in most of Kernel.
58
+ This is not appropriate for many uses; for instance, delegation to Rails Models.
59
+ DumbDelegator, on the other hand, delegates nearly everything to the wrapped object.
43
60
  email:
44
61
  - alindeman@gmail.com
45
62
  - steven@harmanly.com
@@ -57,12 +74,17 @@ files:
57
74
  - Rakefile
58
75
  - dumb_delegator.gemspec
59
76
  - lib/dumb_delegator.rb
77
+ - lib/dumb_delegator/triple_equal_ext.rb
60
78
  - lib/dumb_delegator/version.rb
61
79
  - spec/dumb_delegator_spec.rb
62
80
  - spec/spec_helper.rb
63
81
  homepage: https://github.com/stevenharman/dumb_delegator
64
- licenses: []
65
- metadata: {}
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ changelog_uri: https://github.com/stevenharman/dumb_delegator/blob/master/CHANGELOG.md
86
+ documentation_uri: https://rubydoc.info/gems/dumb_delegator
87
+ source_code_uri: https://github.com/stevenharman/dumb_delegator
66
88
  post_install_message:
67
89
  rdoc_options: []
68
90
  require_paths:
@@ -71,19 +93,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
93
  requirements:
72
94
  - - ">="
73
95
  - !ruby/object:Gem::Version
74
- version: 1.9.3
96
+ version: 2.4.0
75
97
  required_rubygems_version: !ruby/object:Gem::Requirement
76
98
  requirements:
77
99
  - - ">="
78
100
  - !ruby/object:Gem::Version
79
101
  version: '0'
80
102
  requirements: []
81
- rubygems_version: 3.0.6
103
+ rubygems_version: 3.0.3
82
104
  signing_key:
83
105
  specification_version: 4
84
- summary: Delegator and SimpleDelegator in Ruby's stdlib are somewhat useful, but they
85
- pull in most of Kernel. This is not appropriate for many uses; for instance, delegation
86
- to Rails models.
106
+ summary: Delegator class that delegates ALL the things
87
107
  test_files:
88
108
  - spec/dumb_delegator_spec.rb
89
109
  - spec/spec_helper.rb