Commit 07caf3d4b2431f2858c250972537a612650ac23d

Authored by Rodrigo Souto
1 parent f65bac2a

[macro-support-review] Refactoring macros infra-structure

app/helpers/application_helper.rb
@@ -1413,29 +1413,17 @@ module ApplicationHelper @@ -1413,29 +1413,17 @@ module ApplicationHelper
1413 1413
1414 def convert_macro(html, source) 1414 def convert_macro(html, source)
1415 doc = Hpricot(html) 1415 doc = Hpricot(html)
1416 - while element = doc.search('.macro').first  
1417 - macro_name = element['data-macro']  
1418 - method_name = "macro_#{macro_name}"  
1419 - attrs = collect_macro_attributes(element)  
1420 - plugin_instance = Environment.macros[environment.id][method_name]  
1421 - if plugin_instance  
1422 - result = plugin_instance.send(method_name, attrs, element.inner_html, source)  
1423 - element.inner_html = result.kind_of?(Proc) ? self.instance_eval(&result) : result  
1424 - element['class'] = "parsed-macro #{macro_name}"  
1425 - else  
1426 - element.inner_html = _("Unsupported macro %s!") % macro_name  
1427 - element['class'] = "failed-macro #{macro_name}"  
1428 - end  
1429 - attrs.each {|key, value| element.remove_attribute("data-macro-#{key}")} 1416 + #TODO This way is more efficient but do not support macro inside of
  1417 + # macro. You must parse them from the inside-out in order to enable
  1418 + # that.
  1419 + doc.search('.macro').each do |macro|
  1420 + macro_name = macro['data-macro']
  1421 + result = @plugins.parse_macro(macro_name, macro, source)
  1422 + macro.inner_html = result.kind_of?(Proc) ? self.instance_eval(&result) : result
1430 end 1423 end
1431 doc.html 1424 doc.html
1432 end 1425 end
1433 1426
1434 - def collect_macro_attributes(element)  
1435 - element.attributes.to_hash.select {|key, value| key[0..10] == 'data-macro-'}.  
1436 - inject({}){|result, a| result.merge({a[0][11..-1] => a[1]})}.with_indifferent_access  
1437 - end  
1438 -  
1439 def default_folder_for_image_upload(profile) 1427 def default_folder_for_image_upload(profile)
1440 default_folder = profile.folders.find_by_type('Gallery') 1428 default_folder = profile.folders.find_by_type('Gallery')
1441 default_folder = profile.folders.find_by_type('Folder') if default_folder.nil? 1429 default_folder = profile.folders.find_by_type('Folder') if default_folder.nil?
app/helpers/macros_helper.rb
1 module MacrosHelper 1 module MacrosHelper
2 2
3 def macros_in_menu 3 def macros_in_menu
4 - Environment.macros[@environment.id].reject{ |macro_name, plugin_instance| macro_configuration(macro_name)[:icon_path] } 4 + @plugins.dispatch(:macros).reject{ |macro| macro.configuration[:icon_path] }
5 end 5 end
6 6
7 def macros_with_buttons 7 def macros_with_buttons
8 - Environment.macros[@environment.id].reject{ |macro_name, plugin_instance| !macro_configuration(macro_name)[:icon_path] }  
9 - end 8 + @plugins.dispatch(:macros).reject{ |macro| !macro.configuration[:icon_path] }
10 9
11 - def macro_configuration(macro_name)  
12 - plugin_instance = Environment.macros[@environment.id][macro_name]  
13 - plugin_instance.send("config_#{macro_name}")  
14 end 10 end
15 11
16 - def macro_title(macro_name)  
17 - macro_configuration(macro_name)[:title] || macro_name.to_s.humanize 12 + def macro_title(macro)
  13 + macro.configuration[:title] || macro.name.humanize
18 end 14 end
19 15
20 - def generate_macro_config_dialog(macro_name)  
21 - if macro_configuration(macro_name)[:skip_dialog]  
22 - "function(){#{macro_generator(macro_name)}}" 16 + def generate_macro_config_dialog(macro)
  17 + if macro.configuration[:skip_dialog]
  18 + "function(){#{macro_generator(macro)}}"
