dumb_delegator 0.8.0 → 0.8.1
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 +5 -5
- data/.travis.yml +25 -8
- data/CHANGELOG.md +13 -0
- data/Gemfile +1 -1
- data/README.md +28 -30
- data/dumb_delegator.gemspec +5 -5
- data/lib/dumb_delegator/version.rb +1 -1
- data/spec/dumb_delegator_spec.rb +74 -51
- data/spec/spec_helper.rb +3 -4
- metadata +8 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 63674a3e04272740045c64f5cd122fb431c333be76ffb7f5364067e28f31ef44
|
4
|
+
data.tar.gz: 8b6ad9d8f119f2e8092e9fd5027ea076a41420ab76ea3555587577a12b234027
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5c94e20a372ff9fb834e9efe3b9bf922bc3539af15bab58aafa1fd5d8403a31b8de7728d7a6fdd7d8a90558333a2b326b866549156af3405049d811ac9b9bce
|
7
|
+
data.tar.gz: 180f72c3eb297c0ea3e14f36dd87d9c13951316371f4d3d0c6eeb70e09812b4d7ee509fae5515e4559be3969612fced9da7adaa4cb5b2c4ea8459d9b77c179fd
|
data/.travis.yml
CHANGED
@@ -1,12 +1,29 @@
|
|
1
1
|
language: ruby
|
2
|
+
dist: xenial
|
3
|
+
env:
|
4
|
+
global:
|
5
|
+
- CC_TEST_REPORTER_ID=de7062a4090ce5638b515a2cf9f2ab619de3e3f4ff439dc6cdad025c7a8d6b76
|
2
6
|
rvm:
|
3
7
|
- 1.9.3
|
4
|
-
- 2.0
|
5
|
-
- 2.1
|
8
|
+
- 2.0
|
9
|
+
- 2.1
|
10
|
+
- 2.2
|
11
|
+
- 2.3
|
12
|
+
- 2.4
|
13
|
+
- 2.5
|
14
|
+
- 2.6
|
15
|
+
- 2.7
|
6
16
|
- jruby-19mode
|
7
|
-
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
- jruby
|
18
|
+
cache: bundler
|
19
|
+
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
|
21
|
+
- gem update bundler --conservative
|
22
|
+
before_script:
|
23
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
24
|
+
- chmod +x ./cc-test-reporter
|
25
|
+
- ./cc-test-reporter before-build
|
26
|
+
script:
|
27
|
+
- bundle exec rake spec
|
28
|
+
after_script:
|
29
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
|
5
|
+
|
6
|
+
## [Unreleased]
|
7
|
+
|
8
|
+
## [0.8.1] 2020-01-25
|
9
|
+
### Changed
|
10
|
+
- Explicitly Require Ruby >= 1.9.3
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- This CHANGELOG file.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
# DumbDelegator
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/dumb_delegator)
|
4
|
+
[](https://travis-ci.org/stevenharman/dumb_delegator)
|
5
|
+
[](https://codeclimate.com/github/stevenharman/dumb_delegator/maintainability)
|
6
|
+
[](https://codeclimate.com/github/stevenharman/dumb_delegator/test_coverage)
|
7
7
|
|
8
|
-
Ruby provides the `delegate` standard library. However, we found that it is not
|
9
|
-
appropriate for many use cases that require nearly every call to be proxied.
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
Ruby provides the `delegate` standard library.
|
10
|
+
However, we found that it is not appropriate for cases that require nearly every call to be proxied.
|
11
|
+
|
12
|
+
For instance, Rails uses `#class` and `#instance_of?` to introspect on model classes when generating forms and URL helpers.
|
13
|
+
These methods are not forwarded when using `Delegator` or `SimpleDelegator`.
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
require
|
16
|
+
require "delegate"
|
17
17
|
|
18
18
|
class MyAwesomeClass
|
19
19
|
# ...
|
@@ -22,14 +22,14 @@ end
|
|
22
22
|
o = MyAwesomeClass.new
|
23
23
|
d = SimpleDelegator.new(o)
|
24
24
|
|
25
|
-
d.class
|
26
|
-
d.is_a? MyAwesomeClass
|
25
|
+
d.class #=> SimpleDelegator
|
26
|
+
d.is_a? MyAwesomeClass #=> false
|
27
27
|
```
|
28
28
|
|
29
|
-
`DumbDelegator`, on the other hand, forwards almost ALL
|
29
|
+
`DumbDelegator`, on the other hand, forwards almost ALL THE THINGS:
|
30
30
|
|
31
31
|
```ruby
|
32
|
-
require
|
32
|
+
require "dumb_delegator"
|
33
33
|
|
34
34
|
class MyAwesomeClass
|
35
35
|
# ...
|
@@ -38,25 +38,23 @@ end
|
|
38
38
|
o = MyAwesomeClass.new
|
39
39
|
d = DumbDelegator.new(o)
|
40
40
|
|
41
|
-
d.class
|
42
|
-
d.is_a? MyAwesomeClass
|
41
|
+
d.class #=> MyAwesomeClass
|
42
|
+
d.is_a? MyAwesomeClass #=> true
|
43
43
|
```
|
44
44
|
|
45
45
|
## Usage
|
46
46
|
|
47
47
|
### Rails Model Decorator
|
48
48
|
|
49
|
-
There are [many decorator
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
also observed the need to redefine `instance_of?` for URL helpers.
|
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.
|
54
53
|
|
55
|
-
With `DumbDelegator`, there's not a need for this hackery because nearly every
|
56
|
-
possible method is delegated:
|
54
|
+
With `DumbDelegator`, there's not a need for this hackery because nearly every possible method is delegated:
|
57
55
|
|
58
56
|
```ruby
|
59
|
-
require
|
57
|
+
require "dumb_delegator"
|
60
58
|
|
61
59
|
class Coffee
|
62
60
|
def cost
|
@@ -64,7 +62,7 @@ class Coffee
|
|
64
62
|
end
|
65
63
|
|
66
64
|
def origin
|
67
|
-
|
65
|
+
"Colombia"
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
@@ -81,17 +79,17 @@ class Sugar < DumbDelegator
|
|
81
79
|
end
|
82
80
|
|
83
81
|
coffee = Coffee.new
|
84
|
-
Sugar.new(Milk.new(coffee)).cost
|
85
|
-
Sugar.new(Sugar.new(coffee)).cost
|
86
|
-
Milk.new(coffee).origin
|
87
|
-
Sugar.new(Milk.new(coffee)).class
|
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
|
88
86
|
```
|
89
87
|
|
90
88
|
## Installation
|
91
89
|
|
92
90
|
Add this line to your application's Gemfile:
|
93
91
|
|
94
|
-
gem
|
92
|
+
gem "dumb_delegator"
|
95
93
|
|
96
94
|
And then execute:
|
97
95
|
|
data/dumb_delegator.gemspec
CHANGED
@@ -2,8 +2,11 @@
|
|
2
2
|
require File.expand_path('../lib/dumb_delegator/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "dumb_delegator"
|
6
|
+
gem.version = DumbDelegator::VERSION
|
7
|
+
gem.required_ruby_version = ">= 1.9.3"
|
5
8
|
gem.authors = ['Andy Lindeman', 'Steven Harman']
|
6
|
-
gem.email = ['alindeman@gmail.com', '
|
9
|
+
gem.email = ['alindeman@gmail.com', 'steven@harmanly.com']
|
7
10
|
gem.description = %q{Delegator class that delegates ALL the things}
|
8
11
|
gem.summary = <<-EOD
|
9
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.
|
@@ -12,11 +15,8 @@ Gem::Specification.new do |gem|
|
|
12
15
|
|
13
16
|
gem.files = `git ls-files`.split($\)
|
14
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
-
gem.name = 'dumb_delegator'
|
16
18
|
gem.require_paths = ['lib']
|
17
|
-
gem.version = DumbDelegator::VERSION
|
18
19
|
|
19
|
-
gem.add_development_dependency 'pry'
|
20
20
|
gem.add_development_dependency 'rake', '~> 10.0'
|
21
|
-
gem.add_development_dependency 'rspec', '~> 3.
|
21
|
+
gem.add_development_dependency 'rspec', '~> 3.4'
|
22
22
|
end
|
data/spec/dumb_delegator_spec.rb
CHANGED
@@ -1,78 +1,103 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe DumbDelegator do
|
4
|
-
subject(:dummy) {
|
5
|
-
let(:target) {
|
4
|
+
subject(:dummy) { Wrapper.new(target) }
|
5
|
+
let(:target) { Target.new }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
class Wrapper < DumbDelegator
|
8
|
+
def wrapper_method
|
9
|
+
"Method only on wrapper."
|
10
|
+
end
|
11
|
+
|
12
|
+
def common_method
|
13
|
+
["Method on wrapper.", super].join(" ")
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
|
-
|
13
|
-
|
17
|
+
class Target
|
18
|
+
def common_method
|
19
|
+
"Method on target."
|
20
|
+
end
|
21
|
+
|
22
|
+
def target_method
|
23
|
+
"Method only on target."
|
24
|
+
end
|
25
|
+
|
26
|
+
def query(*args)
|
27
|
+
"queried with #{args}"
|
28
|
+
end
|
14
29
|
|
15
|
-
|
30
|
+
def with_block(&block)
|
31
|
+
block.call
|
32
|
+
end
|
16
33
|
end
|
17
34
|
|
18
|
-
it
|
19
|
-
|
20
|
-
|
35
|
+
it "delegates to the target object" do
|
36
|
+
expect(dummy.target_method).to eq("Method only on target.")
|
37
|
+
end
|
21
38
|
|
22
|
-
|
39
|
+
it "delegates to the target object with arguments" do
|
40
|
+
result = dummy.query("some_key", 42)
|
41
|
+
|
42
|
+
expect(result).to eq(%(queried with ["some_key", 42]))
|
23
43
|
end
|
24
44
|
|
25
|
-
it
|
26
|
-
|
27
|
-
|
45
|
+
it "delegates to the target object with a block" do
|
46
|
+
result = dummy.with_block { "block called!" }
|
47
|
+
|
48
|
+
expect(result).to eq("block called!")
|
49
|
+
end
|
28
50
|
|
51
|
+
it "errors if the method is not defined on the wrapper nor the target" do
|
29
52
|
expect {
|
30
|
-
dummy.
|
53
|
+
dummy.no_such_method
|
31
54
|
}.to raise_error(NoMethodError)
|
32
55
|
end
|
33
56
|
|
34
|
-
it
|
35
|
-
expect(target).to receive(:
|
36
|
-
def dummy.foo
|
37
|
-
'bar'
|
38
|
-
end
|
57
|
+
it "responds to methods defined by child classes" do
|
58
|
+
expect(target).to receive(:wrapper_method).never
|
39
59
|
|
40
|
-
dummy.
|
60
|
+
expect(dummy.wrapper_method).to eq("Method only on wrapper.")
|
41
61
|
end
|
42
62
|
|
43
|
-
it
|
44
|
-
expect(
|
45
|
-
dummy.class
|
63
|
+
it "responds to methods defined by child classes, and can super up to target" do
|
64
|
+
expect(dummy.common_method).to eq("Method on wrapper. Method on target.")
|
46
65
|
end
|
47
66
|
|
48
|
-
it
|
49
|
-
expect(
|
50
|
-
dummy.is_a?
|
67
|
+
it "delegates methods defined on Object" do
|
68
|
+
expect(dummy.class).to eq(Target)
|
51
69
|
end
|
52
70
|
|
53
|
-
it
|
54
|
-
expect(target).to receive(:
|
55
|
-
dummy.
|
71
|
+
it "delegates methods defined on Kernel" do
|
72
|
+
expect(target).to receive(:nil?)
|
73
|
+
dummy.nil?
|
56
74
|
end
|
57
75
|
|
58
|
-
it
|
59
|
-
|
60
|
-
!dummy
|
76
|
+
it "delegates bang (!) operator" do
|
77
|
+
allow(target).to receive(:!) { "bang!" }
|
78
|
+
expect(!dummy).to eq("bang!")
|
61
79
|
end
|
62
80
|
|
63
|
-
it
|
64
|
-
|
65
|
-
|
81
|
+
it "delegates object inequivalence" do
|
82
|
+
allow(target).to receive(:!=).and_call_original
|
83
|
+
|
84
|
+
expect(dummy != target).to be false
|
85
|
+
end
|
86
|
+
|
87
|
+
it "delegates object equivalence" do
|
88
|
+
expect(dummy).to eql(target)
|
89
|
+
expect(dummy == target).to be true
|
66
90
|
end
|
67
91
|
|
68
|
-
it
|
69
|
-
expect(
|
70
|
-
dummy
|
92
|
+
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)
|
71
96
|
end
|
72
97
|
|
73
|
-
it
|
74
|
-
|
75
|
-
dummy
|
98
|
+
it "delegates ===" do
|
99
|
+
pending("Implement #=== on DumbDelegator")
|
100
|
+
expect(dummy === Target).to be true
|
76
101
|
end
|
77
102
|
|
78
103
|
it 'delegates instance_eval' do
|
@@ -119,18 +144,16 @@ describe DumbDelegator do
|
|
119
144
|
end
|
120
145
|
end
|
121
146
|
|
122
|
-
context
|
123
|
-
|
124
|
-
|
125
|
-
it 'respond to methods defined on the subclass' do
|
126
|
-
expect(dummy.respond_to?(:foobar)).to be true
|
147
|
+
context "subclasses of DumbDelegator" do
|
148
|
+
it "respond to methods defined on the subclass" do
|
149
|
+
expect(dummy).to respond_to(:target_method)
|
127
150
|
end
|
128
151
|
end
|
129
152
|
end
|
130
153
|
|
131
|
-
describe
|
132
|
-
it
|
133
|
-
expect(dummy.__getobj__).to equal
|
154
|
+
describe "#__getobj__" do
|
155
|
+
it "returns the target object" do
|
156
|
+
expect(dummy.__getobj__).to equal(target)
|
134
157
|
end
|
135
158
|
end
|
136
159
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
if ENV[
|
2
|
-
require
|
3
|
-
|
1
|
+
if ENV["CODECLIMATE_REPO_TOKEN"]
|
2
|
+
require "simplecov"
|
3
|
+
SimpleCov.start
|
4
4
|
end
|
5
5
|
|
6
6
|
require File.expand_path('../lib/dumb_delegator', File.dirname(__FILE__))
|
7
|
-
require 'pry'
|
8
7
|
|
9
8
|
RSpec.configure do |config|
|
10
9
|
config.run_all_when_everything_filtered = true
|
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.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Lindeman
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-01-26 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'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: rake
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,18 +31,18 @@ dependencies:
|
|
45
31
|
requirements:
|
46
32
|
- - "~>"
|
47
33
|
- !ruby/object:Gem::Version
|
48
|
-
version: '3.
|
34
|
+
version: '3.4'
|
49
35
|
type: :development
|
50
36
|
prerelease: false
|
51
37
|
version_requirements: !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
39
|
- - "~>"
|
54
40
|
- !ruby/object:Gem::Version
|
55
|
-
version: '3.
|
41
|
+
version: '3.4'
|
56
42
|
description: Delegator class that delegates ALL the things
|
57
43
|
email:
|
58
44
|
- alindeman@gmail.com
|
59
|
-
-
|
45
|
+
- steven@harmanly.com
|
60
46
|
executables: []
|
61
47
|
extensions: []
|
62
48
|
extra_rdoc_files: []
|
@@ -64,6 +50,7 @@ files:
|
|
64
50
|
- ".gitignore"
|
65
51
|
- ".rspec"
|
66
52
|
- ".travis.yml"
|
53
|
+
- CHANGELOG.md
|
67
54
|
- Gemfile
|
68
55
|
- LICENSE
|
69
56
|
- README.md
|
@@ -84,15 +71,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
71
|
requirements:
|
85
72
|
- - ">="
|
86
73
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
74
|
+
version: 1.9.3
|
88
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
76
|
requirements:
|
90
77
|
- - ">="
|
91
78
|
- !ruby/object:Gem::Version
|
92
79
|
version: '0'
|
93
80
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.4.2
|
81
|
+
rubygems_version: 3.0.6
|
96
82
|
signing_key:
|
97
83
|
specification_version: 4
|
98
84
|
summary: Delegator and SimpleDelegator in Ruby's stdlib are somewhat useful, but they
|
@@ -101,4 +87,3 @@ summary: Delegator and SimpleDelegator in Ruby's stdlib are somewhat useful, but
|
|
101
87
|
test_files:
|
102
88
|
- spec/dumb_delegator_spec.rb
|
103
89
|
- spec/spec_helper.rb
|
104
|
-
has_rdoc:
|