Commit 71015018b67f3a77c8876cace01c60fb581d81f0
1 parent
1f128345
Exists in
master
and in
29 other branches
r222@sede: terceiro | 2007-07-28 15:54:13 -0300
ActionItem0: implementing a better interface for the old flexible_template git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@226 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
15 changed files
with
318 additions
and
0 deletions
Show diff stats
... | ... | @@ -0,0 +1,22 @@ |
1 | +require 'rake' | |
2 | +require 'rake/testtask' | |
3 | +require 'rake/rdoctask' | |
4 | + | |
5 | +desc 'Default: run unit tests.' | |
6 | +task :default => :test | |
7 | + | |
8 | +desc 'Test the design plugin.' | |
9 | +Rake::TestTask.new(:test) do |t| | |
10 | + t.libs << 'lib' | |
11 | + t.pattern = 'test/**/*_test.rb' | |
12 | + t.verbose = true | |
13 | +end | |
14 | + | |
15 | +desc 'Generate documentation for the design plugin.' | |
16 | +Rake::RDocTask.new(:rdoc) do |rdoc| | |
17 | + rdoc.rdoc_dir = 'rdoc' | |
18 | + rdoc.title = 'Design' | |
19 | + rdoc.options << '--line-numbers' << '--inline-source' | |
20 | + rdoc.rdoc_files.include('README') | |
21 | + rdoc.rdoc_files.include('lib/**/*.rb') | |
22 | +end | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +require 'design' | |
2 | + | |
3 | +class ActionController::Base | |
4 | + | |
5 | + # Declares that this controller uses design plugin to generate its layout. | |
6 | + # See the plugin README for options that can be passed to this method. | |
7 | + def self.design(config = {}) | |
8 | + if (config.has_key?(:holder) && config.has_key?(:fixed)) || (!config.has_key?(:holder) && !config.has_key?(:fixed)) | |
9 | + raise ArgumentError.new("You must supply either <tt>:holder</tt> or <tt>:fixed</tt> to design.") | |
10 | + end | |
11 | + | |
12 | + @design_plugin_config = config | |
13 | + | |
14 | + include Design | |
15 | + end | |
16 | + | |
17 | + # declares this controller as a design editor, including in it all the | |
18 | + # functionalities to do that (besides those for using a design). Accepts the | |
19 | + # same options as design. | |
20 | + def self.design_editor(config = {}) | |
21 | + self.design(config) | |
22 | + include Design::Editor | |
23 | + end | |
24 | + | |
25 | +end | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +# Install hook code here | ... | ... |
... | ... | @@ -0,0 +1,29 @@ |
1 | +require 'design/fixed_design_holder' | |
2 | +require 'design/proxy_design_holder' | |
3 | + | |
4 | +require 'design/helper' | |
5 | +require 'design/editor' | |
6 | + | |
7 | +module Design | |
8 | + | |
9 | + # gets the Design object for this controller | |
10 | + def design | |
11 | + @design_plugin_data ||= Hash.new | |
12 | + data = @design_plugin_data | |
13 | + | |
14 | + return data[:design] if data.has_key?(:design) | |
15 | + | |
16 | + config = self.class.instance_variable_get("@design_plugin_config") | |
17 | + | |
18 | + if config.has_key?(:holder) | |
19 | + holder_variable_name = config[:holder] | |
20 | + data[:design] = Design::ProxyDesignHolder.new(self.instance_variable_get("@#{holder_variable_name}")) | |
21 | + else | |
22 | + options = (config[:fixed].kind_of? Hash) ? config[:fixed] : {} | |
23 | + data[:design] = Design::FixedDesignHolder.new(options) | |
24 | + end | |
25 | + | |
26 | + data[:design] # redundant, but makes more clear the return value | |
27 | + end | |
28 | + protected :design | |
29 | +end | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +module Design | |
2 | + | |
3 | + class FixedDesignHolder | |
4 | + attr_reader :template, :theme, :icon_theme, :boxes | |
5 | + def initialize(options = {}) | |
6 | + @template = options[:template] || 'default' | |
7 | + @theme = options[:theme] || 'default' | |
8 | + @icon_theme = options[:icon_theme] || 'default' | |
9 | + @boxes = options[:boxes] || default_boxes | |
10 | + end | |
11 | + | |
12 | + # creates some default boxes | |
13 | + def default_boxes | |
14 | + box1 = Box.new | |
15 | + box2 = Box.new | |
16 | + box2.blocks << MainBlock.new | |
17 | + box3 = Box.new | |
18 | + | |
19 | + [box1, box2, box3] | |
20 | + end | |
21 | + private :default_boxes | |
22 | + end | |
23 | + | |
24 | +end | |
25 | + | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module Design | |
2 | + | |
3 | + # This class uses an external holder object to hold the details of the | |
4 | + # design, and proxies all access to the template data to it. This object can | |
5 | + # be any object that responds to the following methods: | |
6 | + # | |
7 | + # * +template+ | |
8 | + # * +template=+ | |
9 | + # * +theme+ | |
10 | + # * +theme=+ | |
11 | + # * +icon_theme+ | |
12 | + # * +icon_theme=+ | |
13 | + # * +boxes+ | |
14 | + # * +boxes=+ | |
15 | + # | |
16 | + # These methods must implement get/set semantics for atrributes with their | |
17 | + # names, and can be implemented with +attr_accessor+, as ActiveRecord | |
18 | + # columns, or event explicity by writing the methods and storing the values | |
19 | + # wherever you want. | |
20 | + # | |
21 | + # +template+, +theme+ and +icon_theme+ must return (and accept in the | |
22 | + # setters) strings, while +boxes+ must be an array of Box objects. | |
23 | + class ProxyDesignHolder | |
24 | + | |
25 | + attr_reader :holder | |
26 | + | |
27 | + # creates a new proxy for +holder+ | |
28 | + def initialize(holder) | |
29 | + @holder = holder | |
30 | + end | |
31 | + | |
32 | + # proxies all calls to +template+, +theme+, +icon_theme+ and +boxes+ (as | |
33 | + # well as their setters counterparts) to the holder object | |
34 | + def method_missing(method_id, *args) | |
35 | + if method_id.to_s =~ /^(template|theme|icon_theme|boxes)=?$/ | |
36 | + holder.send(method_id, *args) | |
37 | + else | |
38 | + raise NoMethodError.new("Design has no method \"#{method_id}\"") | |
39 | + end | |
40 | + end | |
41 | + end | |
42 | + | |
43 | +end | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +require File.join(File.dirname(__FILE__), 'test_helper') | |
2 | + | |
3 | +class FixedDesignHolderTest < Test::Unit::TestCase | |
4 | + | |
5 | + def test_design_should_include_design_module | |
6 | + assert FixedDesignTestController.included_modules.include?(Design) | |
7 | + end | |
8 | + | |
9 | + def test_design_editor_should_include_design_and_design_editor_module | |
10 | + assert DesignEditorTestController.included_modules.include?(Design) | |
11 | + assert DesignEditorTestController.included_modules.include?(Design::Editor) | |
12 | + end | |
13 | + | |
14 | + def test_should_not_accept_no_holder_and_no_fixed | |
15 | + assert_raise ArgumentError do | |
16 | + DesignEditorTestController.design | |
17 | + end | |
18 | + end | |
19 | + def test_should_not_accept_both_holder_and_fixed | |
20 | + assert_raise ArgumentError do | |
21 | + DesignEditorTestController.design :holder => 'something', :fixed => true end | |
22 | + end | |
23 | + | |
24 | +end | ... | ... |
... | ... | @@ -0,0 +1,53 @@ |
1 | +require File.join(File.dirname(__FILE__), 'test_helper') | |
2 | + | |
3 | +class FixedDesignHolderTest < Test::Unit::TestCase | |
4 | + | |
5 | + include Design | |
6 | + | |
7 | + def test_explicit_design | |
8 | + controller = FixedDesignTestController.new | |
9 | + assert_kind_of Design::FixedDesignHolder, controller.design | |
10 | + assert_equal 'some_template', controller.design.template | |
11 | + assert_equal 'some_theme', controller.design.theme | |
12 | + assert_equal 'some_icon_theme', controller.design.icon_theme | |
13 | + assert_equal [FixedDesignTestController::BOX1, FixedDesignTestController::BOX2, FixedDesignTestController::BOX3], controller.design.boxes | |
14 | + end | |
15 | + | |
16 | + def test_explicit_design_should_have_sensible_defaults | |
17 | + controller = FixedDesignDefaultTestController.new | |
18 | + assert_kind_of Design::FixedDesignHolder, controller.design | |
19 | + assert_equal 'default', controller.design.template | |
20 | + assert_equal 'default', controller.design.theme | |
21 | + assert_equal 'default', controller.design.icon_theme | |
22 | + assert_kind_of Array, controller.design.boxes | |
23 | + assert_equal 3, controller.design.boxes.size | |
24 | + end | |
25 | + | |
26 | + def test_should_not_be_able_to_assign_template | |
27 | + # FixedDesignHolder does not implement assigment, on purpose | |
28 | + assert_raise NoMethodError do | |
29 | + FixedDesignHolder.new.template = 'break' | |
30 | + end | |
31 | + end | |
32 | + | |
33 | + def test_should_not_be_able_to_assign_theme | |
34 | + # FixedDesignHolder does not implement assigment, on purpose | |
35 | + assert_raise NoMethodError do | |
36 | + FixedDesignHolder.new.theme = 'break' | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + def test_should_not_be_able_to_assign_icon_theme | |
41 | + assert_raise NoMethodError do | |
42 | + FixedDesignHolder.new.icon_theme = 'break' | |
43 | + end | |
44 | + end | |
45 | + | |
46 | + def test_should_not_be_able_to_assign_boxes | |
47 | + assert_raise NoMethodError do | |
48 | + FixedDesignHolder.new.boxes = [] | |
49 | + end | |
50 | + end | |
51 | + | |
52 | + | |
53 | +end | ... | ... |
... | ... | @@ -0,0 +1,32 @@ |
1 | +require File.join(File.dirname(__FILE__), 'test_helper') | |
2 | + | |
3 | + | |
4 | +class ProxyDesignHolderTest < Test::Unit::TestCase | |
5 | + | |
6 | + # FIXME: rewrite this test with mocha | |
7 | + def test_design_should_interact_with_sample_holder | |
8 | + design = Design::ProxyDesignHolder.new(SampleHolderForTestingProxyDesignHolder.new) | |
9 | + design.template = 'bli' | |
10 | + assert_equal 'bli', design.template | |
11 | + design.theme = 'bli' | |
12 | + assert_equal 'bli', design.theme | |
13 | + design.icon_theme = 'bli' | |
14 | + assert_equal 'bli', design.icon_theme | |
15 | + design.boxes = [] | |
16 | + assert_equal [], design.boxes | |
17 | + end | |
18 | + | |
19 | + def test_design_user_controller_should_get_a_proper_design | |
20 | + controller = ProxyDesignHolderTestController.new | |
21 | + design = controller.send(:design) | |
22 | + design.template = 'bli' | |
23 | + assert_equal 'bli', design.template | |
24 | + design.theme = 'bli' | |
25 | + assert_equal 'bli', design.theme | |
26 | + design.icon_theme = 'bli' | |
27 | + assert_equal 'bli', design.icon_theme | |
28 | + design.boxes = [] | |
29 | + assert_equal [], design.boxes | |
30 | + end | |
31 | + | |
32 | +end | ... | ... |
... | ... | @@ -0,0 +1,44 @@ |
1 | +ENV["RAILS_ENV"] = "test" | |
2 | +require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment") | |
3 | + | |
4 | +require 'test/unit' | |
5 | + | |
6 | +######################## | |
7 | +# test clases below here | |
8 | +######################## | |
9 | + | |
10 | +class FixedDesignTestController < ActionController::Base | |
11 | + | |
12 | + BOX1 = Box.new | |
13 | + BOX2 = Box.new | |
14 | + BOX3 = Box.new | |
15 | + | |
16 | + design :fixed => { | |
17 | + :template => 'some_template', | |
18 | + :theme => 'some_theme', | |
19 | + :icon_theme => 'some_icon_theme', | |
20 | + :boxes => [ BOX1, BOX2, BOX3 ], | |
21 | + } | |
22 | +end | |
23 | + | |
24 | +class FixedDesignDefaultTestController < ActionController::Base | |
25 | + design :fixed => true | |
26 | +end | |
27 | + | |
28 | +class SampleHolderForTestingProxyDesignHolder | |
29 | + attr_accessor :template, :theme, :icon_theme, :boxes | |
30 | +end | |
31 | + | |
32 | +class ProxyDesignHolderTestController < ActionController::Base | |
33 | + design :holder => 'sample_object' | |
34 | + def initialize | |
35 | + @sample_object = SampleHolderForTestingProxyDesignHolder.new | |
36 | + end | |
37 | +end | |
38 | + | |
39 | +class DesignEditorTestController < ActionController::Base | |
40 | + design_editor :holder => 'sample_object' | |
41 | + def initialize | |
42 | + @sample_object = SampleHolderForTestingProxyDesignHolder.new | |
43 | + end | |
44 | +end | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +# Uninstall hook code here | ... | ... |