decorum 0.4.1 → 0.5.0

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
  SHA1:
3
- metadata.gz: 7bfa93fae71415540de7bd2671d54885520c7c02
4
- data.tar.gz: 3bfbf59a7418f85ab8c8127abf392b4ca05b1a3b
3
+ metadata.gz: 862e4435ac09860217f17edc406d6779a9f0414d
4
+ data.tar.gz: 8cbd6050375b8f40110cb5feaf667fee7280977b
5
5
  SHA512:
6
- metadata.gz: 0ab83066bd10977de6e9490d94f0fe8f7c68300d5b67a200a239b15b3d1d5c7072f6b6767566ca2109ebd295ac96a59ff6833d86b67edfbb85ee2945e367c08a
7
- data.tar.gz: 8f269196ea075f3fbe8fdf780f0c21441de56a65be5d18e9520bf0082b18a4dbed6df5b80d8e28a1ef3307942ce39933be8384f09f00c0d2b47f49a2900816a5
6
+ metadata.gz: 0ff3a972d777a846831dda2949a69f617372fb0fb896b7594e925b58e4f3a6172e95c68ee85e445f1491d55f68ae7a9b6e7ba8b595aaac662053b8677276d7b2
7
+ data.tar.gz: bd13f3a374b2fe2b36baed5e33bd03051e945e843438e72ccb747fc6759d205edf9925770c69ad1a6578ac08050daf8d13198ce58f3e7cd0513eca9f2f07a73f
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .*.swp
1
2
  *.gem
2
3
  *.rbc
3
4
  .bundle
