Permalink
Browse files

Added api to add behavior to layers

Added meta hooks on layers for activation and deactivation
  * currently this does not include repetitive activation and deactivation
Added specs to test the new behavior
Added hook for include in event_machine
  • Loading branch information...
1 parent b4056b0 commit 6bc09e3ad695287da58e236a06b6cca35804843b @schmidt committed Mar 13, 2008
Showing with 119 additions and 4 deletions.
  1. +4 −0 lib/contextr/event_machine.rb
  2. +14 −2 lib/contextr/layer.rb
  3. +43 −2 lib/contextr/public_api.rb
  4. +58 −0 spec/contextr_spec.rb
@@ -62,6 +62,10 @@ def method_added(name)
ContextR::EventMachine::on_method_added(self, name)
super
end
+ def include(modul)
+ modul.instance_method.each { |m| method_added(m) }
+ super
+ end
end
end
end
View
@@ -1,5 +1,17 @@
module ContextR # :nodoc:
- class Layer # :nodoc: all
+ class Layer
+ def activated
+ nil
+ end
+ def deactivated
+ nil
+ end
+ def inspect
+ "ContextR::layer(:#{ContextR::symbol_by_layer(self)})"
+ end
+ alias_method :to_s, :inspect
+
+ # :nodoc: all
def definitions
@definitions ||= {}
end
@@ -65,7 +77,7 @@ def replace_core_method(contextified_class, method_name, version)
version)
end
- def register_callbacks(cclass, mmodule)
+ def register_callbacks(cclass, mmodule)
{:on_wrapper_method_added => mmodule,
:on_class_method_added => cclass }.each do | callback, klass |
ContextR::EventMachine.register(self, callback,
View
@@ -18,7 +18,13 @@ def with_layers(*layer_symbols, &block)
layers = layer_symbols.collect do |layer_symbol|
layer_by_symbol(layer_symbol)
end.reverse
- layered_do(layers | active_layers_as_classes, block)
+ layers_being_activated = layers - active_layers_as_classes
+ layers_being_activated.each { |l| l.activated }
+
+ return_value = layered_do(layers | active_layers_as_classes, block)
+
+ layers_being_activated.each { |l| l.deactivated }
+ return_value
end
alias with_layer with_layers
@@ -40,7 +46,13 @@ def without_layers(*layer_symbols, &block)
layers = layer_symbols.collect do |layer_symbol|
layer_by_symbol(layer_symbol)
end
- layered_do(active_layers_as_classes - layers, block)
+ layers_being_deactivated = layers & active_layers_as_classes
+ layers_being_deactivated.each { |l| l.deactivated }
+
+ return_value = layered_do(active_layers_as_classes - layers, block)
+
+ layers_being_deactivated.each { |l| l.activated }
+ return_value
end
alias without_layer without_layers
@@ -54,6 +66,35 @@ def layers
layers_as_classes.collect { |layer| symbol_by_layer(layer) }
end
+ # returns the layer, defined by the given name. If passed a block, it will
+ # instance_eval it on the layer and return its value instead. The latter
+ # may be used to define the activated and deactived methods for a layer.
+ #
+ # ContextR::layer(:log) do
+ # def logger
+ # @logger ||= Logger.new
+ # end
+ # def activated
+ # logger.log("Logging active")
+ # end
+ # def deactivated
+ # logger.log("Logging inactive")
+ # end
+ # end
+ #
+ # # will call activated before executing the block
+ # # and deactivated afterwards
+ # ContextR::with_layer(:log) do
+ # 1 + 1
+ # end
+ #
+ def layer(name, &block)
+ if block_given?
+ layer_by_symbol(name).instance_eval(&block)
+ else
+ layer_by_symbol(name)
+ end
+ end
end
self.extend(PublicApi)
end
View
@@ -238,6 +238,57 @@ def to_s
ContextR::layers.sort_by{ |s| s.to_s }.should include(layer)
end
end
+
+ it "should return a layer on #layer(:name)" do
+ ContextR::layer(:log).should == ContextR::layer_by_symbol(:log)
+ end
+ it "should execute the block given to #layer(:name)" do
+ lambda do
+ ContextR::layer(:log) do
+ def moo
+ "moo"
+ end
+ end.should == nil
+ end.should_not raise_error
+
+ ContextR::layer(:log).moo == "moo"
+ end
+
+ it "should execute activated for all layers on activation" do
+ ContextR::layer(:log) do
+ def activated
+ raise "activated"
+ end
+ end
+
+ lambda do
+ ContextR::with_layer(:log) { 1 + 1 }
+ end.should raise_error(RuntimeError, "activated")
+
+ ContextR::layer(:log) do
+ def activated
+ nil
+ end
+ end
+ end
+
+ it "should execute deactivated for all layers on deactivation" do
+ ContextR::layer(:log) do
+ def deactivated
+ raise "deactivated"
+ end
+ end
+
+ lambda do
+ ContextR::with_layer(:log) { 1 + 1 }
+ end.should raise_error(RuntimeError, "deactivated")
+
+ ContextR::layer(:log) do
+ def deactivated
+ nil
+ end
+ end
+ end
end
describe "ContextR" do
@@ -252,3 +303,10 @@ def to_s
end
end
end
+
+describe ContextR::Layer do
+ it "should give a nice, self-referencing output on inspect and to_s" do
+ eval(ContextR::layer(:log).inspect).should == ContextR::layer(:log)
+ eval(ContextR::layer(:log).to_s).should == ContextR::layer(:log)
+ end
+end

0 comments on commit 6bc09e3

Please sign in to comment.