-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This module adds three methods to decorate an object. Decorator class is being inferred automatically. When no decorator is found, * `#decorate` returns `nil`, * `#decorate!` raises `Magic::Lookup::Error`, * `#decorated` returns the original object. One can test if the object is actually decorated with `#decorated?`. `Decoratable` is mixed into `Object` by default.
- Loading branch information
1 parent
1c12ea7
commit 59a20b1
Showing
6 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# frozen_string_literal: true | ||
|
||
module Magic | ||
module Decoratable | ||
def decorate = decorator&.new self | ||
def decorate! = decorate || raise(Lookup::Error.for self, Decorator) | ||
def decorated = decorate || self | ||
def decorated? = false | ||
|
||
private | ||
|
||
def decorator = Decorator.for self.class | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module Magic | ||
module Decoratable | ||
def decorate: -> Decorator? | ||
def decorate!: -> Decorator | ||
def decorated: -> (Decorator | self) | ||
|
||
def decorated?: -> bool | ||
|
||
private | ||
|
||
def decorator: -> Class? | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ module Magic | |
module Decorator | ||
class Base | ||
extend Lookup | ||
|
||
def decorated?: -> bool | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# frozen_string_literal: true | ||
|
||
module Magic | ||
RSpec.describe Decoratable do | ||
subject { object } | ||
|
||
let(:object) { 2.times.map { rand } } | ||
|
||
def decorator_class = Class.new Decorator::Base | ||
|
||
before do # HACK: decorators persist across examples somehow otherwise | ||
stub_const 'Magic::Decorator::Base', Class.new(Decorator::Base) | ||
end | ||
|
||
after { Decorator::Base.clear_memery_cache! } | ||
|
||
shared_context :decoratable do | ||
before { stub_const 'ArrayDecorator', decorator_class } | ||
end | ||
|
||
shared_examples 'returns decorated object' do | ||
its([]) { is_expected.to eq object } | ||
its([]) { is_expected.to be_decorated } | ||
end | ||
|
||
describe '#decorate', :method do | ||
it_behaves_like :decoratable do | ||
include_examples 'returns decorated object' | ||
end | ||
|
||
its([]) { is_expected.to be_nil } | ||
end | ||
|
||
describe '#decorate!', :method do | ||
it_behaves_like :decoratable do | ||
include_examples 'returns decorated object' | ||
end | ||
|
||
it { expect { subject[] }.to raise_error Lookup::Error } | ||
end | ||
|
||
describe '#decorated', :method do | ||
it_behaves_like :decoratable do | ||
include_examples 'returns decorated object' | ||
end | ||
|
||
its([]) { is_expected.to eq object } | ||
its([]) { is_expected.not_to be_decorated } | ||
end | ||
|
||
describe '#decorated?', :method do | ||
let(:object) { super().decorated } | ||
|
||
it_behaves_like :decoratable do | ||
its([]) { is_expected.to be true } | ||
end | ||
|
||
its([]) { is_expected.to be false } | ||
end | ||
end | ||
end |