decorum 0.4.1 → 0.5.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
  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