From 732532b72eb70e39da54af255b3d659ad4b14095 Mon Sep 17 00:00:00 2001 From: Nico Hagenburger Date: Sat, 1 Feb 2014 23:45:46 +0100 Subject: [PATCH 1/3] upgraded hooks to 0.3.3; integrated custom changes as made for 0.2.0 Conflicts: middleman-core/lib/middleman-core/application.rb --- .../lib/middleman-core/application.rb | 2 +- .../hooks-0.2.0/CHANGES.textile | 9 - .../hooks-0.2.0/Gemfile | 3 - .../hooks-0.2.0/README.rdoc | 107 --------- .../hooks-0.2.0/test/hooks_test.rb | 141 ------------ .../test/inheritable_attribute_test.rb | 55 ----- .../hooks-0.2.0/test/test_helper.rb | 10 - .../hooks-0.3.3/.gitignore | 2 + .../hooks-0.3.3/.travis.yml | 5 + .../hooks-0.3.3/CHANGES.md | 33 +++ .../hooks-0.3.3/Gemfile | 3 + .../hooks-0.3.3/LICENSE.txt | 20 ++ .../hooks-0.3.3/README.md | 202 ++++++++++++++++ .../{hooks-0.2.0 => hooks-0.3.3}/Rakefile | 0 .../hooks.gemspec | 13 +- .../{hooks-0.2.0 => hooks-0.3.3}/lib/hooks.rb | 95 +++++--- .../hooks-0.3.3/lib/hooks/hook.rb | 81 +++++++ .../lib/hooks/inheritable_attribute.rb | 4 +- .../hooks-0.3.3/lib/hooks/instance_hooks.rb | 25 ++ .../hooks-0.3.3/lib/hooks/version.rb | 3 + .../hooks-0.3.3/test/hook_test.rb | 31 +++ .../hooks-0.3.3/test/hooks_test.rb | 216 ++++++++++++++++++ .../test/inheritable_attribute_test.rb | 53 +++++ .../hooks-0.3.3/test/instance_hooks_test.rb | 55 +++++ .../hooks-0.3.3/test/test_helper.rb | 3 + 25 files changed, 804 insertions(+), 367 deletions(-) delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md rename middleman-core/lib/vendored-middleman-deps/{hooks-0.2.0 => hooks-0.3.3}/Rakefile (100%) rename middleman-core/lib/vendored-middleman-deps/{hooks-0.2.0 => hooks-0.3.3}/hooks.gemspec (71%) rename middleman-core/lib/vendored-middleman-deps/{hooks-0.2.0 => hooks-0.3.3}/lib/hooks.rb (54%) create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb rename middleman-core/lib/vendored-middleman-deps/{hooks-0.2.0 => hooks-0.3.3}/lib/hooks/inheritable_attribute.rb (98%) create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb create mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 74c35285..0ae9a811 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -14,7 +14,7 @@ require 'active_support/core_ext/integer/inflections' require 'active_support/core_ext/float/rounding' # Simple callback library -require 'vendored-middleman-deps/hooks-0.2.0/lib/hooks' +require 'vendored-middleman-deps/hooks-0.3.3/lib/hooks' # Our custom logger require 'middleman-core/logger' diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile deleted file mode 100644 index 3beea91d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile +++ /dev/null @@ -1,9 +0,0 @@ -h2. 0.2.0 - -h3. Changes - * Callback blocks are now executed on the instance using @instance_exec@. If you need to access the class (former context) use @self.class@. - -h2. 0.1.4 - -h3. Bugfixes - * An uninitialized @inheritable_attr@ doesn't crash since it is not cloned anymore. Note that an uncloneable attribute value still causes an exception. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile deleted file mode 100644 index a1b93f3e..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source :rubygems - -gemspec diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc deleted file mode 100644 index 4a209500..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc +++ /dev/null @@ -1,107 +0,0 @@ -= Hooks - -Generic hooks with callbacks for Ruby. - - -== Introduction - -_Hooks_ lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as _you_ run the hook! - -It's almost like ActiveSupport::Callbacks but 76,6% less complex. Instead, it is not more than 60 lines of code, one method compilation, no +method_missing+ and no magic. - -Also, you may pass additional arguments to your callbacks when invoking a hook. - -== Example - -Let's take... a cat. - - require 'hooks' - - class Cat - include Hooks - - define_hook :after_dinner - -Now you can add callbacks to your hook declaratively in your class. - - after_dinner do - puts "Ice cream for #{self}!" - end - - after_dinner :have_a_desert # => refers to Cat#have_a_desert - - def have_a_desert - puts "Hell, yeah!" - end - -This will run the block and #have_a_desert from above. - - cat.run_hook :after_dinner - # => Ice cream for #! - Hell, yeah! - -Callback blocks and methods will be executed with instance context. Note how +self+ in the block refers to the Cat instance. - - -== Inheritance - -Hooks are inherited, here's a complete example to put it all together. - - class Garfield < Cat - - after_dinner :want_some_more - - def want_some_more - puts "Is that all?" - end - end - - - Garfield.new.run_hook :after_dinner - # => Ice cream for #! - Hell, yeah! - Is that all? - -Note how the callbacks are invoked in the order they were inherited. - - -== Options for Callbacks - -You're free to pass any number of arguments to #run_callback, those will be passed to the callbacks. - - cat.run_hook :before_dinner, cat, Time.now - -The callbacks should be ready for receiving parameters. - - before_dinner :wash_pawns - before_dinner do |who, when| - ... - end - - def wash_pawns(who, when) - - -Not sure why a cat should have ice cream for dinner. Beside that, I was tempted naming this gem _hooker_. - - -== Installation - - gem install hooks - - -== Anybody using it? - -* Hooks is already used in [Apotomo:http://github.com/apotonick/apotomo], a hot widget framework for Rails. Look at +lib/apotomo/widget.rb+ for examples and into +lib/apotomo/tree_node.rb+ to learn how modules-driven code might benefit from hooks. - -== Similar libraries - -* http://github.com/nakajima/aspectory -* http://github.com/auser/backcall -* http://github.com/mmcgrana/simple_callbacks - - -== License - -Copyright (c) 2010, Nick Sutterer - -Released under the MIT License. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb deleted file mode 100644 index 83cb24e4..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb +++ /dev/null @@ -1,141 +0,0 @@ -require 'test_helper' - -class HooksTest < Test::Unit::TestCase - class TestClass - include Hooks - - def executed - @executed ||= []; - end - end - - - context "Hooks.define_hook" do - setup do - @klass = Class.new(TestClass) - - @mum = @klass.new - @mum.class.define_hook :after_eight - end - - should "provide accessors to the stored callbacks" do - assert_equal [], @klass._after_eight_callbacks - @klass._after_eight_callbacks << :dine - assert_equal [:dine], @klass._after_eight_callbacks - end - - should "respond to Class.callbacks_for_hook" do - assert_equal [], @klass.callbacks_for_hook(:after_eight) - @klass.after_eight :dine - assert_equal [:dine], @klass.callbacks_for_hook(:after_eight) - end - - context "creates a public writer for the hook that" do - should "accepts method names" do - @klass.after_eight :dine - assert_equal [:dine], @klass._after_eight_callbacks - end - - should "accepts blocks" do - @klass.after_eight do true; end - assert @klass._after_eight_callbacks.first.kind_of? Proc - end - - should "be inherited" do - @klass.after_eight :dine - subklass = Class.new(@klass) - - assert_equal [:dine], subklass._after_eight_callbacks - end - end - - context "Hooks#run_hook" do - should "run without parameters" do - @mum.instance_eval do - def a; executed << :a; nil; end - def b; executed << :b; end - - self.class.after_eight :b - self.class.after_eight :a - end - - @mum.run_hook(:after_eight) - - assert_equal [:b, :a], @mum.executed - end - - should "accept arbitrary parameters" do - @mum.instance_eval do - def a(me, arg); executed << arg+1; end - end - @mum.class.after_eight :a - @mum.class.after_eight lambda { |me, arg| me.executed << arg-1 } - - @mum.run_hook(:after_eight, @mum, 1) - - assert_equal [2, 0], @mum.executed - end - - should "execute block callbacks in instance context" do - @mum.class.after_eight { executed << :c } - @mum.run_hook(:after_eight) - assert_equal [:c], @mum.executed - end - end - - context "in class context" do - should "run a callback block" do - executed = [] - @klass.after_eight do - executed << :klass - end - @klass.run_hook :after_eight - - assert_equal [:klass], executed - end - - should "run a class methods" do - executed = [] - @klass.instance_eval do - after_eight :have_dinner - - def have_dinner(executed) - executed << :have_dinner - end - end - @klass.run_hook :after_eight, executed - - assert_equal [:have_dinner], executed - end - end - end - - context "Deriving" do - setup do - @klass = Class.new(TestClass) - - @mum = @klass.new - @mum.class.define_hook :after_eight - end - - should "inherit the hook" do - @klass.class_eval do - after_eight :take_shower - - def take_shower - executed << :take_shower - end - end - - @kid = Class.new(@klass) do - after_eight :have_dinner - - def have_dinner - executed << :have_dinner - end - end.new - - assert_equal [:take_shower, :have_dinner], @kid.run_hook(:after_eight) - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb deleted file mode 100644 index 27e10a2d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'test_helper' - -class HooksTest < Test::Unit::TestCase - context "Hooks.define_hook" do - setup do - @klass = Class.new(Object) do - extend Hooks::InheritableAttribute - end - - @mum = @klass.new - @klass.inheritable_attr :drinks - end - - should "provide a reader with empty inherited attributes, already" do - assert_equal nil, @klass.drinks - end - - should "provide a reader with empty inherited attributes in a derived class" do - assert_equal nil, Class.new(@klass).drinks - #@klass.drinks = true - #Class.new(@klass).drinks # TODO: crashes. - end - - should "provide an attribute copy in subclasses" do - @klass.drinks = [] - assert @klass.drinks.object_id != Class.new(@klass).drinks.object_id - end - - should "provide a writer" do - @klass.drinks = [:cabernet] - assert_equal [:cabernet], @klass.drinks - end - - should "inherit attributes" do - @klass.drinks = [:cabernet] - - subklass_a = Class.new(@klass) - subklass_a.drinks << :becks - - subklass_b = Class.new(@klass) - - assert_equal [:cabernet], @klass.drinks - assert_equal [:cabernet, :becks], subklass_a.drinks - assert_equal [:cabernet], subklass_b.drinks - end - - should "not inherit attributes if we set explicitely" do - @klass.drinks = [:cabernet] - subklass = Class.new(@klass) - - subklass.drinks = [:merlot] # we only want merlot explicitely. - assert_equal [:merlot], subklass.drinks # no :cabernet, here - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb deleted file mode 100644 index f0b0b3cd..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'rubygems' - -# wycats says... -require 'bundler' -Bundler.setup -require 'test/unit' -require 'shoulda' -require 'hooks' - -$:.unshift File.dirname(__FILE__) # add current dir to LOAD_PATHS diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore new file mode 100644 index 00000000..80e3957f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore @@ -0,0 +1,2 @@ +Gemfile.lock + diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml new file mode 100644 index 00000000..03107eec --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml @@ -0,0 +1,5 @@ +language: ruby +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md new file mode 100644 index 00000000..277fda61 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md @@ -0,0 +1,33 @@ +## 0.3.3 + +* Fix a bug where the hook writer method (e.g. `#after_dark`) wasn't available on the instance even when `InstanceHooks` was included. + +## 0.3.2 + +* Added `Hooks::InstanceHooks` to add hooks and/or callbacks on instance level. Thanks to @mpapis for that suggestion. + +## 0.3.1 + +* Fix a bug, string hook names are now treated as symbols. + +## 0.3.0 + +* The callback chain can now be halted by configuring the hook as `halts_on_falsey: true` and returning `nil` or `false` from the callback. +* Internal refactorings: hooks are now encapsulated in `Hook` instances and run their callback chains. + +## 0.2.2 + +* `#run_hook` now returns the list of callback results. + +## 0.2.1 + +* You can now pass multiple hook names to `#define_hooks`. + +## 0.2.0 + +h3. Changes +* Callback blocks are now executed on the instance using `instance_exec`. If you need to access the class (former context) use `self.class`. + +## 0.1.4 + +* An uninitialized `inheritable_attr` doesn't crash since it is not cloned anymore. Note that an uncloneable attribute value still causes an exception. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile new file mode 100644 index 00000000..fa75df15 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt new file mode 100644 index 00000000..ffbc659d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011-2013 Nick Sutterer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md new file mode 100644 index 00000000..436d988d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md @@ -0,0 +1,202 @@ +# Hooks + +_Generic hooks with callbacks for Ruby._ + + +## Introduction + +_Hooks_ lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as _you_ run the hook! + +It's almost like ActiveSupport::Callbacks but 76,6% less complex. Instead, it is not more than a few lines of code, one method compilation, no `method_missing` and no magic. + +Also, you may pass additional arguments to your callbacks when invoking a hook. + +## Example + +Let's take... a cat. + +```ruby +require 'hooks' + +class Cat + include Hooks + + define_hooks :before_dinner, :after_dinner +``` + +Now you can add callbacks to your hook declaratively in your class. + +```ruby + before_dinner :wash_paws + + after_dinner do + puts "Ice cream for #{self}!" + end + + after_dinner :have_a_desert # => refers to Cat#have_a_desert + + def have_a_desert + puts "Hell, yeah!" + end +``` + +This will run the block and `#have_a_desert` from above. + +```ruby +cat.run_hook :after_dinner +# => Ice cream for #! + Hell, yeah! +``` + +Callback blocks and methods will be executed with instance context. Note how `self` in the block refers to the Cat instance. + + +## Inheritance + +Hooks are inherited, here's a complete example to put it all together. + +```ruby +class Garfield < Cat + + after_dinner :want_some_more + + def want_some_more + puts "Is that all?" + end +end + + +Garfield.new.run_hook :after_dinner +# => Ice cream for #! + Hell, yeah! + Is that all? +``` + +Note how the callbacks are invoked in the order they were inherited. + + +## Options for Callbacks + +You're free to pass any number of arguments to #run_callback, those will be passed to the callbacks. + +```ruby +cat.run_hook :before_dinner, cat, Time.now +``` + +The callbacks should be ready for receiving parameters. + +```ruby +before_dinner :wash_pawns +before_dinner do |who, when| + ... +end + +def wash_pawns(who, when) +``` + +Not sure why a cat should have ice cream for dinner. Beside that, I was tempted naming this gem _hooker_. + + +## Running And Halting Hooks + +Using `#run_hook` doesn't only run all callbacks for this hook but also returns an array of the results from each callback method or block. + +```ruby +class Garfield + include Hooks + define_hook :after_dark + + after_dark { "Chase mice" } + after_dark { "Enjoy supper" } +end + +Garfield.new.run_hook :after_dark +# => ["Chase mice", "Enjoy supper"] +``` + +This is handy if you need to collect data from your callbacks without having to access a global (brrr) variable. + +With the `:halts_on_falsey` option you can halt the callback chain when a callback returns `nil` or `false`. + +```ruby +class Garfield + include Hooks + define_hook :after_dark, halts_on_falsey: true + + after_dark { "Chase mice" } + after_dark { nil } + after_dark { "Enjoy supper" } +end + +result = Garfield.new.run_hook :after_dark +# => ["Chase mice"] +``` + +This will only run the first two callbacks. Note that the result doesn't contain the `nil` value. You even can check if the chain was halted. + +```ruby +result.halted? #=> true +``` + +## Instance Hooks + +You can also define hooks and/or add callbacks per instance. This is helpful if your class should define a basic set of hooks and callbacks that are then extended by instances. + +```ruby +class Cat + include Hooks + include Hooks::InstanceHooks + + define_hook :after_dark + + after_dark { "Chase mice" } +end +``` + +Note that you have to include `Hooks::InstanceHooks` to get this additional functionality. + +See how callbacks can be added to a separate object, now. + +```ruby +garfield = Cat.new + +garfield.after_dark :sleep +garfield.run_hook(:after_dark) # => invoke "Chase mice" hook and #sleep +``` + +This will copy all callbacks from the `after_dark` hook to the instance and add a second hook. This all happens on the `garfield` instance, only, and leaves the class untouched. + +Naturally, adding new hooks works like-wise. + +```ruby +garfield.define_hook :before_six +garfield.before_six { .. } +``` +This feature was added in 0.3.2. + + +## Installation + +In your Gemfile, do + +```ruby +gem "hooks" +``` + +## Anybody using it? + +* Hooks is already used in [Apotomo](http://github.com/apotonick/apotomo), a hot widget framework for Rails. +* The [datamappify](https://github.com/fredwu/datamappify) gem uses hooks and the author Fred Wu contributed to this gem! + +## Similar libraries + +* http://github.com/nakajima/aspectory +* http://github.com/auser/backcall +* http://github.com/mmcgrana/simple_callbacks + + +## License + +Copyright (c) 2013, Nick Sutterer + +Released under the MIT License. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Rakefile b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile similarity index 100% rename from middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Rakefile rename to middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec similarity index 71% rename from middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec rename to middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec index 326f75c0..fe7c1cf4 100644 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec @@ -1,7 +1,7 @@ lib = File.expand_path('../lib/', __FILE__) $:.unshift lib unless $:.include?(lib) -require 'hooks' +require 'hooks/version' Gem::Specification.new do |s| s.name = "hooks" @@ -9,14 +9,17 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.authors = ["Nick Sutterer"] s.email = ["apotonick@gmail.com"] - s.homepage = "http://nicksda.apotomo.de/tag/hooks" + s.homepage = "http://nicksda.apotomo.de/2010/09/hooks-and-callbacks-for-ruby-but-simple/" s.summary = %q{Generic hooks with callbacks for Ruby.} s.description = %q{Declaratively define hooks, add callbacks and run them with the options you like.} - + s.license = "MIT" + s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.require_paths = ["lib"] - - s.add_development_dependency "shoulda" + s.license = 'MIT' + + s.add_development_dependency "minitest", ">= 5.0.0" s.add_development_dependency "rake" + s.add_development_dependency "pry" end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb similarity index 54% rename from middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb rename to middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb index 9c4ca879..02ad0964 100644 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb @@ -1,35 +1,41 @@ require File.join(File.dirname(__FILE__), "hooks/inheritable_attribute") +require File.join(File.dirname(__FILE__), "hooks/hook") # Almost like ActiveSupport::Callbacks but 76,6% less complex. # # Example: # # class CatWidget < Apotomo::Widget -# define_hook :after_dinner +# define_hooks :before_dinner, :after_dinner # # Now you can add callbacks to your hook declaratively in your class. # -# after_dinner do puts "Ice cream!" end +# before_dinner :wash_paws +# after_dinner { puts "Ice cream!" } # after_dinner :have_a_desert # => refers to CatWidget#have_a_desert # # Running the callbacks happens on instances. It will run the block and #have_a_desert from above. # # cat.run_hook :after_dinner module Hooks - VERSION = "0.2.0" - def self.included(base) - base.extend InheritableAttribute - base.extend ClassMethods + base.class_eval do + extend InheritableAttribute + extend ClassMethods + inheritable_attr :_hooks + self._hooks= HookSet.new + end end module ClassMethods - def define_hook(name) - accessor_name = "_#{name}_callbacks" + def define_hooks(*names) + options = extract_options!(names) - setup_hook_accessors(accessor_name) - define_hook_writer(name, accessor_name) + names.each do |name| + setup_hook(name, options) + end end + alias_method :define_hook, :define_hooks # Like Hooks#run_hook but for the class. Note that +:callbacks+ must be class methods. # @@ -46,13 +52,7 @@ module Hooks end def run_hook_for(name, scope, *args) - callbacks_for_hook(name).each do |callback| - if callback.kind_of? Symbol - scope.send(callback, *args) - else - scope.instance_exec(*args, &callback) - end - end + _hooks[name].run(scope, *args) end # Returns the callbacks for +name+. Handy if you want to run the callbacks yourself, say when @@ -67,28 +67,37 @@ module Hooks # # would run callbacks in the object _instance_ context, passing +self+ as block parameter. def callbacks_for_hook(name) - send("_#{name}_callbacks") + _hooks[name] end private - - def define_hook_writer(hook, accessor_name) - self.send(:define_method, hook.to_sym) do |&block| - if self.class.respond_to?(hook) - self.class.send(hook.to_sym, &block) - end - end - - instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{hook}(method=nil, &block) - #{accessor_name} << (block || method) - end - RUBY_EVAL + def setup_hook(name, options) + _hooks[name] = Hook.new(options) + define_hook_writer(name) end - def setup_hook_accessors(accessor_name) - inheritable_attr(accessor_name) - send("#{accessor_name}=", []) # initialize ivar. + def define_hook_writer(name) + self.send(:define_method, name.to_sym) do |&block| + if self.class.respond_to?(name) + self.class.send(name.to_sym, &block) + end + end + instance_eval *hook_writer_args(name) + end + + def hook_writer_args(name) + # DISCUSS: isn't there a simpler way to define a dynamic method? should the internal logic be handled by HooksSet instead? + str = <<-RUBY_EVAL + def #{name}(method=nil, &block) + _hooks[:#{name}] << (block || method) + end + RUBY_EVAL + + [str, __FILE__, __LINE__ + 1] + end + + def extract_options!(args) + args.last.is_a?(Hash) ? args.pop : {} end end @@ -106,4 +115,22 @@ module Hooks def run_hook(name, *args) self.class.run_hook_for(name, self, *args) end + + class HookSet < Hash + def [](name) + super(name.to_sym) + end + + def []=(name, values) + super(name.to_sym, values) + end + + def clone + super.tap do |cloned| + each { |name, callbacks| cloned[name] = callbacks.clone } + end + end + end end + +require File.join(File.dirname(__FILE__), "hooks/instance_hooks") diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb new file mode 100644 index 00000000..0f4d65a7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb @@ -0,0 +1,81 @@ +module Hooks + class Hook < Array + def initialize(options) + super() + @options = options + end + + # The chain contains the return values of the executed callbacks. + # + # Example: + # + # class Person + # define_hook :before_eating + # + # before_eating :wash_hands + # before_eating :locate_food + # before_eating :sit_down + # + # def wash_hands; :washed_hands; end + # def locate_food; :located_food; false; end + # def sit_down; :sat_down; end + # end + # + # result = person.run_hook(:before_eating) + # result.chain #=> [:washed_hands, false, :sat_down] + # + # If :halts_on_falsey is enabled: + # + # class Person + # define_hook :before_eating, :halts_on_falsey => true + # # ... + # end + # + # result = person.run_hook(:before_eating) + # result.chain #=> [:washed_hands] + def run(scope, *args) + inject(Results.new) do |results, callback| + executed = execute_callback(scope, callback, *args) + + return results.halted! unless continue_execution?(executed) + results << executed + end + end + + private + def execute_callback(scope, callback, *args) + if callback.kind_of?(Symbol) + scope.send(callback, *args) + else + scope.instance_exec(*args, &callback) + end + end + + def continue_execution?(result) + @options[:halts_on_falsey] ? result : true + end + + class Results < Array + # so much code for nothing... + def initialize(*) + super + @halted = false + end + + def halted! + @halted = true + self + end + + # Returns true or false based on whether all callbacks + # in the hook chain were successfully executed. + def halted? + @halted + end + + def not_halted? + not @halted + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb similarity index 98% rename from middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb rename to middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb index 88f24b4f..352e28d6 100644 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb @@ -22,12 +22,12 @@ module Hooks def #{name}=(v) @#{name} = v end - + def #{name} return @#{name} unless superclass.respond_to?(:#{name}) and value = superclass.#{name} @#{name} ||= value.clone # only do this once. end } end - end + end end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb new file mode 100644 index 00000000..0f523fa4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb @@ -0,0 +1,25 @@ +module Hooks + module InstanceHooks + include ClassMethods + + def run_hook(name, *args) + run_hook_for(name, self, *args) + end + + private + def _hooks + @_hooks ||= self.class._hooks.clone # TODO: generify that with representable_attrs. + end + + module ClassMethods + def define_hook_writer(name) + super + class_eval *hook_writer_args(name) + end + end + + def self.included(base) + base.extend(ClassMethods) + end + end +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb new file mode 100644 index 00000000..788aaf77 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb @@ -0,0 +1,3 @@ +module Hooks + VERSION = "0.3.3" +end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb new file mode 100644 index 00000000..5d539be1 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb @@ -0,0 +1,31 @@ +require 'test_helper' + +class HookTest < MiniTest::Spec + subject { Hooks::Hook.new({}) } + + it "exposes array behaviour for callbacks" do + subject << :play_music + subject << :drink_beer + + subject.to_a.must_equal [:play_music, :drink_beer] + end +end + +class ResultsTest < MiniTest::Spec + subject { Hooks::Hook::Results.new } + + describe "#halted?" do + it "defaults to false" do + subject.halted?.must_equal false + end + + it "responds to #halted!" do + subject.halted! + subject.halted?.must_equal true + end + + it "responds to #not_halted?" do + subject.not_halted?.must_equal true + end + end +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb new file mode 100644 index 00000000..151a4b3d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb @@ -0,0 +1,216 @@ +require 'test_helper' + +class HooksTest < MiniTest::Spec + class TestClass + include Hooks + + def executed + @executed ||= []; + end + end + + + describe "::define_hook" do + let(:klass) do + Class.new(TestClass) do + define_hook :after_eight + end + end + + subject { klass.new } + + it "respond to Class.callbacks_for_hook" do + assert_equal [], klass.callbacks_for_hook(:after_eight) + klass.after_eight :dine + assert_equal [:dine], klass.callbacks_for_hook(:after_eight) + end + + it 'symbolizes strings when defining a hook' do + subject.class.define_hooks :before_one, 'after_one' + assert_equal [], klass.callbacks_for_hook(:before_one) + assert_equal [], klass.callbacks_for_hook(:after_one) + assert_equal [], klass.callbacks_for_hook('after_one') + end + + it "accept multiple hook names" do + subject.class.define_hooks :before_ten, :after_ten + assert_equal [], klass.callbacks_for_hook(:before_ten) + assert_equal [], klass.callbacks_for_hook(:after_ten) + end + + describe "creates a public writer for the hook that" do + it "accepts method names" do + klass.after_eight :dine + assert_equal [:dine], klass._hooks[:after_eight] + end + + it "accepts blocks" do + klass.after_eight do true; end + assert klass._hooks[:after_eight].first.kind_of? Proc + end + + it "be inherited" do + klass.after_eight :dine + subklass = Class.new(klass) + + assert_equal [:dine], subklass._hooks[:after_eight] + end + # TODO: check if options are not shared! + end + + describe "Hooks#run_hook" do + it "run without parameters" do + subject.instance_eval do + def a; executed << :a; nil; end + def b; executed << :b; end + + self.class.after_eight :b + self.class.after_eight :a + end + + subject.run_hook(:after_eight) + + assert_equal [:b, :a], subject.executed + end + + it "returns empty Results when no callbacks defined" do + subject.run_hook(:after_eight).must_equal Hooks::Hook::Results.new + end + + it "accept arbitrary parameters" do + subject.instance_eval do + def a(me, arg); executed << arg+1; end + end + subject.class.after_eight :a + subject.class.after_eight lambda { |me, arg| me.executed << arg-1 } + + subject.run_hook(:after_eight, subject, 1) + + assert_equal [2, 0], subject.executed + end + + it "execute block callbacks in instance context" do + subject.class.after_eight { executed << :c } + subject.run_hook(:after_eight) + assert_equal [:c], subject.executed + end + + it "returns all callbacks in order" do + subject.class.after_eight { :dinner_out } + subject.class.after_eight { :party_hard } + subject.class.after_eight { :taxi_home } + + results = subject.run_hook(:after_eight) + + assert_equal [:dinner_out, :party_hard, :taxi_home], results + assert_equal false, results.halted? + assert_equal true, results.not_halted? + end + + describe "halts_on_falsey: true" do + let(:klass) do + Class.new(TestClass) do + define_hook :after_eight, :halts_on_falsey => true + end + end + + [nil, false].each do |falsey| + it "returns successful callbacks in order (with #{falsey.inspect})" do + ordered = [] + + subject.class.after_eight { :dinner_out } + subject.class.after_eight { :party_hard; falsey } + subject.class.after_eight { :taxi_home } + + results = subject.run_hook(:after_eight) + + assert_equal [:dinner_out], results + assert_equal true, results.halted? + end + end + end + + describe "halts_on_falsey: false" do + [nil, false].each do |falsey| + it "returns all callbacks in order (with #{falsey.inspect})" do + ordered = [] + + subject.class.after_eight { :dinner_out } + subject.class.after_eight { :party_hard; falsey } + subject.class.after_eight { :taxi_home } + + results = subject.run_hook(:after_eight) + + assert_equal [:dinner_out, falsey, :taxi_home], results + assert_equal false, results.halted? + end + end + end + end + + describe "in class context" do + it "runs callback block" do + executed = [] + klass.after_eight do + executed << :klass + end + klass.run_hook(:after_eight) + + executed.must_equal([:klass]) + end + + it "runs instance methods" do + executed = [] + klass.instance_eval do + after_eight :have_dinner + + def have_dinner(executed) + executed << :have_dinner + end + end + klass.run_hook(:after_eight, executed) + + executed.must_equal([:have_dinner]) + end + end + end + + describe "Inheritance" do + let (:superclass) { + Class.new(TestClass) do + define_hook :after_eight + + after_eight :take_shower + end + } + + let (:subclass) { Class.new(superclass) do after_eight :have_dinner end } + + it "inherits callbacks from the hook" do + subclass.callbacks_for_hook(:after_eight).must_equal [:take_shower, :have_dinner] + end + + it "doesn't mix up superclass hooks" do + subclass.superclass.callbacks_for_hook(:after_eight).must_equal [:take_shower] + end + end +end + +class HookSetTest < MiniTest::Spec + subject { Hooks::HookSet.new } + + let (:first_hook) { Hooks::Hook.new(:halts_on_falsey => true) } + let (:second_hook) { Hooks::Hook.new(:halts_on_falsey => false) } + + it "responds to #clone" do + subject[:after_eight] = [first_hook] + + clone = subject.clone + + clone[:after_eight] << second_hook + + subject.must_equal(:after_eight => [first_hook]) + clone.must_equal(:after_eight => [first_hook, second_hook]) + end + # TODO: test if options get cloned. +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb new file mode 100644 index 00000000..4cc14e58 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class HooksTest < MiniTest::Spec + describe "Hooks.define_hook" do + subject { + Class.new(Object) do + extend Hooks::InheritableAttribute + inheritable_attr :drinks + end + } + + it "provides a reader with empty inherited attributes, already" do + assert_equal nil, subject.drinks + end + + it "provides a reader with empty inherited attributes in a derived class" do + assert_equal nil, Class.new(subject).drinks + #subject.drinks = true + #Class.new(subject).drinks # TODO: crashes. + end + + it "provides an attribute copy in subclasses" do + subject.drinks = [] + assert subject.drinks.object_id != Class.new(subject).drinks.object_id + end + + it "provides a writer" do + subject.drinks = [:cabernet] + assert_equal [:cabernet], subject.drinks + end + + it "inherits attributes" do + subject.drinks = [:cabernet] + + subklass_a = Class.new(subject) + subklass_a.drinks << :becks + + subklass_b = Class.new(subject) + + assert_equal [:cabernet], subject.drinks + assert_equal [:cabernet, :becks], subklass_a.drinks + assert_equal [:cabernet], subklass_b.drinks + end + + it "does not inherit attributes if we set explicitely" do + subject.drinks = [:cabernet] + subklass = Class.new(subject) + + subklass.drinks = [:merlot] # we only want merlot explicitely. + assert_equal [:merlot], subklass.drinks # no :cabernet, here + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb new file mode 100644 index 00000000..ffac3fb5 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb @@ -0,0 +1,55 @@ +require "test_helper" + +class InstanceHooksTest < HooksTest + describe "#define_hook" do + let(:klass) { Class.new(TestClass) do + include Hooks::InstanceHooks + end } + + subject { klass.new.tap do |obj| + obj.instance_eval do + def dine; executed << :dine; end + end + end } + + it "adds hook to instance" do + subject.define_hook :after_eight + + assert_equal [], subject.callbacks_for_hook(:after_eight) + end + + it "copies existing class hook" do + klass.define_hook :after_eight + klass.after_eight :dine + + assert_equal [:dine], subject.callbacks_for_hook(:after_eight) + end + + describe "#after_eight (adding callbacks)" do + before do + subject.define_hook :after_eight + subject.after_eight :dine + end + + it "adds #after_eight hook" do + assert_equal [:dine], subject.callbacks_for_hook(:after_eight) + end + + it "responds to #run_hook" do + subject.run_hook :after_eight + subject.executed.must_equal [:dine] + end + end + + describe "#after_eight from class (no define_hook in instance)" do + it "responds to #after_eight" do + klass.define_hook :after_eight + + subject.after_eight :dine + + subject.run_hook :after_eight + subject.executed.must_equal [:dine] + end + end + end +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb new file mode 100644 index 00000000..2ece0d0e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb @@ -0,0 +1,3 @@ +require 'minitest/autorun' +require 'pry' +require 'hooks' From e5d95944c4843cedc485c0d08157055f8afe64cf Mon Sep 17 00:00:00 2001 From: Nico Hagenburger Date: Sun, 2 Feb 2014 11:12:57 +0100 Subject: [PATCH 2/3] =?UTF-8?q?use=20instance=20hooks=20provided=20by=20ho?= =?UTF-8?q?oks=20instead=20of=20changing=20the=20gem=E2=80=99s=20source?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conflicts: middleman-core/lib/middleman-core/core_extensions/extensions.rb --- middleman-core/lib/middleman-core/application.rb | 7 +++++++ .../lib/middleman-more/core_extensions/compass.rb | 4 ++-- .../lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb | 5 ----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 0ae9a811..bf549708 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -32,6 +32,7 @@ module Middleman # Uses callbacks include Hooks + include Hooks::InstanceHooks # Before request hook define_hook :before @@ -223,6 +224,12 @@ module Middleman end alias :inspect :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s + # Hooks clones _hooks from the class to the instance. + # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 + # Middleman expects the same list of hooks for class and instance hooks: + def _hooks + self.class._hooks + end end end diff --git a/middleman-core/lib/middleman-more/core_extensions/compass.rb b/middleman-core/lib/middleman-more/core_extensions/compass.rb index cdf2c299..2aa46d47 100644 --- a/middleman-core/lib/middleman-more/core_extensions/compass.rb +++ b/middleman-core/lib/middleman-more/core_extensions/compass.rb @@ -49,7 +49,7 @@ class Middleman::CoreExtensions::Compass < ::Middleman::Extension end # Call hook - app.run_hook :compass_config, ::Compass.configuration + app.run_hook_for :compass_config, app, ::Compass.configuration # Tell Tilt to use it as well (for inline sass blocks) ::Tilt.register 'sass', CompassSassTemplate @@ -73,4 +73,4 @@ class Middleman::CoreExtensions::Compass < ::Middleman::Extension super.merge(::Compass.configuration.to_sass_engine_options) end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb index 02ad0964..d7c6d5dd 100644 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb +++ b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb @@ -77,11 +77,6 @@ module Hooks end def define_hook_writer(name) - self.send(:define_method, name.to_sym) do |&block| - if self.class.respond_to?(name) - self.class.send(name.to_sym, &block) - end - end instance_eval *hook_writer_args(name) end From 0c3000c799fc2e0cccd3635c9611aef23286105e Mon Sep 17 00:00:00 2001 From: Nico Hagenburger Date: Sun, 2 Feb 2014 11:18:25 +0100 Subject: [PATCH 3/3] =?UTF-8?q?as=20there=20are=20no=20more=20local=20chan?= =?UTF-8?q?ges=20in=20the=20hooks=E2=80=99=20source,=20it=20can=20be=20unv?= =?UTF-8?q?endored=20and=20used=20as=20gem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/middleman-core/application.rb | 2 +- .../hooks-0.3.3/.gitignore | 2 - .../hooks-0.3.3/.travis.yml | 5 - .../hooks-0.3.3/CHANGES.md | 33 --- .../hooks-0.3.3/Gemfile | 3 - .../hooks-0.3.3/LICENSE.txt | 20 -- .../hooks-0.3.3/README.md | 202 ---------------- .../hooks-0.3.3/Rakefile | 12 - .../hooks-0.3.3/hooks.gemspec | 25 -- .../hooks-0.3.3/lib/hooks.rb | 131 ----------- .../hooks-0.3.3/lib/hooks/hook.rb | 81 ------- .../lib/hooks/inheritable_attribute.rb | 33 --- .../hooks-0.3.3/lib/hooks/instance_hooks.rb | 25 -- .../hooks-0.3.3/lib/hooks/version.rb | 3 - .../hooks-0.3.3/test/hook_test.rb | 31 --- .../hooks-0.3.3/test/hooks_test.rb | 216 ------------------ .../test/inheritable_attribute_test.rb | 53 ----- .../hooks-0.3.3/test/instance_hooks_test.rb | 55 ----- .../hooks-0.3.3/test/test_helper.rb | 3 - middleman-core/middleman-core.gemspec | 1 + 20 files changed, 2 insertions(+), 934 deletions(-) delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb delete mode 100644 middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index bf549708..13595135 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -14,7 +14,7 @@ require 'active_support/core_ext/integer/inflections' require 'active_support/core_ext/float/rounding' # Simple callback library -require 'vendored-middleman-deps/hooks-0.3.3/lib/hooks' +require 'hooks' # Our custom logger require 'middleman-core/logger' diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore deleted file mode 100644 index 80e3957f..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Gemfile.lock - diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml deleted file mode 100644 index 03107eec..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: ruby -rvm: - - 1.8.7 - - 1.9.3 - - 2.0.0 diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md deleted file mode 100644 index 277fda61..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/CHANGES.md +++ /dev/null @@ -1,33 +0,0 @@ -## 0.3.3 - -* Fix a bug where the hook writer method (e.g. `#after_dark`) wasn't available on the instance even when `InstanceHooks` was included. - -## 0.3.2 - -* Added `Hooks::InstanceHooks` to add hooks and/or callbacks on instance level. Thanks to @mpapis for that suggestion. - -## 0.3.1 - -* Fix a bug, string hook names are now treated as symbols. - -## 0.3.0 - -* The callback chain can now be halted by configuring the hook as `halts_on_falsey: true` and returning `nil` or `false` from the callback. -* Internal refactorings: hooks are now encapsulated in `Hook` instances and run their callback chains. - -## 0.2.2 - -* `#run_hook` now returns the list of callback results. - -## 0.2.1 - -* You can now pass multiple hook names to `#define_hooks`. - -## 0.2.0 - -h3. Changes -* Callback blocks are now executed on the instance using `instance_exec`. If you need to access the class (former context) use `self.class`. - -## 0.1.4 - -* An uninitialized `inheritable_attr` doesn't crash since it is not cloned anymore. Note that an uncloneable attribute value still causes an exception. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile deleted file mode 100644 index fa75df15..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gemspec diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt deleted file mode 100644 index ffbc659d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2011-2013 Nick Sutterer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md deleted file mode 100644 index 436d988d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# Hooks - -_Generic hooks with callbacks for Ruby._ - - -## Introduction - -_Hooks_ lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as _you_ run the hook! - -It's almost like ActiveSupport::Callbacks but 76,6% less complex. Instead, it is not more than a few lines of code, one method compilation, no `method_missing` and no magic. - -Also, you may pass additional arguments to your callbacks when invoking a hook. - -## Example - -Let's take... a cat. - -```ruby -require 'hooks' - -class Cat - include Hooks - - define_hooks :before_dinner, :after_dinner -``` - -Now you can add callbacks to your hook declaratively in your class. - -```ruby - before_dinner :wash_paws - - after_dinner do - puts "Ice cream for #{self}!" - end - - after_dinner :have_a_desert # => refers to Cat#have_a_desert - - def have_a_desert - puts "Hell, yeah!" - end -``` - -This will run the block and `#have_a_desert` from above. - -```ruby -cat.run_hook :after_dinner -# => Ice cream for #! - Hell, yeah! -``` - -Callback blocks and methods will be executed with instance context. Note how `self` in the block refers to the Cat instance. - - -## Inheritance - -Hooks are inherited, here's a complete example to put it all together. - -```ruby -class Garfield < Cat - - after_dinner :want_some_more - - def want_some_more - puts "Is that all?" - end -end - - -Garfield.new.run_hook :after_dinner -# => Ice cream for #! - Hell, yeah! - Is that all? -``` - -Note how the callbacks are invoked in the order they were inherited. - - -## Options for Callbacks - -You're free to pass any number of arguments to #run_callback, those will be passed to the callbacks. - -```ruby -cat.run_hook :before_dinner, cat, Time.now -``` - -The callbacks should be ready for receiving parameters. - -```ruby -before_dinner :wash_pawns -before_dinner do |who, when| - ... -end - -def wash_pawns(who, when) -``` - -Not sure why a cat should have ice cream for dinner. Beside that, I was tempted naming this gem _hooker_. - - -## Running And Halting Hooks - -Using `#run_hook` doesn't only run all callbacks for this hook but also returns an array of the results from each callback method or block. - -```ruby -class Garfield - include Hooks - define_hook :after_dark - - after_dark { "Chase mice" } - after_dark { "Enjoy supper" } -end - -Garfield.new.run_hook :after_dark -# => ["Chase mice", "Enjoy supper"] -``` - -This is handy if you need to collect data from your callbacks without having to access a global (brrr) variable. - -With the `:halts_on_falsey` option you can halt the callback chain when a callback returns `nil` or `false`. - -```ruby -class Garfield - include Hooks - define_hook :after_dark, halts_on_falsey: true - - after_dark { "Chase mice" } - after_dark { nil } - after_dark { "Enjoy supper" } -end - -result = Garfield.new.run_hook :after_dark -# => ["Chase mice"] -``` - -This will only run the first two callbacks. Note that the result doesn't contain the `nil` value. You even can check if the chain was halted. - -```ruby -result.halted? #=> true -``` - -## Instance Hooks - -You can also define hooks and/or add callbacks per instance. This is helpful if your class should define a basic set of hooks and callbacks that are then extended by instances. - -```ruby -class Cat - include Hooks - include Hooks::InstanceHooks - - define_hook :after_dark - - after_dark { "Chase mice" } -end -``` - -Note that you have to include `Hooks::InstanceHooks` to get this additional functionality. - -See how callbacks can be added to a separate object, now. - -```ruby -garfield = Cat.new - -garfield.after_dark :sleep -garfield.run_hook(:after_dark) # => invoke "Chase mice" hook and #sleep -``` - -This will copy all callbacks from the `after_dark` hook to the instance and add a second hook. This all happens on the `garfield` instance, only, and leaves the class untouched. - -Naturally, adding new hooks works like-wise. - -```ruby -garfield.define_hook :before_six -garfield.before_six { .. } -``` -This feature was added in 0.3.2. - - -## Installation - -In your Gemfile, do - -```ruby -gem "hooks" -``` - -## Anybody using it? - -* Hooks is already used in [Apotomo](http://github.com/apotonick/apotomo), a hot widget framework for Rails. -* The [datamappify](https://github.com/fredwu/datamappify) gem uses hooks and the author Fred Wu contributed to this gem! - -## Similar libraries - -* http://github.com/nakajima/aspectory -* http://github.com/auser/backcall -* http://github.com/mmcgrana/simple_callbacks - - -## License - -Copyright (c) 2013, Nick Sutterer - -Released under the MIT License. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile deleted file mode 100644 index 4799b87b..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/Rakefile +++ /dev/null @@ -1,12 +0,0 @@ -require 'rake' -require 'rake/testtask' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the hooks plugin.' -Rake::TestTask.new(:test) do |test| - test.libs << 'test' - test.test_files = FileList['test/*_test.rb'] - test.verbose = true -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec deleted file mode 100644 index fe7c1cf4..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/hooks.gemspec +++ /dev/null @@ -1,25 +0,0 @@ -lib = File.expand_path('../lib/', __FILE__) -$:.unshift lib unless $:.include?(lib) - -require 'hooks/version' - -Gem::Specification.new do |s| - s.name = "hooks" - s.version = Hooks::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["Nick Sutterer"] - s.email = ["apotonick@gmail.com"] - s.homepage = "http://nicksda.apotomo.de/2010/09/hooks-and-callbacks-for-ruby-but-simple/" - s.summary = %q{Generic hooks with callbacks for Ruby.} - s.description = %q{Declaratively define hooks, add callbacks and run them with the options you like.} - s.license = "MIT" - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.require_paths = ["lib"] - s.license = 'MIT' - - s.add_development_dependency "minitest", ">= 5.0.0" - s.add_development_dependency "rake" - s.add_development_dependency "pry" -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb deleted file mode 100644 index d7c6d5dd..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks.rb +++ /dev/null @@ -1,131 +0,0 @@ -require File.join(File.dirname(__FILE__), "hooks/inheritable_attribute") -require File.join(File.dirname(__FILE__), "hooks/hook") - -# Almost like ActiveSupport::Callbacks but 76,6% less complex. -# -# Example: -# -# class CatWidget < Apotomo::Widget -# define_hooks :before_dinner, :after_dinner -# -# Now you can add callbacks to your hook declaratively in your class. -# -# before_dinner :wash_paws -# after_dinner { puts "Ice cream!" } -# after_dinner :have_a_desert # => refers to CatWidget#have_a_desert -# -# Running the callbacks happens on instances. It will run the block and #have_a_desert from above. -# -# cat.run_hook :after_dinner -module Hooks - def self.included(base) - base.class_eval do - extend InheritableAttribute - extend ClassMethods - inheritable_attr :_hooks - self._hooks= HookSet.new - end - end - - module ClassMethods - def define_hooks(*names) - options = extract_options!(names) - - names.each do |name| - setup_hook(name, options) - end - end - alias_method :define_hook, :define_hooks - - # Like Hooks#run_hook but for the class. Note that +:callbacks+ must be class methods. - # - # Example: - # - # class Cat - # after_eight :grab_a_beer - # - # def self.grab_a_beer(*) # and so on... - # - # where Cat.run_hook :after_eight will call the class method +grab_a_beer+. - def run_hook(name, *args) - run_hook_for(name, self, *args) - end - - def run_hook_for(name, scope, *args) - _hooks[name].run(scope, *args) - end - - # Returns the callbacks for +name+. Handy if you want to run the callbacks yourself, say when - # they should be executed in another context. - # - # Example: - # - # def initialize - # self.class.callbacks_for_hook(:after_eight).each do |callback| - # instance_exec(self, &callback) - # end - # - # would run callbacks in the object _instance_ context, passing +self+ as block parameter. - def callbacks_for_hook(name) - _hooks[name] - end - - private - def setup_hook(name, options) - _hooks[name] = Hook.new(options) - define_hook_writer(name) - end - - def define_hook_writer(name) - instance_eval *hook_writer_args(name) - end - - def hook_writer_args(name) - # DISCUSS: isn't there a simpler way to define a dynamic method? should the internal logic be handled by HooksSet instead? - str = <<-RUBY_EVAL - def #{name}(method=nil, &block) - _hooks[:#{name}] << (block || method) - end - RUBY_EVAL - - [str, __FILE__, __LINE__ + 1] - end - - def extract_options!(args) - args.last.is_a?(Hash) ? args.pop : {} - end - end - - # Runs the callbacks (method/block) for the specified hook +name+. Additional arguments will - # be passed to the callback. - # - # Example: - # - # cat.run_hook :after_dinner, "i want ice cream!" - # - # will invoke the callbacks like - # - # desert("i want ice cream!") - # block.call("i want ice cream!") - def run_hook(name, *args) - self.class.run_hook_for(name, self, *args) - end - - class HookSet < Hash - def [](name) - super(name.to_sym) - end - - def []=(name, values) - super(name.to_sym, values) - end - - def clone - super.tap do |cloned| - each { |name, callbacks| cloned[name] = callbacks.clone } - end - end - end -end - -require File.join(File.dirname(__FILE__), "hooks/instance_hooks") diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb deleted file mode 100644 index 0f4d65a7..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/hook.rb +++ /dev/null @@ -1,81 +0,0 @@ -module Hooks - class Hook < Array - def initialize(options) - super() - @options = options - end - - # The chain contains the return values of the executed callbacks. - # - # Example: - # - # class Person - # define_hook :before_eating - # - # before_eating :wash_hands - # before_eating :locate_food - # before_eating :sit_down - # - # def wash_hands; :washed_hands; end - # def locate_food; :located_food; false; end - # def sit_down; :sat_down; end - # end - # - # result = person.run_hook(:before_eating) - # result.chain #=> [:washed_hands, false, :sat_down] - # - # If :halts_on_falsey is enabled: - # - # class Person - # define_hook :before_eating, :halts_on_falsey => true - # # ... - # end - # - # result = person.run_hook(:before_eating) - # result.chain #=> [:washed_hands] - def run(scope, *args) - inject(Results.new) do |results, callback| - executed = execute_callback(scope, callback, *args) - - return results.halted! unless continue_execution?(executed) - results << executed - end - end - - private - def execute_callback(scope, callback, *args) - if callback.kind_of?(Symbol) - scope.send(callback, *args) - else - scope.instance_exec(*args, &callback) - end - end - - def continue_execution?(result) - @options[:halts_on_falsey] ? result : true - end - - class Results < Array - # so much code for nothing... - def initialize(*) - super - @halted = false - end - - def halted! - @halted = true - self - end - - # Returns true or false based on whether all callbacks - # in the hook chain were successfully executed. - def halted? - @halted - end - - def not_halted? - not @halted - end - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb deleted file mode 100644 index 352e28d6..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/inheritable_attribute.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Hooks - module InheritableAttribute - # Creates an inheritable attribute with accessors in the singleton class. Derived classes inherit the - # attributes. This is especially helpful with arrays or hashes that are extended in the inheritance - # chain. Note that you have to initialize the inheritable attribute. - # - # Example: - # - # class Cat - # inheritable_attr :drinks - # self.drinks = ["Becks"] - # - # class Garfield < Cat - # self.drinks << "Fireman's 4" - # - # and then, later - # - # Cat.drinks #=> ["Becks"] - # Garfield.drinks #=> ["Becks", "Fireman's 4"] - def inheritable_attr(name) - instance_eval %Q{ - def #{name}=(v) - @#{name} = v - end - - def #{name} - return @#{name} unless superclass.respond_to?(:#{name}) and value = superclass.#{name} - @#{name} ||= value.clone # only do this once. - end - } - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb deleted file mode 100644 index 0f523fa4..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/instance_hooks.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Hooks - module InstanceHooks - include ClassMethods - - def run_hook(name, *args) - run_hook_for(name, self, *args) - end - - private - def _hooks - @_hooks ||= self.class._hooks.clone # TODO: generify that with representable_attrs. - end - - module ClassMethods - def define_hook_writer(name) - super - class_eval *hook_writer_args(name) - end - end - - def self.included(base) - base.extend(ClassMethods) - end - end -end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb deleted file mode 100644 index 788aaf77..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/lib/hooks/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Hooks - VERSION = "0.3.3" -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb deleted file mode 100644 index 5d539be1..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hook_test.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'test_helper' - -class HookTest < MiniTest::Spec - subject { Hooks::Hook.new({}) } - - it "exposes array behaviour for callbacks" do - subject << :play_music - subject << :drink_beer - - subject.to_a.must_equal [:play_music, :drink_beer] - end -end - -class ResultsTest < MiniTest::Spec - subject { Hooks::Hook::Results.new } - - describe "#halted?" do - it "defaults to false" do - subject.halted?.must_equal false - end - - it "responds to #halted!" do - subject.halted! - subject.halted?.must_equal true - end - - it "responds to #not_halted?" do - subject.not_halted?.must_equal true - end - end -end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb deleted file mode 100644 index 151a4b3d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/hooks_test.rb +++ /dev/null @@ -1,216 +0,0 @@ -require 'test_helper' - -class HooksTest < MiniTest::Spec - class TestClass - include Hooks - - def executed - @executed ||= []; - end - end - - - describe "::define_hook" do - let(:klass) do - Class.new(TestClass) do - define_hook :after_eight - end - end - - subject { klass.new } - - it "respond to Class.callbacks_for_hook" do - assert_equal [], klass.callbacks_for_hook(:after_eight) - klass.after_eight :dine - assert_equal [:dine], klass.callbacks_for_hook(:after_eight) - end - - it 'symbolizes strings when defining a hook' do - subject.class.define_hooks :before_one, 'after_one' - assert_equal [], klass.callbacks_for_hook(:before_one) - assert_equal [], klass.callbacks_for_hook(:after_one) - assert_equal [], klass.callbacks_for_hook('after_one') - end - - it "accept multiple hook names" do - subject.class.define_hooks :before_ten, :after_ten - assert_equal [], klass.callbacks_for_hook(:before_ten) - assert_equal [], klass.callbacks_for_hook(:after_ten) - end - - describe "creates a public writer for the hook that" do - it "accepts method names" do - klass.after_eight :dine - assert_equal [:dine], klass._hooks[:after_eight] - end - - it "accepts blocks" do - klass.after_eight do true; end - assert klass._hooks[:after_eight].first.kind_of? Proc - end - - it "be inherited" do - klass.after_eight :dine - subklass = Class.new(klass) - - assert_equal [:dine], subklass._hooks[:after_eight] - end - # TODO: check if options are not shared! - end - - describe "Hooks#run_hook" do - it "run without parameters" do - subject.instance_eval do - def a; executed << :a; nil; end - def b; executed << :b; end - - self.class.after_eight :b - self.class.after_eight :a - end - - subject.run_hook(:after_eight) - - assert_equal [:b, :a], subject.executed - end - - it "returns empty Results when no callbacks defined" do - subject.run_hook(:after_eight).must_equal Hooks::Hook::Results.new - end - - it "accept arbitrary parameters" do - subject.instance_eval do - def a(me, arg); executed << arg+1; end - end - subject.class.after_eight :a - subject.class.after_eight lambda { |me, arg| me.executed << arg-1 } - - subject.run_hook(:after_eight, subject, 1) - - assert_equal [2, 0], subject.executed - end - - it "execute block callbacks in instance context" do - subject.class.after_eight { executed << :c } - subject.run_hook(:after_eight) - assert_equal [:c], subject.executed - end - - it "returns all callbacks in order" do - subject.class.after_eight { :dinner_out } - subject.class.after_eight { :party_hard } - subject.class.after_eight { :taxi_home } - - results = subject.run_hook(:after_eight) - - assert_equal [:dinner_out, :party_hard, :taxi_home], results - assert_equal false, results.halted? - assert_equal true, results.not_halted? - end - - describe "halts_on_falsey: true" do - let(:klass) do - Class.new(TestClass) do - define_hook :after_eight, :halts_on_falsey => true - end - end - - [nil, false].each do |falsey| - it "returns successful callbacks in order (with #{falsey.inspect})" do - ordered = [] - - subject.class.after_eight { :dinner_out } - subject.class.after_eight { :party_hard; falsey } - subject.class.after_eight { :taxi_home } - - results = subject.run_hook(:after_eight) - - assert_equal [:dinner_out], results - assert_equal true, results.halted? - end - end - end - - describe "halts_on_falsey: false" do - [nil, false].each do |falsey| - it "returns all callbacks in order (with #{falsey.inspect})" do - ordered = [] - - subject.class.after_eight { :dinner_out } - subject.class.after_eight { :party_hard; falsey } - subject.class.after_eight { :taxi_home } - - results = subject.run_hook(:after_eight) - - assert_equal [:dinner_out, falsey, :taxi_home], results - assert_equal false, results.halted? - end - end - end - end - - describe "in class context" do - it "runs callback block" do - executed = [] - klass.after_eight do - executed << :klass - end - klass.run_hook(:after_eight) - - executed.must_equal([:klass]) - end - - it "runs instance methods" do - executed = [] - klass.instance_eval do - after_eight :have_dinner - - def have_dinner(executed) - executed << :have_dinner - end - end - klass.run_hook(:after_eight, executed) - - executed.must_equal([:have_dinner]) - end - end - end - - describe "Inheritance" do - let (:superclass) { - Class.new(TestClass) do - define_hook :after_eight - - after_eight :take_shower - end - } - - let (:subclass) { Class.new(superclass) do after_eight :have_dinner end } - - it "inherits callbacks from the hook" do - subclass.callbacks_for_hook(:after_eight).must_equal [:take_shower, :have_dinner] - end - - it "doesn't mix up superclass hooks" do - subclass.superclass.callbacks_for_hook(:after_eight).must_equal [:take_shower] - end - end -end - -class HookSetTest < MiniTest::Spec - subject { Hooks::HookSet.new } - - let (:first_hook) { Hooks::Hook.new(:halts_on_falsey => true) } - let (:second_hook) { Hooks::Hook.new(:halts_on_falsey => false) } - - it "responds to #clone" do - subject[:after_eight] = [first_hook] - - clone = subject.clone - - clone[:after_eight] << second_hook - - subject.must_equal(:after_eight => [first_hook]) - clone.must_equal(:after_eight => [first_hook, second_hook]) - end - # TODO: test if options get cloned. -end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb deleted file mode 100644 index 4cc14e58..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/inheritable_attribute_test.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'test_helper' - -class HooksTest < MiniTest::Spec - describe "Hooks.define_hook" do - subject { - Class.new(Object) do - extend Hooks::InheritableAttribute - inheritable_attr :drinks - end - } - - it "provides a reader with empty inherited attributes, already" do - assert_equal nil, subject.drinks - end - - it "provides a reader with empty inherited attributes in a derived class" do - assert_equal nil, Class.new(subject).drinks - #subject.drinks = true - #Class.new(subject).drinks # TODO: crashes. - end - - it "provides an attribute copy in subclasses" do - subject.drinks = [] - assert subject.drinks.object_id != Class.new(subject).drinks.object_id - end - - it "provides a writer" do - subject.drinks = [:cabernet] - assert_equal [:cabernet], subject.drinks - end - - it "inherits attributes" do - subject.drinks = [:cabernet] - - subklass_a = Class.new(subject) - subklass_a.drinks << :becks - - subklass_b = Class.new(subject) - - assert_equal [:cabernet], subject.drinks - assert_equal [:cabernet, :becks], subklass_a.drinks - assert_equal [:cabernet], subklass_b.drinks - end - - it "does not inherit attributes if we set explicitely" do - subject.drinks = [:cabernet] - subklass = Class.new(subject) - - subklass.drinks = [:merlot] # we only want merlot explicitely. - assert_equal [:merlot], subklass.drinks # no :cabernet, here - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb deleted file mode 100644 index ffac3fb5..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/instance_hooks_test.rb +++ /dev/null @@ -1,55 +0,0 @@ -require "test_helper" - -class InstanceHooksTest < HooksTest - describe "#define_hook" do - let(:klass) { Class.new(TestClass) do - include Hooks::InstanceHooks - end } - - subject { klass.new.tap do |obj| - obj.instance_eval do - def dine; executed << :dine; end - end - end } - - it "adds hook to instance" do - subject.define_hook :after_eight - - assert_equal [], subject.callbacks_for_hook(:after_eight) - end - - it "copies existing class hook" do - klass.define_hook :after_eight - klass.after_eight :dine - - assert_equal [:dine], subject.callbacks_for_hook(:after_eight) - end - - describe "#after_eight (adding callbacks)" do - before do - subject.define_hook :after_eight - subject.after_eight :dine - end - - it "adds #after_eight hook" do - assert_equal [:dine], subject.callbacks_for_hook(:after_eight) - end - - it "responds to #run_hook" do - subject.run_hook :after_eight - subject.executed.must_equal [:dine] - end - end - - describe "#after_eight from class (no define_hook in instance)" do - it "responds to #after_eight" do - klass.define_hook :after_eight - - subject.after_eight :dine - - subject.run_hook :after_eight - subject.executed.must_equal [:dine] - end - end - end -end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb deleted file mode 100644 index 2ece0d0e..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.3.3/test/test_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'minitest/autorun' -require 'pry' -require 'hooks' diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 954a2325..1d98baa6 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |s| s.add_dependency("bundler", ["~> 1.1"]) s.add_dependency("rack", [">= 1.4.5"]) s.add_dependency("tilt", ["~> 1.4.1"]) + s.add_dependency("hooks", ["~> 0.3"]) # Builder s.add_dependency("rack-test", ["~> 0.6.1"])