23 else 19 else
24 "function(){ 20 "function(){
25 - jQuery('<div>'+#{macro_configuration_dialog(macro_name).to_json}+'</div>').dialog({  
26 - title: #{macro_title(macro_name).to_json}, 21 + jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({
  22 + title: #{macro_title(macro).to_json},
27 modal: true, 23 modal: true,
28 buttons: [ 24 buttons: [
29 {text: #{_('Ok').to_json}, click: function(){ 25 {text: #{_('Ok').to_json}, click: function(){
30 tinyMCE.activeEditor.execCommand('mceInsertContent', false, 26 tinyMCE.activeEditor.execCommand('mceInsertContent', false,
31 - (function(dialog){ #{macro_generator(macro_name)} })(this)); 27 + (function(dialog){ #{macro_generator(macro)} })(this));
32 jQuery(this).dialog('close'); 28 jQuery(this).dialog('close');
33 }}, 29 }},
34 {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}} 30 {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}}
@@ -40,9 +36,9 @@ module MacrosHelper @@ -40,9 +36,9 @@ module MacrosHelper
40 36
41 def include_macro_js_files 37 def include_macro_js_files
42 plugins_javascripts = [] 38 plugins_javascripts = []
43 - Environment.macros[environment.id].map do |macro_name, plugin_instance|  
44 - if macro_configuration(macro_name)[:js_files]  
45 - macro_configuration(macro_name)[:js_files].map { |js| plugins_javascripts << plugin_instance.class.public_path(js) } 39 + @plugins.dispatch(:macros).map do |macro|
  40 + if macro.configuration[:js_files]
  41 + macro.configuration[:js_files].map { |js| plugins_javascripts << macro.plugin.public_path(js) }
46 end 42 end
47 end 43 end
48 javascript_include_tag(plugins_javascripts, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_javascripts.to_s)) unless plugins_javascripts.empty? 44 javascript_include_tag(plugins_javascripts, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_javascripts.to_s)) unless plugins_javascripts.empty?
@@ -50,9 +46,9 @@ module MacrosHelper @@ -50,9 +46,9 @@ module MacrosHelper
50 46
51 def macro_css_files 47 def macro_css_files
52 plugins_css = [] 48 plugins_css = []
53 - Environment.macros[environment.id].map do |macro_name, plugin_instance|  
54 - if macro_configuration(macro_name)[:css_files]  
55 - macro_configuration(macro_name)[:css_files].map { |css| plugins_css << plugin_instance.class.public_path(css) } 49 + @plugins.dispatch(:macros).map do |macro|
  50 + if macro.configuration[:css_files]
  51 + macro.configuration[:css_files].map { |css| plugins_css << macro.plugin.public_path(css) }
56 end 52 end
57 end 53 end
58 plugins_css.join(',') 54 plugins_css.join(',')
@@ -60,29 +56,31 @@ module MacrosHelper @@ -60,29 +56,31 @@ module MacrosHelper
60 56
61 protected 57 protected
62 58
63 - def macro_generator(macro_name)  
64 - if macro_configuration(macro_name)[:generator]  
65 - macro_configuration(macro_name)[:generator] 59 + def macro_generator(macro)
  60 + if macro.configuration[:generator]
  61 + macro.configuration[:generator]
66 else 62 else
67 - macro_default_generator(macro_name) 63 + macro_default_generator(macro)
68 end 64 end
  65 +
69 end 66 end
70 -  
71 - def macro_default_generator(macro_name) 67 +
  68 + def macro_default_generator(macro)
72 code = "var params = {};" 69 code = "var params = {};"
73 - configuration = macro_configuration(macro_name) 70 + macro_name = macro.name.undescore
  71 + configuration = macro_configuration(macro)
74 configuration[:params].map do |field| 72 configuration[:params].map do |field|
75 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" 73 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();"
76 end 74 end
77 code + " 75 code + "
78 - var html = jQuery('<div class=\"macro mceNonEditable\" data-macro=\"#{macro_name[6..-1]}\">'+#{macro_title(macro_name).to_json}+'</div>')[0]; 76 + var html = jQuery('<div class=\"macro mceNonEditable\" data-macro=\"#{macro_name}\">'+#{macro_title(macro).to_json}+'</div>')[0];
79 for(key in params) html.setAttribute('data-macro-'+key,params[key]); 77 for(key in params) html.setAttribute('data-macro-'+key,params[key]);
80 return html.outerHTML; 78 return html.outerHTML;
81 " 79 "
82 end 80 end
83 81
84 - def macro_configuration_dialog(macro_name)  
85 - macro_configuration(macro_name)[:params].map do |field| 82 + def macro_configuration_dialog(macro)
  83 + macro.configuration[:params].map do |field|
86 label_name = field[:label] || field[:name].to_s.humanize 84 label_name = field[:label] || field[:name].to_s.humanize
87 case field[:type] 85 case field[:type]
88 when 'text' 86 when 'text'
app/models/environment.rb
@@ -16,10 +16,6 @@ class Environment &lt; ActiveRecord::Base @@ -16,10 +16,6 @@ class Environment &lt; ActiveRecord::Base
16 filename 16 filename
17 end 17 end
18 18
19 - class << self  
20 - attr_accessor :macros  
21 - end  
22 -  
23 PERMISSIONS['Environment'] = { 19 PERMISSIONS['Environment'] = {
24 'view_environment_admin_panel' => N_('View environment admin panel'), 20 'view_environment_admin_panel' => N_('View environment admin panel'),
25 'edit_environment_features' => N_('Edit environment features'), 21 'edit_environment_features' => N_('Edit environment features'),
app/views/shared/tiny_mce.rhtml
@@ -11,8 +11,8 @@ @@ -11,8 +11,8 @@
11 <% else %> 11 <% else %>
12 first_line = "print,separator,copy,paste,separator,undo,redo,separator,search,replace,separator,forecolor,fontsizeselect,formatselect" 12 first_line = "print,separator,copy,paste,separator,undo,redo,separator,search,replace,separator,forecolor,fontsizeselect,formatselect"
13 second_line = "bold,italic,underline,strikethrough,separator,bullist,numlist,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,link,unlink,image,table,separator,cleanup,code,macros" 13 second_line = "bold,italic,underline,strikethrough,separator,bullist,numlist,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,link,unlink,image,table,separator,cleanup,code,macros"
14 - <% macros_with_buttons.each do |macro_name, plugin_instance| %>  
15 - second_line += ',<%=macro_name %>' 14 + <% macros_with_buttons.each do |macro| %>
  15 + second_line += ',<%=macro.name.underscore %>'
16 <% end %> 16 <% end %>
17 <% end %> 17 <% end %>
18 18
@@ -32,11 +32,11 @@ tinymce.create(&#39;tinymce.plugins.MacrosPlugin&#39;, { @@ -32,11 +32,11 @@ tinymce.create(&#39;tinymce.plugins.MacrosPlugin&#39;, {
32 icons : false 32 icons : false
33 }); 33 });
34 34
35 - <% macros_in_menu.each do |macro_name, plugin_instance| %> 35 + <% macros_in_menu.each do |macro| %>
36 c.onRenderMenu.add(function(c, m) { 36 c.onRenderMenu.add(function(c, m) {
37 m.add({ 37 m.add({
38 - title: <%= macro_title(macro_name).to_json %>,  
39 - onclick: <%= generate_macro_config_dialog(macro_name) %> 38 + title: <%= macro_title(macro).to_json %>,
  39 + onclick: <%= generate_macro_config_dialog(macro) %>
40 }); 40 });
41 }); 41 });
42 <% end %> 42 <% end %>
@@ -75,11 +75,11 @@ tinyMCE.init({ @@ -75,11 +75,11 @@ tinyMCE.init({
75 language: <%= tinymce_language.inspect %>, 75 language: <%= tinymce_language.inspect %>,
76 entity_encoding: 'raw', 76 entity_encoding: 'raw',
77 setup : function(ed) { 77 setup : function(ed) {
78 - <% macros_with_buttons.each do |macro_name, plugin_instance| %>  
79 - ed.addButton('<%= macro_name %>', {  
80 - title: <%= macro_title(macro_name).to_json %>,  
81 - onclick: <%= generate_macro_config_dialog(macro_name) %>,  
82 - image : '<%= macro_configuration(macro_name)[:icon_path]%>' 78 + <% macros_with_buttons.each do |macro| %>
  79 + ed.addButton('<%= macro.name.underscore %>', {
  80 + title: <%= macro_title(macro).to_json %>,
  81 + onclick: <%= generate_macro_config_dialog(macro) %>,
  82 + image : '<%= macro.configuration[:icon_path]%>'
83 }); 83 });
84 <% end %> 84 <% end %>
85 } 85 }
lib/noosfero/plugin.rb
@@ -7,9 +7,6 @@ class Noosfero::Plugin @@ -7,9 +7,6 @@ class Noosfero::Plugin
7 7
8 def initialize(context=nil) 8 def initialize(context=nil)
9 self.context = context 9 self.context = context
10 - macro_methods.each do |method|  
11 - Environment.macros[context.environment.id][method] = self unless context.nil?  
12 - end  
13 end 10 end
14 11
15 class << self 12 class << self
@@ -147,6 +144,12 @@ class Noosfero::Plugin @@ -147,6 +144,12 @@ class Noosfero::Plugin
147 blocks || [] 144 blocks || []
148 end 145 end
149 146
  147 + def macros
  148 + self.class.constants.map do |constant_name|
  149 + self.class.const_get(constant_name)
  150 + end.select {|klass| klass <= Noosfero::Plugin::Macro}
  151 + end
  152 +
150 # Here the developer may specify the events to which the plugins can 153 # Here the developer may specify the events to which the plugins can
151 # register and must return true or false. The default value must be false. 154 # register and must return true or false. The default value must be false.
152 155
@@ -443,12 +446,6 @@ class Noosfero::Plugin @@ -443,12 +446,6 @@ class Noosfero::Plugin
443 nil 446 nil
444 end 447 end
445 448
446 - # -> Register macro methods in environment  
447 - # returns = ['method1', 'method2', ...]  
448 - def macro_methods  
449 - []  
450 - end  
451 -  
452 # -> Finds objects by their contents 449 # -> Finds objects by their contents
453 # returns = {:results => [a, b, c, ...], ...} 450 # returns = {:results => [a, b, c, ...], ...}
454 # P.S.: The plugin might add other informations on the return hash for its 451 # P.S.: The plugin might add other informations on the return hash for its
lib/noosfero/plugin/macro.rb 0 → 100644
@@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
  1 +class Noosfero::Plugin::Macro
  2 +
  3 + attr_accessor :context
  4 +
  5 + def self.configuration
  6 +# {:generator => ''}
  7 + end
  8 +
  9 + def self.plugin
  10 + name.split('::')[0...-1].join('::').constantize
  11 + end
  12 +
  13 + def initialize(context=nil)
  14 + self.context = context
  15 + end
  16 +
  17 + def attributes(macro)
  18 + macro.attributes.to_hash.
  19 + select {|key, value| key[0..10] == 'data-macro-'}.
  20 + inject({}){|result, a| result.merge({a[0][11..-1] => a[1]})}.
  21 + with_indifferent_access
  22 + end
  23 +
  24 + def convert(macro, source)
  25 + macro_name = macro['data-macro']
  26 + attrs = attributes(macro)
  27 +
  28 + begin
  29 + content = parse(attrs, macro.inner_html, source)
  30 + macro['class'] = "parsed-macro #{macro_name}"
  31 + rescue Exception => exception
  32 + content = _("Unsupported macro %s!") % macro_name
  33 + macro['class'] = "failed-macro #{macro_name}"
  34 + end
  35 +
  36 + attrs.each {|key, value| macro.remove_attribute("data-macro-#{key}")}
  37 + content
  38 + end
  39 +
  40 + def parse(attrs, inner_html, source)
  41 + raise
  42 + end
  43 +
  44 +end
lib/noosfero/plugin/manager.rb
@@ -6,7 +6,6 @@ class Noosfero::Plugin::Manager @@ -6,7 +6,6 @@ class Noosfero::Plugin::Manager
6 def initialize(environment, context) 6 def initialize(environment, context)
7 @environment = environment 7 @environment = environment
8 @context = context 8 @context = context
9 - Environment.macros = {environment.id => {}} unless environment.nil?  
10 end 9 end
11 10
12 delegate :each, :to => :enabled_plugins 11 delegate :each, :to => :enabled_plugins
@@ -54,12 +53,23 @@ class Noosfero::Plugin::Manager @@ -54,12 +53,23 @@ class Noosfero::Plugin::Manager
54 result 53 result
55 end 54 end
56 55
  56 + def parse_macro(macro_name, macro, source = nil)
  57 + macro_instance = enabled_macros[macro_name] || enabled_macros['default']
  58 + macro_instance.convert(macro, source)
  59 + end
  60 +
57 def enabled_plugins 61 def enabled_plugins
58 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| 62 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin|
59 plugin.constantize.new(context) 63 plugin.constantize.new(context)
60 end 64 end
61 end 65 end
62 66
  67 + def enabled_macros
  68 + @enabled_macros ||= dispatch(:macros).inject({}) do |memo, macro|
  69 + memo.merge!(macro.name.underscore => macro.new(context))
  70 + end.merge('default' => Noosfero::Plugin::Macro.new(context))
  71 + end
  72 +
63 def [](name) 73 def [](name)
64 klass = Noosfero::Plugin.klass(name) 74 klass = Noosfero::Plugin.klass(name)
65 enabled_plugins.select do |plugin| 75 enabled_plugins.select do |plugin|
test/unit/application_helper_test.rb
@@ -661,35 +661,38 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -661,35 +661,38 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
661 661
662 should 'parse macros' do 662 should 'parse macros' do
663 class Plugin1 < Noosfero::Plugin 663 class Plugin1 < Noosfero::Plugin
664 - def macro_test1(params, inner_html, source) 664 + end
  665 +
  666 + class Plugin1::Macro1 < Noosfero::Plugin::Macro
  667 + def parse(params, inner_html, source)
665 'Test1' 668 'Test1'
666 end 669 end
667 - def macro_test2(params, inner_html, source)  
668 - 'Test2'  
669 - end 670 + end
670 671
671 - def macro_methods  
672 - ['macro_test1', 'macro_test2'] 672 + class Plugin1::Macro2 < Noosfero::Plugin::Macro
  673 + def parse(params, inner_html, source)
  674 + 'Test2'
673 end 675 end
674 end 676 end
675 677
676 - @environment = Environment.default  
677 - Environment.macros = {@environment.id => {}}  
678 - context = mock()  
679 - context.stubs(:environment).returns(@environment)  
680 - Plugin1.new(context)  
681 - html = '  
682 - <div class="macro nonEdit" data-macro="test1" data-macro-param="123"></div>  
683 - <div class="macro nonEdit" data-macro="test2"></div>  
684 - <div class="macro nonEdit" data-macro="unexistent" data-macro-param="987"></div>  
685 - ' 678 + environment = Environment.default
  679 + environment.enable_plugin(Plugin1)
  680 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  681 + macro1_name = Plugin1::Macro1.name.underscore
  682 + macro2_name = Plugin1::Macro2.name.underscore
  683 +
  684 + html = "
  685 + <div class='macro nonEdit' data-macro='#{macro1_name}' data-macro-param='123'></div>
  686 + <div class='macro nonEdit' data-macro='#{macro2_name}'></div>
  687 + <div class='macro nonEdit' data-macro='unexistent' data-macro-param='987'></div>
  688 + "
686 parsed_html = convert_macro(html, mock()) 689 parsed_html = convert_macro(html, mock())
687 parsed_divs = Hpricot(parsed_html).search('div') 690 parsed_divs = Hpricot(parsed_html).search('div')
688 - expected_divs = Hpricot('  
689 - <div data-macro="test1" class="parsed-macro test1">Test1</div>  
690 - <div data-macro="test2" class="parsed-macro test2">Test2</div>  
691 - <div data-macro="unexistent" class="failed-macro unexistent">Unsupported macro unexistent!</div>  
692 - ').search('div') 691 + expected_divs = Hpricot("
  692 + <div data-macro='#{macro1_name}' class='parsed-macro #{macro1_name}'>Test1</div>
  693 + <div data-macro='#{macro2_name}' class='parsed-macro #{macro2_name}'>Test2</div>
  694 + <div data-macro='unexistent' class='failed-macro unexistent'>Unsupported macro unexistent!</div>
  695 + ").search('div')
693 696
694 # comparing div attributes between parsed and expected html 697 # comparing div attributes between parsed and expected html
695 parsed_divs.each_with_index do |div, i| 698 parsed_divs.each_with_index do |div, i|
test/unit/macros_helper_test.rb
@@ -24,14 +24,25 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -24,14 +24,25 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
24 :title => _('Profile Image Link') 24 :title => _('Profile Image Link')
25 } 25 }
26 26
27 - should 'generate html for macro configuration' do 27 + class Plugin1 < Noosfero::Plugin
  28 + end
  29 +
  30 + def setup
28 @environment = Environment.default 31 @environment = Environment.default
29 - Environment.macros = {}  
30 - macros = Environment.macros[@environment.id] = {}  
31 - plugin_instance = mock  
32 - plugin_instance.stubs('config_macro_example').returns(CONFIG)  
33 - macros['macro_example'] = plugin_instance  
34 - html = macro_configuration_dialog('macro_example') 32 + @environment.enable_plugin(Plugin1)
  33 + @plugins = Noosfero::Plugin::Manager.new(@environment, self)
  34 + end
  35 +
  36 + attr_accessor :environment
  37 +
  38 + should 'generate html for macro configuration' do
  39 + class Plugin1::Macro < Noosfero::Plugin::Macro
  40 + def self.configuration
  41 + CONFIG
  42 + end
  43 + end
  44 +
  45 + html = macro_configuration_dialog(Plugin1::Macro)
35 assert_tag_in_string html, :tag => 'label', :content => _('Identifier') 46 assert_tag_in_string html, :tag => 'label', :content => _('Identifier')
36 assert_tag_in_string html, :tag => 'input', :attributes => {:name => 'identifier'} 47 assert_tag_in_string html, :tag => 'input', :attributes => {:name => 'identifier'}
37 assert_tag_in_string html, :tag => 'label', :content => 'size'.humanize 48 assert_tag_in_string html, :tag => 'label', :content => 'size'.humanize
@@ -43,82 +54,79 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -43,82 +54,79 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
43 end 54 end
44 55
45 should 'get macro title' do 56 should 'get macro title' do
46 - @environment = Environment.default  
47 - Environment.macros = {}  
48 - macros = Environment.macros[@environment.id] = {}  
49 - plugin_instance = mock  
50 - plugin_instance.stubs('config_macro_example').returns(CONFIG)  
51 - macros['macro_example'] = plugin_instance  
52 - title = macro_title('macro_example') 57 + class Plugin1::Macro < Noosfero::Plugin::Macro
  58 + def self.configuration
  59 + CONFIG
  60 + end
  61 + end
  62 + title = macro_title(Plugin1::Macro)
53 assert _('Profile Image Link'), title 63 assert _('Profile Image Link'), title
54 end 64 end
55 65
  66 + class Plugin1::Macro1 < Noosfero::Plugin::Macro
  67 + def self.configuration
  68 + {}
  69 + end
  70 + end
  71 +
  72 + class Plugin1::Macro2 < Noosfero::Plugin::Macro
  73 + def self.configuration
  74 + {:icon_path => 'icon.png'}
  75 + end
  76 + end
  77 +
56 should 'get only macros in menu' do 78 should 'get only macros in menu' do
57 - @environment = Environment.default  
58 - Environment.macros = {}  
59 - macros = Environment.macros[@environment.id] = {}  
60 - plugin_instance = mock  
61 - plugin_instance.stubs('config_macro_example').returns({})  
62 - macros['macro_example'] = plugin_instance  
63 - plugin_instance_other = mock  
64 - plugin_instance_other.stubs('config_macro_example_other').returns({:icon_path => 'icon.png'})  
65 - macros['macro_example_other'] = plugin_instance_other  
66 - assert_equal [plugin_instance], macros_in_menu.values 79 + assert_includes macros_in_menu, Plugin1::Macro1
  80 + assert_not_includes macros_in_menu, Plugin1::Macro2
67 end 81 end
68 82
69 should 'get only macros with buttons' do 83 should 'get only macros with buttons' do
70 - @environment = Environment.default  
71 - Environment.macros = {}  
72 - macros = Environment.macros[@environment.id] = {}  
73 - plugin_instance = mock  
74 - plugin_instance.stubs('config_macro_example').returns({})  
75 - macros['macro_example'] = plugin_instance  
76 - plugin_instance_other = mock  
77 - plugin_instance_other.stubs('config_macro_example_other').returns({:icon_path => 'icon.png'})  
78 - macros['macro_example_other'] = plugin_instance_other  
79 - assert_equal [plugin_instance_other], macros_with_buttons.values 84 + assert_includes macros_with_buttons, Plugin1::Macro2
  85 + assert_not_includes macros_with_buttons, Plugin1::Macro1
80 end 86 end
81 87
82 should 'skip macro config dialog and call generator directly' do 88 should 'skip macro config dialog and call generator directly' do
83 - @environment = Environment.default  
84 - Environment.macros = {}  
85 - macros = Environment.macros[@environment.id] = {}  
86 - plugin_instance = mock  
87 - plugin_instance.stubs('config_macro_example').returns({:skip_dialog => true, :generator => '', :params => [] })  
88 - macros['macro_example'] = plugin_instance  
89 - assert_equal 'function(){}', generate_macro_config_dialog('macro_example') 89 + class Plugin1::Macro < Noosfero::Plugin::Macro
  90 + def self.configuration
  91 + {:skip_dialog => true, :generator => '', :params => []}
  92 + end
  93 + end
  94 +
  95 + assert_equal 'function(){}', generate_macro_config_dialog(Plugin1::Macro)
90 end 96 end
91 97
92 should 'include js files' do 98 should 'include js files' do
93 - @environment = Environment.default  
94 - Environment.macros = {}  
95 - macros = Environment.macros[@environment.id] = {}  
96 - plugin_instance = mock  
97 - plugin_instance.stubs('config_macro_example').returns({:js_files => 'macro.js' })  
98 - plugin_instance.class.stubs(:public_path).with('macro.js').returns('macro.js')  
99 - macros['macro_example'] = plugin_instance  
100 - assert_equal '<script src="/javascripts/macro.js" type="text/javascript"></script>', include_macro_js_files 99 + class Plugin1::Macro < Noosfero::Plugin::Macro
  100 + def self.configuration
  101 + {:js_files => 'macro.js' }
  102 + end
  103 + end
  104 +
  105 + assert_equal "<script src=\"#{Plugin1.public_path('macro.js')}\" type=\"text/javascript\"></script>", include_macro_js_files
101 end 106 end
102 107
103 should 'get macro css files' do 108 should 'get macro css files' do
104 - @environment = Environment.default  
105 - Environment.macros = {}  
106 - macros = Environment.macros[@environment.id] = {}  
107 - plugin_instance = mock  
108 - plugin_instance.stubs('config_macro_example').returns({:css_files => 'macro.css' })  
109 - plugin_instance.class.stubs(:public_path).with('macro.css').returns('macro.css')  
110 - macros['macro_example'] = plugin_instance  
111 - assert_equal 'macro.css', macro_css_files 109 + class Plugin1::Macro < Noosfero::Plugin::Macro
  110 + def self.configuration
  111 + {:css_files => 'macro.css' }
  112 + end
  113 +
  114 + def self.public_path(file)
  115 + 'macro.css'
  116 + end
  117 + end
  118 +
  119 + assert_equal Plugin1.public_path('macro.css'), macro_css_files
112 end 120 end
113 121
114 should 'get macro specific generator' do 122 should 'get macro specific generator' do
115 - @environment = Environment.default  
116 - Environment.macros = {}  
117 - macros = Environment.macros[@environment.id] = {}  
118 - plugin_instance = mock  
119 - plugin_instance.stubs('config_macro_example').returns({:generator => 'macro_generator' })  
120 - macros['macro_example'] = plugin_instance  
121 - assert_equal 'macro_generator', macro_generator('macro_example') 123 + class Plugin1::Macro < Noosfero::Plugin::Macro
  124 + def self.configuration
  125 + {:generator => 'macro_generator' }
  126 + end
  127 + end
  128 +
  129 + assert_equal 'macro_generator', macro_generator(Plugin1::Macro)
122 end 130 end
123 131
124 end 132 end
test/unit/plugin_manager_test.rb
@@ -168,4 +168,30 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -168,4 +168,30 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
168 assert_equal Plugin2, manager.fetch_first_plugin(:random_event) 168 assert_equal Plugin2, manager.fetch_first_plugin(:random_event)
169 end 169 end
170 170
  171 + should 'parse macro' do
  172 + class Plugin1 < Noosfero::Plugin
  173 + def macros
  174 + [Macro1, Macro2]
  175 + end
  176 + end
  177 +
  178 + class Plugin1::Macro1 < Noosfero::Plugin::Macro
  179 + def convert(macro, source)
  180 + macro.gsub('%{name}', 'Macro1')
  181 + end
  182 + end
  183 +
  184 + class Plugin1::Macro2 < Noosfero::Plugin::Macro
  185 + def convert(macro, source)
  186 + macro.gsub('%{name}', 'Macro2')
  187 + end
  188 + end
  189 +
  190 + environment.enable_plugin(Plugin1)
  191 + macro = 'My name is %{name}!'
  192 +
  193 + assert_equal 'My name is Macro1!', manager.parse_macro(Plugin1::Macro1.name.underscore, macro)
  194 + assert_equal 'My name is Macro2!', manager.parse_macro(Plugin1::Macro2.name.underscore, macro)
  195 + end
  196 +
171 end 197 end
test/unit/plugin_test.rb
@@ -28,35 +28,6 @@ class PluginTest &lt; ActiveSupport::TestCase @@ -28,35 +28,6 @@ class PluginTest &lt; ActiveSupport::TestCase
28 assert_equal({:controller => 'plugin_test/plugin1_admin', :action => 'index'}, Plugin1.admin_url) 28 assert_equal({:controller => 'plugin_test/plugin1_admin', :action => 'index'}, Plugin1.admin_url)
29 end 29 end
30 30
31 - should 'register its macros in the environment when instantiated' do  
32 - class Plugin1 < Noosfero::Plugin  
33 - def macro_example1(params, inner_html, source)  
34 - end  
35 -  
36 - def example2(params, inner_html, source)  
37 - end  
38 -  
39 - def not_macro  
40 - end  
41 -  
42 - def macro_methods  
43 - ['macro_example1', 'example2']  
44 - end  
45 - end  
46 -  
47 - Environment.macros = {}  
48 - Environment.macros[environment.id] = {}  
49 - macros = Environment.macros[environment.id]  
50 - context = mock()  
51 - context.stubs(:environment).returns(environment)  
52 -  
53 - plugin_instance = Plugin1.new(context)  
54 -  
55 - assert_equal plugin_instance, macros['macro_example1']  
56 - assert_equal plugin_instance, macros['example2']  
57 - assert_nil macros['not_macro']  
58 - end  
59 -  
60 should 'load_comments return nil by default' do 31 should 'load_comments return nil by default' do
61 32
62 class Plugin1 < Noosfero::Plugin; end; 33 class Plugin1 < Noosfero::Plugin; end;