blob: 96181acaa332450e8061fb7df425645d7c3f21b3 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with this
# work for additional information regarding copyright ownership. The ASF
# licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helpers'))
describe Extension do
before do
@saved_modules = Project.class_eval { @extension_modules }.dup
@saved_callbacks = Project.class_eval { @global_callbacks }.dup
end
after do
modules = @saved_modules
callbacks = @saved_callbacks
Project.class_eval do
@global_callbacks = callbacks
@extension_modules = modules
end
end
it 'should call Extension.first_time during include' do
TestExtension.should_receive(:first_time_called).once
class Buildr::Project
include TestExtension
end
end
it 'should call before_define and after_define in order when project is defined' do
begin
TestExtension.callback do |extension|
extension.should_receive(:before_define_called).once.ordered
extension.should_receive(:after_define_called).once.ordered
end
class Buildr::Project
include TestExtension
end
define('foo')
ensure
TestExtension.callback { |ignore| }
end
end
it 'should call before_define and after_define for each project defined' do
begin
extensions = 0
TestExtension.callback do |extension|
extensions += 1
extension.should_receive(:before_define_called).once.ordered
extension.should_receive(:after_define_called).once.ordered
end
class Buildr::Project
include TestExtension
end
define('foo')
define('bar')
extensions.should equal(2)
ensure
TestExtension.callback { |ignore| }
end
end
it 'should call before_define callbacks in dependency order' do
class Buildr::Project
include ExtensionOneTwo
include ExtensionThreeFour
end
define('foo')
project('foo').before_order.should == [ :one, :two, :three, :four ]
project('foo').after_order.should == [ :four, :three, :two, :one ]
end
it 'should call before_define callbacks when extending project' do
define('foo') do
extend ExtensionOneTwo
extend ExtensionThreeFour
end
project('foo').before_order.should == [ :two, :one, :four, :three ]
project('foo').after_order.should == [ :four, :three, :two, :one ]
end
it 'should raise error when including if callback dependencies cannot be satisfied' do
class Buildr::Project
include ExtensionOneTwo # missing ExtensionThreeFour
end
lambda { define('foo') }.should raise_error
end
it 'should raise error when extending if callback dependencies cannot be satisfied' do
lambda {
define('foo') do |project|
extend ExtensionOneTwo # missing ExtensionThreeFour
end
}.should raise_error
end
it 'should ignore dependencies when extending project' do
define('bar') do |project|
extend ExtensionThreeFour # missing ExtensionOneTwo
end
project('bar').before_order.should == [:four, :three]
project('bar').after_order.should == [:four, :three]
end
end
module TestExtension
include Extension
def initialize(*args)
super
# callback is used to obtain extension instance created by buildr
@@callback.call(self) if @@callback
end
def self.callback(&block)
@@callback = block
end
first_time do
self.first_time_called()
end
before_define do |project|
project.before_define_called()
end
after_define do |project|
project.after_define_called()
end
def self.first_time_called()
end
end
module BeforeAfter
def before_order
@before_order ||= []
end
def after_order
@after_order ||= []
end
end
module ExtensionOneTwo
include Extension, BeforeAfter
before_define(:two => :one) do |project|
project.before_order << :two
end
before_define(:one) do |project|
project.before_order << :one
end
after_define(:one => :two) do |project|
project.after_order << :one
end
after_define(:two => :three) do |project|
project.after_order << :two
end
end
module ExtensionThreeFour
include Extension, BeforeAfter
before_define(:three => :two)
before_define(:four => :three) do |project|
project.before_order << :four
end
before_define(:three) do |project|
project.before_order << :three
end
after_define(:three => :four) do |project|
project.after_order << :three
end
after_define(:four) do |project|
project.after_order << :four
end
end