@@ -1,3 +1,6 @@
1
+ # 0.5.0 / 2016-04-03
2
+ * [FEATURE] public methods in Decorations (#decorate, #undecorate, etc.) may now be aliased
3
+
1
4
  # 0.4.1 / 2015-04-24
2
5
  * [BUGFIX] updated test suite for new rspec T/F comparison style
3
6
 
data/README.md CHANGED
@@ -25,11 +25,17 @@ end
25
25
  bp = BirthdayParty.new
26
26
  bp.respond_to?(:shoot_confetti) # ==> false
27
27
  bp.is_decorated? # ==> false
28
+ # but wait!
28
29
  bp.decorate(Confetti)
30
+ # and now...
31
+ bp.respond_to?(:shoot_confetti) # ==> true
29
32
  bp.is_decorated? # ==> true
30
33
  bp.shoot_confetti # ==> "boom, yay"
31
34
  ```
32
35
 
36
+ ## New in 0.5.0
37
+ - The (public) methods in Decorum::Decorations (decorate, undecorate, etc.) may now be aliased. If you were having weird bugs beacuse Decorum was clobbering some existing method named `#decorate`, this is the version for you. More below.
38
+
33
39
  ## New in 0.4.0
34
40
  - Decorators and their attributes may now be specified in class definitions, and loaded with `#load_decorators_from_class`
35
41
  - `#is_decorated?`
@@ -245,9 +251,10 @@ See the source for more details.
245
251
 
246
252
  First, objects need to be decoratable. You can do this for a whole class,
247
253
  by including Decorum::Decorations, or for a single object, by extending it.
248
- (Note: this alone doesn't change the object's method lookup. It just makes
249
- `#decorate` available on the object. The behavior is only changed when
250
- `#decorate` is called.) The easiest way is probably including
254
+ Note: this alone doesn't change the object's method lookup. It just makes
255
+ `#decorate` and friends available on the object. (Note: As of 0.5.0 this
256
+ isn't strictly true. See [Aliasing Decorum Methods](#aliasing-decorum-methods) below.) The behavior is only changed when
257
+ `#decorate` is called. The easiest way is probably including
251
258
  Decorum::Decorations at whatever point(s) of the class hierarchy you
252
259
  feel appropriate.
253
260
 
@@ -270,6 +277,7 @@ end
270
277
  r = Royalty.find_by_palace_name(:bob)
271
278
  r.respond_to? :styled_name # ==> false
272
279
  r.decorate StyledNameDecorator
280
+ r.respond_to? :styled_name # ==> true
273
281
  r.styled_name # ==> "His Grace Most Potent Baron Sir Percy Arnold Robert \"Bob\" Gorpthwaite, Esq."
274
282
  ```
275
283
 
@@ -317,7 +325,7 @@ definition:
317
325
  class Coffee
318
326
  include Decorum::Decorations
319
327
  # two bovine dairy no sugar by default, please:
320
- decorators Milk, { animal: "cow" }, Milk, { animal: "cow" }
328
+ decorum Milk, { animal: "cow" }, Milk, { animal: "cow" }
321
329
  ...
322
330
  end
323
331
 
@@ -327,6 +335,12 @@ c.add_milk
327
335
  c.milk_level # ==> 2
328
336
  ```
329
337
 
338
+ (This class method was called `decorators` in versions prior to 0.5.0,
339
+ but in the interest of avoiding naming conflicts, it's been changed to
340
+ `decorum`. If however you're using the standard [method aliases](#aliasing-decorum-methods),
341
+ it will install an alias for `decorators`, allowing your existing stuff to
342
+ keep working without changes.)
343
+
330
344
  Note that this usage does _not_ automatically include decorators on new
331
345
  objects. That would require invasive procedures on your object initialization.
332
346
  Instead, Decorum provides `#load_decorators_from_class`, which you can call
@@ -528,6 +542,46 @@ x.method_in_question # <== "overridden"
528
542
  If you declare `immediate` with no arguments, the decorators entire public interface
529
543
  is used.
530
544
 
545
+ ### Aliasing Decorum methods
546
+
547
+ Including/extending Decorum::Decorations makes a number of public methods (e.g., `#decorate`)
548
+ available on an object, which can be a problem if methods under those names
549
+ already exist. As of 0.5.0, these methods are actually implemented with "internalized"
550
+ names, (e.g., `#_decorum_decorate`) and aliased after the fact. Decorum is loaded by requiring
551
+ two files:
552
+
553
+ ```ruby
554
+ # lib/decorum.rb
555
+ require_relative 'decorum/noaliases'
556
+ require_relative 'decorum/aliases'
557
+ ```
558
+
559
+ The `noaliases` file loads up everything except aliasing; after requiring this file,
560
+ public methods in Decorum::Decorations are available by their internal names. Aliases
561
+ are then loaded for each of the public methods, either as specified in upcased environment variables
562
+ (e.g., `_DECORUM_DECORATE="my_decorate_alias"`) or failing that, the default values
563
+ in `aliases`. Here are the public methods and their defaults:
564
+
565
+ ```ruby
566
+ # from lib/decorum/aliases.rb
567
+ DEFAULT_ALIASES = { _decorum_decorate: "decorate",
568
+ _decorum_undecorate: "undecorate",
569
+ _decorum_is_decorated?: "is_decorated?",
570
+ _decorum_decorators: "decorators",
571
+ _decorum_decorated_state: "decorated_state",
572
+ _decorum_load_decorators_from_class: "load_decorators_from_class",
573
+ _decorum_raw_decorators: nil,
574
+ _decorum_raw_decorators!: nil,
575
+ _decorum_namespaces: nil }
576
+ ```
577
+
578
+ The `.decorum` method made available to modules when they include Decorum::Decorations is also
579
+ aliased here as either the value of `_DECORUM_CLASS_DECORATORS` or just `.decorators`.
580
+
581
+ If you need something else, (e.g., more finely grained aliases) you can just `require decorum/noaliases`,
582
+ and all of Decorum's aliasing will be skipped. You can then implement your own scheme however you like.
583
+
584
+
531
585
  ### Decorators All the Way Down
532
586
 
533
587
  Decorum includes a class called Decorum::BareParticular, which descends from
@@ -539,8 +593,7 @@ return nil by default.
539
593
 
540
594
  ## To-do
541
595
  A few things I can imagine showing up soon:
542
- - An easy way to alias the main methods (#decorate, #undecorate), as you might
543
- want those names for something else.
596
+ - See open issues
544
597
  - Thread safety: probably not an issue if you're retooling your Rails helpers,
545
598
  but consider a case like this:
546
599
 
@@ -1,39 +1,3 @@
1
- # decorum.rb
2
- require 'ostruct'
3
-
4
- superhash_class = if class_name = ENV['DECORUM_SUPERHASH_CLASS']
5
- current = nil
6
- class_name.split('::').each do |const_name|
7
- modyool = current || Kernel
8
- current = modyool.const_get(const_name)
9
- end
10
- current
11
- else
12
- OpenStruct
13
- end
14
-
15
- shared_state_class = if class_name = ENV['DECORUM_SHARED_STATE_CLASS']
16
- current = nil
17
- class_name.split('::').each do |const_name|
18
- modyool = current || Kernel
19
- current = modyool.const_get(const_name)
20
- end
21
- current
22
- else
23
- superhash_class
24
- end
25
-
26
- module Decorum
27
- end
28
-
29
- Decorum::SuperHash = superhash_class
30
- Decorum::SharedState = shared_state_class
31
-
32
- require_relative 'decorum/version'
33
- require_relative 'decorum/decorations'
34
- require_relative 'decorum/decorator'
35
- require_relative 'decorum/decorated_state'
36
- require_relative 'decorum/chain_stop'
37
- require_relative 'decorum/bare_particular'
38
- require_relative 'decorum/callable_decorator'
39
- require_relative 'decorum/decorator_namespace'
1
+ # lib/decorum.rb
2
+ require_relative 'decorum/noaliases'
3
+ require_relative 'decorum/aliases'
@@ -0,0 +1,50 @@
1
+ # Here we alias public methods defined by Decorum::Decorations,
2
+ # because these will appear in other people's classes and should
3
+ # therefore not cause conflcts. Public methods:
4
+ # _decorum_decorate
5
+ # _decorum_undecorate
6
+ # _decorum_is_decorated?
7
+ # _decorum_decorators
8
+ # _decorum_decorated_state
9
+ # _decorum_load_decorators_from_class
10
+ #
11
+ # and these three more "internal" methods, no default aliases:
12
+ # _decorum_raw_decorators
13
+ # _decorum_raw_decorators!
14
+ # _decorum_namespaces
15
+ #
16
+ # you can also specify a capitalized method name in env for
17
+ # something other than default, e.g.,
18
+ #
19
+ # _DECORUM_DECORATE='my_funky_decorate_alias'
20
+ #
21
+ # otherwise it will fall back on defaults; to bypass this
22
+ # entirely load decorum/noaliases
23
+
24
+ module Decorum
25
+ module Decorations
26
+ module ClassMethods
27
+ class_method_alias = ENV['_DECORUM_CLASS_DECORATORS'] || "decorators"
28
+ alias_method class_method_alias, :decorum
29
+ end
30
+
31
+ DEFAULT_ALIASES = { _decorum_decorate: "decorate",
32
+ _decorum_undecorate: "undecorate",
33
+ _decorum_is_decorated?: "is_decorated?",
34
+ _decorum_decorators: "decorators",
35
+ _decorum_decorated_state: "decorated_state",
36
+ _decorum_load_decorators_from_class: "load_decorators_from_class",
37
+ _decorum_raw_decorators: nil,
38
+ _decorum_raw_decorators!: nil,
39
+ _decorum_namespaces: nil }
40
+
41
+
42
+ DEFAULT_ALIASES.each do |k, v|
43
+ aliased_name = ENV["#{k.upcase}"] || v
44
+ if aliased_name
45
+ alias_method aliased_name, k
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -3,6 +3,11 @@ module Decorum
3
3
  def initialize(decorator)
4
4
  @_decorator = decorator
5
5
  end
6
+
7
+ # tortuously named to avoid conflict and discourage use
8
+ def _actual_decorator
9
+ @_decorator
10
+ end
6
11
 
7
12
  def method_missing(message, *args, &block)
8
13
  response = catch :chain_stop do
@@ -1,8 +1,8 @@
1
1
  module Decorum
2
2
  module Decorations
3
- def self.included(modyool)
4
3
  # class method to declare default decorators
5
- def modyool.decorators(*args)
4
+ module ClassMethods
5
+ def decorum(*args)
6
6
  # set first-listed priority
7
7
  if args[0] == :reverse
8
8
  return @_decorum_stack_reverse = true
@@ -27,11 +27,15 @@ module Decorum
27
27
  end
28
28
  end
29
29
  end
30
+
31
+ # load the class method(s)
32
+ def self.included(modyool)
33
+ modyool.extend Decorum::Decorations::ClassMethods
34
+ end
30
35
 
31
36
  # public instance methods
32
37
 
33
-
34
- def decorate(klass, options={})
38
+ def _decorum_decorate(klass, options={})
35
39
  if namespace_method = options.delete(:namespace)
36
40
  decorator = nil
37
41
  namespace = nil
@@ -40,128 +44,131 @@ module Decorum
40
44
  unless namespace.is_a?(Decorum::DecoratorNamespace)
41
45
  raise RuntimeError, "#{namespace_method} exists and is not a decorator namespace"
42
46
  end
43
- namespace.decorate(klass, options) { |d| decorator = d }
47
+ namespace._decorum_decorate(klass, options) { |d| decorator = d }
44
48
  else
45
49
  namespace = Decorum::DecoratorNamespace.new(self)
46
- namespace.decorate(klass, options) { |d| decorator = d }
47
- instance_variable_set(:"@_decorum_#{namespace_method}", namespace)
50
+ namespace._decorum_decorate(klass, options) { |d| decorator = d }
51
+ instance_variable_set(:"@_decorum_ns_#{namespace_method}", namespace)
48
52
  m = Module.new do
49
53
  define_method(namespace_method) do
50
- instance_variable_get(:"@_decorum_#{namespace_method}")
54
+ instance_variable_get(:"@_decorum_ns_#{namespace_method}")
51
55
  end
52
56
  end
53
57
  extend m
54
- _decorator_namespaces << namespace_method
58
+ _decorum_namespaces << namespace_method
55
59
  end
56
- yield CallableDecorator.new(decorator) if block_given?
60
+ yield Decorum::CallableDecorator.new(decorator) if block_given?
57
61
  else
58
62
  extend Decorum::Decorations::Intercept
59
- decorator = add_to_decorator_chain(klass, options)
60
- yield CallableDecorator.new(decorator) if block_given?
63
+ decorator = _add_to_decorum_chain(klass, options)
64
+ yield Decorum::CallableDecorator.new(decorator) if block_given?
61
65
  decorator.post_decorate
62
66
  end
63
67
  self
64
68
  end
65
69
 
66
- def undecorate(target)
67
- remove_from_decorator_chain(target)
70
+ def _decorum_undecorate(target)
71
+ _remove_from_decorum_chain(target)
68
72
  self
69
73
  end
70
74
 
71
- def is_decorated?
72
- ![ decorators, _decorator_namespaces.map { |ns| send(ns).decorators } ].flatten.empty?
75
+ def _decorum_is_decorated?
76
+ ![ _decorum_decorators, _decorum_namespaces.map { |ns| send(ns)._decorum_decorators } ].flatten.empty?
73
77
  end
74
78
 
75
79
  # returns callable decorators---use this
76
- def decorators
77
- _decorators.map { |d| CallableDecorator.new(d) }
80
+ def _decorum_decorators
81
+ _decorum_raw_decorators.map { |d| Decorum::CallableDecorator.new(d) }
78
82
  end
79
83
 
80
84
  # leaving it to you to, say, call this from #initialize
81
- def load_decorators_from_class
82
- self.class.decorators.each { |decorator_class, options| decorate(decorator_class, options) }
85
+ def _decorum_load_decorators_from_class
86
+ self.class.decorators.each { |decorator_class, options| _decorum_decorate(decorator_class, options) }
83
87
  self
84
88
  end
85
89
 
86
90
  # returns raw decorators---don't use this unless
87
91
  # you know what you're doing
88
- def _decorators
89
- if @_decorators
90
- return @_decorators
91
- elsif !@_decorator_chain
92
+ def _decorum_raw_decorators
93
+ # the array of raw decorators is memoized; set
94
+ # @_decorum_raw_decorators to nil/false to rebuild
95
+ if @_decorum_raw_decorators
96
+ return @_decorum_raw_decorators
97
+ elsif !@_decorum_chain_reference
92
98
  return []
93
99
  end
94
100
 
95
- decorator = @_decorator_chain
96
- @_decorators = []
101
+ # rebuild the array representation of decorators
102
+ decorator = @_decorum_chain_reference
103
+ @_decorum_raw_decorators = []
97
104
  until decorator.is_a?(Decorum::ChainStop)
98
- @_decorators << decorator
105
+ @_decorum_raw_decorators << decorator
99
106
  decorator = decorator.next_link
100
107
  end
101
- @_decorators
108
+ @_decorum_raw_decorators
102
109
  end
103
110
 
104
111
  # reset the decorator collection
105
- def _decorators!
106
- @_decorators = nil
107
- _decorators
112
+ def _decorum_raw_decorators!
113
+ @_decorum_raw_decorators = nil
114
+ _decorum_raw_decorators
108
115
  end
109
116
 
110
- def decorated_state(klass=nil)
111
- @_decorated_state ||= {}
117
+ def _decorum_decorated_state(klass=nil)
118
+ @_decorum_decorated_state ||= {}
112
119
 
113
120
  if klass
114
- @_decorated_state[klass]
121
+ @_decorum_decorated_state[klass]
115
122
  else
116
- @_decorated_state
123
+ @_decorum_decorated_state
117
124
  end
118
125
  end
119
126
 
120
- def _decorator_namespaces
121
- @_decorator_namespaces ||= []
127
+ def _decorum_namespaces
128
+ @_decorum_namespaces ||= []
122
129
  end
123
130
 
124
131
  module Decorum::Decorations::Intercept
125
132
  def method_missing(message, *args, &block)
126
133
  response = catch :chain_stop do
127
- @_decorator_chain.send(message, *args, &block)
134
+ @_decorum_chain_reference.send(message, *args, &block)
128
135
  end
129
136
  response.is_a?(Decorum::ChainStop) ? super : response
130
137
  end
131
138
 
132
139
  def respond_to_missing?(message, include_private = false)
133
- _decorators.each { |d| return true if d.respond_to?(message) }
140
+ _decorum_raw_decorators.each { |d| return true if d.respond_to?(message) }
134
141
  super
135
142
  end
136
143
  end
137
144
 
138
145
  private
139
146
 
140
- def add_to_decorator_chain(klass, options)
147
+ def _add_to_decorum_chain(klass, options)
141
148
  unless klass.ancestors.include?(Decorum::Decorator)
142
149
  raise TypeError, "decorator chain needs a Decorator"
143
150
  end
144
151
 
145
152
  if options[:decorator_handle]
146
- current_names = _decorators.map { |d| d.decorator_handle.to_sym }.compact
153
+ current_names = _decorum_raw_decorators.map { |d| d.decorator_handle.to_sym }.compact
147
154
  if current_names.include?(options[:decorator_handle].to_sym)
148
155
  raise RuntimeError, "decorator names must be unique over an object"
149
156
  end
150
157
  end
151
158
 
152
- unless decorated_state(klass)
153
- @_decorated_state[klass] = Decorum::DecoratedState.new
159
+ unless _decorum_decorated_state(klass)
160
+ @_decorum_decorated_state[klass] = Decorum::DecoratedState.new
154
161
  end
155
162
 
156
- base = @_decorator_chain || Decorum::ChainStop.new
157
- @_decorator_chain = klass.new(base, self, options)
163
+ base = @_decorum_chain_reference || Decorum::ChainStop.new
164
+ @_decorum_chain_reference = klass.new(base, self, options)
158
165
 
159
166
  if klass.immediate_methods
160
167
  immediate = Module.new do
161
168
  klass.immediate_methods.each do |method_name|
162
169
  define_method(method_name) do |*args, &block|
163
170
  response = catch :chain_stop do
164
- @_decorator_chain.send(__method__, *args, &block)
171
+ @_decorum_chain_reference.send(__method__, *args, &block)
165
172
  end
166
173
  response.is_a?(Decorum::ChainStop) ? super(*args, &block) : response
167
174
  end
@@ -169,30 +176,30 @@ module Decorum
169
176
  end
170
177
  extend immediate
171
178
  end
172
- _decorators!
173
- @_decorator_chain
179
+ _decorum_raw_decorators!
180
+ @_decorum_chain_reference
174
181
  end
175
182
 
176
- def remove_from_decorator_chain(decorator)
177
- if decorator.is_a?(CallableDecorator)
178
- decorator = decorator.instance_variable_get(:@_decorator)
183
+ def _remove_from_decorum_chain(decorator)
184
+ if decorator.is_a?(Decorum::CallableDecorator)
185
+ decorator = decorator._actual_decorator
179
186
  end
180
187
 
181
- unless (decorator.is_a?(Decorum::Decorator) && _decorators.include?(decorator))
188
+ unless (decorator.is_a?(Decorum::Decorator) && _decorum_raw_decorators.include?(decorator))
182
189
  return nil
183
190
  end
184
191
 
185
- if decorator == @_decorator_chain
186
- @_decorator_chain = decorator.next_link
192
+ if decorator == @_decorum_chain_reference
193
+ @_decorum_chain_reference = decorator.next_link
187
194
  else
188
- previous_decorator = _decorators[_decorators.index(decorator) - 1]
195
+ previous_decorator = _decorum_raw_decorators[_decorum_raw_decorators.index(decorator) - 1]
189
196
  previous_decorator.next_link = decorator.next_link
190
197
  end
191
198
 
192
- unless _decorators!.map { |d| d.class }.include?(decorator.class)
193
- @_decorated_state[decorator.class] = nil
199
+ unless _decorum_raw_decorators!.map { |d| d.class }.include?(decorator.class)
200
+ @_decorum_decorated_state[decorator.class] = nil
194
201
  end
195
- _decorators
202
+ _decorum_raw_decorators
196
203
  end
197
204
  end
198
205
  end
@@ -5,9 +5,9 @@ module Decorum
5
5
  alias_method :object, :root
6
6
 
7
7
  def initialize(next_link, root, options)
8
- @passed_options = options
9
- @next_link = next_link
10
- @root = root
8
+ @passed_options = options
9
+ @next_link = next_link
10
+ @root = root
11
11
  @decorator_handle = options[:decorator_handle]
12
12
 
13
13
  defaults = self.class.get_default_attributes
@@ -29,7 +29,7 @@ module Decorum
29
29
  # a superhash of shared state between Decorators
30
30
  # of the same class
31
31
  def decorated_state
32
- root.decorated_state(self.class)
32
+ root._decorum_decorated_state(self.class)
33
33
  end
34
34
 
35
35
  # Decorators that want stackable or cumulative
@@ -0,0 +1,42 @@
1
+ # decorum/noaliases - this does all of the core setup, everything
2
+ # except aliasing public methods in Decorum::Decorations. provided
3
+ # separately so users can bypass the alias process entirely if desired.
4
+
5
+ require 'ostruct'
6
+
7
+ superhash_class = if class_name = ENV['DECORUM_SUPERHASH_CLASS']
8
+ current = nil
9
+ class_name.split('::').each do |const_name|
10
+ modyool = current || Kernel
11
+ current = modyool.const_get(const_name)
12
+ end
13
+ current
14
+ else
15
+ OpenStruct
16
+ end
17
+
18
+ shared_state_class = if class_name = ENV['DECORUM_SHARED_STATE_CLASS']
19
+ current = nil
20
+ class_name.split('::').each do |const_name|
21
+ modyool = current || Kernel
22
+ current = modyool.const_get(const_name)
23
+ end
24
+ current
25
+ else
26
+ superhash_class
27
+ end
28
+
29
+ module Decorum
30
+ end
31
+
32
+ Decorum::SuperHash = superhash_class
33
+ Decorum::SharedState = shared_state_class
34
+
35
+ require_relative 'version'
36
+ require_relative 'decorations'
37
+ require_relative 'decorator'
38
+ require_relative 'decorated_state'
39
+ require_relative 'chain_stop'
40
+ require_relative 'bare_particular'
41
+ require_relative 'callable_decorator'
42
+ require_relative 'decorator_namespace'
@@ -1,3 +1,3 @@
1
1
  module Decorum
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -4,9 +4,9 @@ describe "when Bob is ordering a cup of coffee" do
4
4
  let(:coffee) { Decorum::Examples::Coffee.new }
5
5
 
6
6
  before(:each) do
7
- coffee.decorate(Decorum::Examples::MilkDecorator, animal: "cow", milk_type: "2 percent")
8
- coffee.decorate(Decorum::Examples::MilkDecorator, animal: "cow", milk_type: "2 percent")
9
- coffee.decorate(Decorum::Examples::SugarDecorator)
7
+ coffee._decorum_decorate(Decorum::Examples::MilkDecorator, animal: "cow", milk_type: "2 percent")
8
+ coffee._decorum_decorate(Decorum::Examples::MilkDecorator, animal: "cow", milk_type: "2 percent")
9
+ coffee._decorum_decorate(Decorum::Examples::SugarDecorator)
10
10
  coffee.add_milk
11
11
  coffee.add_sugar
12
12
  end
@@ -22,7 +22,7 @@ describe "when Bob is ordering a cup of coffee" do
22
22
  context "things get interesting" do
23
23
  before(:each) do
24
24
  ["bear", "man", "pig"].each do |critter|
25
- coffee.decorate(Decorum::Examples::MilkDecorator, animal: critter)
25
+ coffee._decorum_decorate(Decorum::Examples::MilkDecorator, animal: critter)
26
26
  end
27
27
  coffee.add_milk
28
28
  end
@@ -5,7 +5,7 @@ describe 'a Fibonacci sequence implemented in Decorators' do
5
5
 
6
6
  before(:each) do
7
7
  100.times do
8
- fibber.decorate(Decorum::Examples::FibonacciDecorator)
8
+ fibber._decorum_decorate(Decorum::Examples::FibonacciDecorator)
9
9
  end
10
10
  end
11
11
 
@@ -8,18 +8,18 @@ describe "When overriding original methods with .immediate" do
8
8
  end
9
9
 
10
10
  it "overrides original methods" do
11
- base_object.decorate(Decorum::Examples::StrongWilledDecorator)
11
+ base_object._decorum_decorate(Decorum::Examples::StrongWilledDecorator)
12
12
  expect(base_object.method_in_question).to eq("overridden")
13
13
  end
14
14
 
15
15
  it "reverts to original method when decorator is unloaded" do
16
- base_object.decorate(Decorum::Examples::StrongWilledDecorator)
17
- base_object.undecorate(base_object.decorators.first)
16
+ base_object._decorum_decorate(Decorum::Examples::StrongWilledDecorator)
17
+ base_object._decorum_undecorate(base_object._decorum_decorators.first)
18
18
  expect(base_object.method_in_question).to eq("original")
19
19
  end
20
20
 
21
21
  it "stops chain on vanished method" do
22
- base_object.decorate(Decorum::Examples::StrongWilledDecorator)
22
+ base_object._decorum_decorate(Decorum::Examples::StrongWilledDecorator)
23
23
  # raise on violated assumptions rather than have multiple conditions in the same test?
24
24
  resp = base_object.second_immediate_method
25
25
  unless resp == "method dos"
@@ -27,17 +27,17 @@ describe "When overriding original methods with .immediate" do
27
27
  raise bail_message
28
28
  end
29
29
 
30
- base_object.undecorate(base_object.decorators.first)
30
+ base_object._decorum_undecorate(base_object._decorum_decorators.first)
31
31
  expect(base_object.second_immediate_method).to eq("class method_missing")
32
32
  end
33
33
 
34
34
  it "recurses" do
35
- 4.times { base_object.decorate(Decorum::Examples::ImmediateDecorator) }
35
+ 4.times { base_object._decorum_decorate(Decorum::Examples::ImmediateDecorator) }
36
36
  expect(base_object.increment_immediately_shared).to eq(4)
37
37
  end
38
38
 
39
39
  it "recurses on namespaced decorator" do
40
- 4.times { base_object.decorate(Decorum::Examples::ImmediateDecorator, namespace: :foo) }
40
+ 4.times { base_object._decorum_decorate(Decorum::Examples::ImmediateDecorator, namespace: :foo) }
41
41
  expect(base_object.foo.increment_immediately_shared).to eq(4)
42
42
  end
43
43
  end
@@ -8,8 +8,8 @@ module Decorum
8
8
  true
9
9
  end
10
10
 
11
- def decorated_state(*args)
12
- @decorated_state ||= Decorum::Spec::Decorator::DecoratedStateStub.new
11
+ def _decorum_decorated_state(*args)
12
+ @_decorum_decorated_state ||= Decorum::Spec::Decorator::DecoratedStateStub.new
13
13
  end
14
14
  end
15
15
  end
@@ -8,6 +8,6 @@ describe Decorum::BareParticular do
8
8
  end
9
9
 
10
10
  it 'black holes undefined methods' do
11
- expect(bp.nonexistent_method).to be_nil
11
+ expect(bp.this_method_absolutely_doesnt_exist).to be_nil
12
12
  end
13
13
  end
@@ -4,7 +4,7 @@ describe Decorum::CallableDecorator do
4
4
  let(:decorator) do
5
5
  c = Decorum::Examples::Coffee.new
6
6
  decorator = nil
7
- c.decorate(Decorum::Examples::MilkDecorator) { |d| decorator = d }
7
+ c._decorum_decorate(Decorum::Examples::MilkDecorator) { |d| decorator = d }
8
8
  decorator
9
9
  end
10
10
 
@@ -5,7 +5,7 @@ describe Decorum::ChainStop do
5
5
 
6
6
  it 'throws self via :chain_stop on undefined method' do
7
7
  response = catch :chain_stop do
8
- chainstop.nonexistent_method
8
+ chainstop.this_method_absolutely_doesnt_exist
9
9
  end
10
10
  expect(response).to be_equal(chainstop)
11
11
  end
@@ -6,39 +6,39 @@ describe Decorum::Decorations do
6
6
  let(:deco_class_2) { Decorum::Spec::Decorations::SecondDecorator }
7
7
  let(:deco_class_3) { Decorum::Spec::Decorations::ThirdDecorator }
8
8
 
9
- context 'loading decorators from class defaults' do
9
+ context 'loading decorators from class defaults via .decorum' do
10
10
  let(:klass) do
11
11
  Class.new do
12
12
  include Decorum::Decorations
13
- decorators Decorum::Spec::Decorations::ClassSpecifiedDecoratorOne, { passed_option: "one" },
13
+ decorum Decorum::Spec::Decorations::ClassSpecifiedDecoratorOne, { passed_option: "one" },
14
14
  Decorum::Spec::Decorations::ClassSpecifiedDecoratorTwo, { passed_option: "two" }
15
15
  end
16
16
  end
17
17
 
18
- describe '.decorators' do
18
+ describe '.decorum' do
19
19
  it 'stores decorators in own state correctly' do
20
- expect(klass.decorators.map { |d| d[0].ancestors.include?(Decorum::Decorator) }.inject(:&)).to be true
20
+ expect(klass.decorum.map { |d| d[0].ancestors.include?(Decorum::Decorator) }.inject(:&)).to be true
21
21
  end
22
22
 
23
23
  # the instance method #load_decorators_from_class will insert them in the order given:
24
24
 
25
25
  it 'normally gives first priority to last listed' do
26
- expect(klass.decorators.map { |d| d[1] } == [{ passed_option: "one" }, { passed_option: "two" }]).to be true
26
+ expect(klass.decorum.map { |d| d[1] } == [{ passed_option: "one" }, { passed_option: "two" }]).to be true
27
27
  end
28
28
 
29
29
  it 'reverses order for first-specfied priority' do
30
30
  klass.decorators :reverse
31
- expect(klass.decorators.map { |d| d[1] } == [{ passed_option: "two" }, { passed_option: "one" }]).to be true
31
+ expect(klass.decorum.map { |d| d[1] } == [{ passed_option: "two" }, { passed_option: "one" }]).to be true
32
32
  end
33
33
 
34
34
  it 'rejects malformed options' do
35
- expect { klass.decorators(Decorum::Spec::Decorations::FirstDecorator, "invalid decorator argument") }.to raise_error
35
+ expect { klass.decorum(Decorum::Spec::Decorations::FirstDecorator, "invalid decorator argument") }.to raise_error
36
36
  end
37
37
 
38
38
  # this probably belongs with other instance methods below, but we've got the
39
39
  # support objects built for it here...
40
40
  describe '#decorators' do
41
- let(:obj) { klass.new.load_decorators_from_class }
41
+ let(:obj) { klass.new._decorum_load_decorators_from_class }
42
42
  it 'returns self' do
43
43
  # sort of
44
44
  expect(obj.is_a?(klass)).to be true
@@ -69,71 +69,71 @@ describe Decorum::Decorations do
69
69
  expect(decorated.undecorated_method).to be true
70
70
  end
71
71
 
72
- describe '#is_decorated?' do
72
+ describe '#_decorum_is_decorated?' do
73
73
  it 'is false' do
74
- expect(decorated.is_decorated?).to be false
74
+ expect(decorated._decorum_is_decorated?).to be false
75
75
  end
76
76
  end
77
77
 
78
- describe '#decorated_state' do
78
+ describe '#_decorum_decorated_state' do
79
79
  it 'returns a hash' do
80
- blank_state = decorated.decorated_state
80
+ blank_state = decorated._decorum_decorated_state
81
81
  expect(blank_state.is_a?(Hash)).to be true
82
82
  end
83
83
 
84
84
  it 'returns an empty hash' do
85
- blank_state = decorated.decorated_state
85
+ blank_state = decorated._decorum_decorated_state
86
86
  expect(blank_state.empty?).to be true
87
87
  end
88
88
 
89
89
  it 'returns nil given an argument' do
90
- expect(decorated.decorated_state(:not_gonna_work)).to be_nil
90
+ expect(decorated._decorum_decorated_state(:not_gonna_work)).to be_nil
91
91
  end
92
92
  end
93
93
 
94
- describe 'undecorate' do
94
+ describe '#_decorum_undecorate' do
95
95
  it 'returns self on symbol' do
96
- expect(decorated.undecorate(:symbol_arg)).to be_equal(decorated)
96
+ expect(decorated._decorum_undecorate(:symbol_arg)).to be_equal(decorated)
97
97
  end
98
98
 
99
99
  it 'returns self on spurious decorator' do
100
- expect(decorated.undecorate(deco_class_1)).to be_equal(decorated)
100
+ expect(decorated._decorum_undecorate(deco_class_1)).to be_equal(decorated)
101
101
  end
102
102
  end
103
103
  end
104
104
 
105
105
  context 'decorated' do
106
- describe '#decorate' do
106
+ describe '#_decorum_decorate' do
107
107
  it 'returns self on decoration' do
108
108
  real_decorated = decorated
109
- expect(decorated.decorate(deco_class_1)).to be_equal(real_decorated)
109
+ expect(decorated._decorum_decorate(deco_class_1)).to be_equal(real_decorated)
110
110
  end
111
111
 
112
112
  it 'calls #post_decorate' do
113
- expect(decorated.decorate(deco_class_1).post_decorated).to eq("decorated")
113
+ expect(decorated._decorum_decorate(deco_class_1).post_decorated).to eq("decorated")
114
114
  end
115
115
 
116
116
  it 'yields decorator if block_given?' do
117
117
  decorator = nil
118
- decorated.decorate(deco_class_1) { |dec| decorator = dec }
119
- actual_decorator = decorated.instance_variable_get(:@_decorator_chain)
120
- expect(decorator.instance_variable_get(:@_decorator)).to be(actual_decorator)
118
+ decorated._decorum_decorate(deco_class_1) { |dec| decorator = dec }
119
+ actual_decorator = decorated.instance_variable_get(:@_decorum_chain_reference)
120
+ expect(decorator._actual_decorator).to be(actual_decorator)
121
121
  end
122
122
 
123
123
  context 'success' do
124
124
  before(:each) do
125
125
  decorator_options = { decorator_handle: "first", shared_attribute: "shared 1", local_attribute: "local 1" }
126
- decorated.decorate(deco_class_1, decorator_options)
126
+ decorated._decorum_decorate(deco_class_1, decorator_options)
127
127
  end
128
128
 
129
- describe '#is_decorated?' do
129
+ describe '#_decorum_is_decorated?' do
130
130
  it 'returns true' do
131
- expect(decorated.is_decorated?).to be true
131
+ expect(decorated._decorum_is_decorated?).to be true
132
132
  end
133
133
 
134
134
  it 'returns false after unloading' do
135
- decorated.undecorate(decorated.decorators.first)
136
- expect(decorated.is_decorated?).to be false
135
+ decorated._decorum_undecorate(decorated._decorum_decorators.first)
136
+ expect(decorated._decorum_is_decorated?).to be false
137
137
  end
138
138
  end
139
139
 
@@ -142,7 +142,7 @@ describe Decorum::Decorations do
142
142
  end
143
143
 
144
144
  it 'sets internal state' do
145
- internal_state = decorated.instance_variable_get(:@_decorator_chain)
145
+ internal_state = decorated.instance_variable_get(:@_decorum_chain_reference)
146
146
  expect(internal_state.is_a?(deco_class_1)).to be true
147
147
  end
148
148
 
@@ -155,7 +155,7 @@ describe Decorum::Decorations do
155
155
  end
156
156
 
157
157
  it 'raises NoMethodError on nonexistent method' do
158
- expect { decorated.nonexistent_method }.to raise_error(NoMethodError)
158
+ expect { decorated.this_method_absolutely_doesnt_exist }.to raise_error(NoMethodError)
159
159
  end
160
160
 
161
161
  it 'is decorated by local attributes' do
@@ -167,14 +167,14 @@ describe Decorum::Decorations do
167
167
  end
168
168
 
169
169
  it 'creates decorated state for decorator class' do
170
- expect(decorated.decorated_state(deco_class_1).shared_attribute).to eq('shared 1')
170
+ expect(decorated._decorum_decorated_state(deco_class_1).shared_attribute).to eq('shared 1')
171
171
  end
172
172
 
173
173
  context 'with multiple decorators' do
174
174
  before(:each) do
175
175
  3.times do |i|
176
176
  klass = send(:"deco_class_#{i + 1}")
177
- decorated.decorate(klass)
177
+ decorated._decorum_decorate(klass)
178
178
  end
179
179
  end
180
180
 
@@ -193,21 +193,21 @@ describe Decorum::Decorations do
193
193
 
194
194
  context 'failure' do
195
195
  it 'rejects classes that are not Decorators' do
196
- expect { decorated.decorate(Class,{}) }.to raise_error(TypeError)
196
+ expect { decorated._decorum_decorate(Class, {}) }.to raise_error(TypeError)
197
197
  end
198
198
 
199
199
  it 'rejects non unique decorator handles' do
200
200
  3.times do |i|
201
201
  klass = send(:"deco_class_#{i + 1}")
202
- decorated.decorate(klass, decorator_handle: "deco-#{i + 1}")
202
+ decorated._decorum_decorate(klass, decorator_handle: "deco-#{i + 1}")
203
203
  end
204
- expect { decorated.decorate(deco_class_1, decorator_handle: "deco-2") }.to raise_error(RuntimeError)
204
+ expect { decorated._decorum_decorate(deco_class_1, decorator_handle: "deco-2") }.to raise_error(RuntimeError)
205
205
  end
206
206
  end
207
207
  end
208
208
 
209
209
  describe '#respond_to?' do
210
- before(:each) { decorated.decorate(deco_class_1) }
210
+ before(:each) { decorated._decorum_decorate(deco_class_1) }
211
211
 
212
212
  it 'returns true for decorated methods' do
213
213
  expect(decorated.respond_to?(:first_decorator_method)).to be true
@@ -218,7 +218,7 @@ describe Decorum::Decorations do
218
218
  end
219
219
 
220
220
  it 'returns false for undefined method' do
221
- expect(decorated.respond_to?(:nonexistent_method)).to be false
221
+ expect(decorated.respond_to?(:this_method_absolutely_doesnt_exist)).to be false
222
222
  end
223
223
  end
224
224
 
@@ -226,31 +226,31 @@ describe Decorum::Decorations do
226
226
  before(:each) do
227
227
  3.times do |x|
228
228
  klass = send(:"deco_class_#{x + 1}")
229
- decorated.decorate(klass, decorator_handle: "deco-#{x + 1}")
229
+ decorated._decorum_decorate(klass, decorator_handle: "deco-#{x + 1}")
230
230
  end
231
231
  end
232
232
 
233
- describe '#decorators' do
233
+ describe '#_decorum_decorators' do
234
234
  it 'accurately reflects loaded decorators and in order' do
235
235
  expected_map = ["deco-3", "deco-2", "deco-1"]
236
- expect(decorated.decorators.map { |d| d.decorator_handle }).to eq(expected_map)
236
+ expect(decorated._decorum_decorators.map { |d| d.decorator_handle }).to eq(expected_map)
237
237
  end
238
238
 
239
239
  it 'memoizes decorators' do
240
- decorated.decorators[0].next_link = decorated.decorators[2]
241
- expect(decorated.decorators.length).to be(3)
240
+ decorated._decorum_decorators[0].next_link = decorated._decorum_decorators[2]
241
+ expect(decorated._decorum_decorators.length).to be(3)
242
242
  end
243
243
 
244
- it 'refreshes via #decorators!' do
245
- decorated._decorators[0].next_link = decorated._decorators[2]
246
- decorated.send(:_decorators!)
247
- expect(decorated.decorators.length).to be(2)
244
+ it 'refreshes via #_decorum_raw_decorators!' do
245
+ decorated._decorum_raw_decorators[0].next_link = decorated._decorum_raw_decorators[2]
246
+ decorated.send(:_decorum_raw_decorators!)
247
+ expect(decorated._decorum_decorators.length).to be(2)
248
248
  end
249
249
  end
250
250
 
251
- describe '#undecorate' do
251
+ describe '#_decorum_undecorate' do
252
252
  before(:each) do
253
- @undec = decorated.decorators.detect { |d| d.decorator_handle == "deco-2" }
253
+ @undec = decorated._decorum_decorators.detect { |d| d.decorator_handle == "deco-2" }
254
254
  # just to make sure...
255
255
  unless @undec.is_a?(Decorum::CallableDecorator)
256
256
  raise "broken test---no such decorator deco-2; undec was #{@undec.inspect}"
@@ -258,23 +258,23 @@ describe Decorum::Decorations do
258
258
  end
259
259
 
260
260
  it 'undecorates' do
261
- decorated.undecorate(@undec)
262
- expect(decorated.decorators.length).to be(2)
261
+ decorated._decorum_undecorate(@undec)
262
+ expect(decorated._decorum_decorators.length).to be(2)
263
263
  end
264
264
 
265
265
  it 'undecorates the right one' do
266
- decorated.undecorate(@undec)
266
+ decorated._decorum_undecorate(@undec)
267
267
  expected_map = ["deco-3", "deco-1"]
268
- expect(decorated.decorators.map { |d| d.decorator_handle }).to eq(expected_map)
268
+ expect(decorated._decorum_decorators.map { |d| d.decorator_handle }).to eq(expected_map)
269
269
  end
270
270
 
271
271
  it 'returns self on success' do
272
272
  real_decorated = decorated
273
- expect(decorated.undecorate(@undec)).to be_equal(real_decorated)
273
+ expect(decorated._decorum_undecorate(@undec)).to be_equal(real_decorated)
274
274
  end
275
275
 
276
276
  context 'once undecorated' do
277
- before(:each) { decorated.undecorate(@undec) }
277
+ before(:each) { decorated._decorum_undecorate(@undec) }
278
278
 
279
279
  it 'no longer responds to removed decorated method' do
280
280
  expect(decorated.respond_to?(:second_decorator_method)).to be false
@@ -289,11 +289,11 @@ describe Decorum::Decorations do
289
289
  end
290
290
 
291
291
  it 'destroys shared state when last class member is gone' do
292
- expect(decorated.decorated_state(deco_class_2)).to be_nil
292
+ expect(decorated._decorum_decorated_state(deco_class_2)).to be_nil
293
293
  end
294
294
 
295
295
  it 'does not destroy other shared state' do
296
- expect(decorated.decorated_state(deco_class_1)).to be_a(Decorum::DecoratedState)
296
+ expect(decorated._decorum_decorated_state(deco_class_1)).to be_a(Decorum::DecoratedState)
297
297
  end
298
298
  end
299
299
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decorum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Cameron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-24 00:00:00.000000000 Z
11
+ date: 2016-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ files:
75
75
  - examples/sugar_decorator.rb
76
76
  - examples/weak_willed_class.rb
77
77
  - lib/decorum.rb
78
+ - lib/decorum/aliases.rb
78
79
  - lib/decorum/bare_particular.rb
79
80
  - lib/decorum/callable_decorator.rb
80
81
  - lib/decorum/chain_stop.rb
@@ -82,6 +83,7 @@ files:
82
83
  - lib/decorum/decorations.rb
83
84
  - lib/decorum/decorator.rb
84
85
  - lib/decorum/decorator_namespace.rb
86
+ - lib/decorum/noaliases.rb
85
87
  - lib/decorum/version.rb
86
88
  - spec/integration/coffee_spec.rb
87
89
  - spec/integration/fibonacci_spec.rb