maruto 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/maruto.rb +0 -4
- data/lib/maruto/magento_config.rb +0 -31
- data/lib/maruto/magento_instance.rb +8 -6
- data/lib/maruto/module_configuration.rb +105 -29
- data/lib/maruto/module_definition.rb +5 -0
- data/lib/maruto/runner.rb +43 -11
- data/lib/maruto/version.rb +1 -1
- data/spec/module_definition_spec.rb +16 -3
- data/spec/module_events_spec.rb +395 -135
- data/spec/module_version_spec.rb +16 -24
- metadata +2 -2
data/lib/maruto.rb
CHANGED
|
@@ -75,37 +75,6 @@ module Maruto
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
##########################################################################################
|
|
79
|
-
# EVENTS
|
|
80
|
-
|
|
81
|
-
# TODO same for:
|
|
82
|
-
# '/config/frontend/events/*'
|
|
83
|
-
# '/config/adminhtml/events/*'
|
|
84
|
-
doc.xpath('/config/global/events/*').each do |node|
|
|
85
|
-
# puts node
|
|
86
|
-
event = node.name
|
|
87
|
-
observers = @global_events_observers[event] ||= {}
|
|
88
|
-
|
|
89
|
-
node.xpath("observers/*").each do |observer_node|
|
|
90
|
-
observer_name = observer_node.name
|
|
91
|
-
if observers.include? observer_name
|
|
92
|
-
mod_first = observers[observer_name][:defined]
|
|
93
|
-
mod_second = mm_name
|
|
94
|
-
@warnings << "event:#{event} observer:#{observer_name} - defined in #{mod_first} and redefined in #{mod_second}"
|
|
95
|
-
# TODO check if there is a dependency path between mod_first and mod_second
|
|
96
|
-
# print_module(mod_first)
|
|
97
|
-
# print_module(mod_second)
|
|
98
|
-
end
|
|
99
|
-
observers[observer_name] = {
|
|
100
|
-
:class => observer_node.at_xpath('class').content,
|
|
101
|
-
:method => observer_node.at_xpath('method').content,
|
|
102
|
-
:defined => mm_name,
|
|
103
|
-
}
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
@global_events_observers[event] = observers
|
|
107
|
-
end
|
|
108
|
-
|
|
109
78
|
end
|
|
110
79
|
end # modules().each
|
|
111
80
|
|
|
@@ -9,10 +9,11 @@ module Maruto::MagentoInstance
|
|
|
9
9
|
sorted_modules, active_modules = Maruto::ModuleDefinition.analyse_module_definitions(all_modules)
|
|
10
10
|
|
|
11
11
|
sorted_modules.each do |m|
|
|
12
|
-
Maruto::ModuleConfiguration.
|
|
13
|
-
# ModuleConfiguration.analyse(m, active_modules)
|
|
12
|
+
Maruto::ModuleConfiguration.parse_module_configuration(m)
|
|
14
13
|
end
|
|
15
14
|
|
|
15
|
+
event_observers = Maruto::ModuleConfiguration.collect_event_observers(sorted_modules)
|
|
16
|
+
|
|
16
17
|
# TODO move to function: collect_warnings + write spec
|
|
17
18
|
warnings = []
|
|
18
19
|
all_modules.each do |m|
|
|
@@ -20,10 +21,11 @@ module Maruto::MagentoInstance
|
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
{
|
|
23
|
-
:active_modules
|
|
24
|
-
:all_modules
|
|
25
|
-
:sorted_modules
|
|
26
|
-
:
|
|
24
|
+
:active_modules => active_modules,
|
|
25
|
+
:all_modules => Hash[all_modules.collect { |m| [m[:name], m]}],
|
|
26
|
+
:sorted_modules => sorted_modules,
|
|
27
|
+
:event_observers => event_observers,
|
|
28
|
+
:warnings => warnings,
|
|
27
29
|
}
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -3,46 +3,58 @@ require 'nokogiri'
|
|
|
3
3
|
|
|
4
4
|
module Maruto::ModuleConfiguration
|
|
5
5
|
|
|
6
|
-
def self.
|
|
6
|
+
def self.parse_module_configuration(m)
|
|
7
7
|
f = File.open(m[:config_path])
|
|
8
|
-
|
|
8
|
+
xml_root = Nokogiri::XML(f) { |config| config.strict }.root
|
|
9
9
|
f.close
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
version_warnings = parse_module_version(m, xml_root)
|
|
12
|
+
event_warnings = parse_all_event_observers(m, xml_root)
|
|
13
|
+
|
|
14
|
+
config_warnings = version_warnings + event_warnings
|
|
15
|
+
|
|
16
|
+
all_module_warnings = m[:warnings] || []
|
|
17
|
+
all_module_warnings.concat(config_warnings.map { |msg| { :file => m[:config_path], :message => msg } })
|
|
18
|
+
|
|
19
|
+
m[:warnings] = all_module_warnings unless all_module_warnings.size == 0
|
|
20
|
+
|
|
21
|
+
m
|
|
12
22
|
end
|
|
13
23
|
|
|
14
|
-
def self.
|
|
24
|
+
def self.parse_module_version(m, xml_root)
|
|
15
25
|
xml_node = xml_root.at_xpath('/config/modules')
|
|
26
|
+
|
|
16
27
|
if xml_node.nil?
|
|
17
|
-
|
|
18
|
-
m[:warnings] << { :file => m[:config_path], :message => "config.xml is missing a /config/modules node" }
|
|
19
|
-
return m
|
|
28
|
+
return ["config.xml is missing a /config/modules node"]
|
|
20
29
|
end
|
|
21
30
|
|
|
31
|
+
warnings = []
|
|
32
|
+
|
|
22
33
|
unless xml_node.at_xpath("./#{m[:name]}")
|
|
23
|
-
m[:
|
|
24
|
-
m[:warnings] << { :file => m[:config_path], :message => "config.xml is missing a /config/modules/#{m[:name]} node" }
|
|
34
|
+
warnings << "config.xml is missing a /config/modules/#{m[:name]} node"
|
|
25
35
|
end
|
|
26
36
|
|
|
27
37
|
xml_node.xpath("./*").each do |n|
|
|
28
38
|
unless n.name.to_sym == m[:name]
|
|
29
|
-
|
|
30
|
-
m[:warnings] << { :file => m[:config_path], :message => "config.xml contains configuration for a different module (/config/modules/#{n.name})" }
|
|
39
|
+
warnings << "config.xml contains configuration for a different module (/config/modules/#{n.name})"
|
|
31
40
|
end
|
|
32
41
|
end
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
m[:version] = xml_node.at_xpath("./#{m[:name]}/version").content
|
|
36
|
-
end
|
|
43
|
+
m[:version] = xml_node.at_xpath("./#{m[:name]}/version").content unless xml_node.at_xpath("./#{m[:name]}/version").nil?
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
warnings
|
|
39
46
|
end
|
|
40
47
|
|
|
41
|
-
def self.
|
|
48
|
+
def self.parse_scoped_event_observers(base_path, xml_node)
|
|
49
|
+
|
|
50
|
+
return [],[] if xml_node.nil?
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
events = []
|
|
53
|
+
warnings = []
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
if xml_node.size > 1
|
|
56
|
+
warnings << "duplicate element in config.xml (#{base_path})"
|
|
57
|
+
end
|
|
46
58
|
|
|
47
59
|
xml_node.xpath('events/*').each do |e|
|
|
48
60
|
event = {
|
|
@@ -56,9 +68,25 @@ module Maruto::ModuleConfiguration
|
|
|
56
68
|
:name => o.name,
|
|
57
69
|
:path => event[:path] + '/observers/' + o.name,
|
|
58
70
|
}
|
|
59
|
-
|
|
60
|
-
observer[:class] = o.at_xpath('class').content
|
|
61
|
-
observer[:method] = o.at_xpath('method').content
|
|
71
|
+
type = o.at_xpath('type').content unless o.at_xpath('type').nil?
|
|
72
|
+
observer[:class] = o.at_xpath('class').content unless o.at_xpath('class').nil?
|
|
73
|
+
observer[:method] = o.at_xpath('method').content unless o.at_xpath('method').nil?
|
|
74
|
+
|
|
75
|
+
# see Mage_Core_Model_App::dispatchEvent
|
|
76
|
+
if type.nil?
|
|
77
|
+
# default is singleton
|
|
78
|
+
observer[:type] = :singleton
|
|
79
|
+
elsif type == 'object'
|
|
80
|
+
# object is an alias for model
|
|
81
|
+
observer[:type] = :model
|
|
82
|
+
warnings << "#{observer[:path]}/type 'object' is an alias for 'model'"
|
|
83
|
+
elsif /^(disabled|model|singleton)$/ =~ type
|
|
84
|
+
observer[:type] = type.to_sym
|
|
85
|
+
else
|
|
86
|
+
# everything else => default (with warning)
|
|
87
|
+
observer[:type] = :singleton
|
|
88
|
+
warnings << "#{observer[:path]}/type replaced with 'singleton', was '#{type}' (possible values: 'disabled', 'model', 'singleton', or nothing)"
|
|
89
|
+
end
|
|
62
90
|
|
|
63
91
|
event[:observers] << observer
|
|
64
92
|
end
|
|
@@ -66,17 +94,65 @@ module Maruto::ModuleConfiguration
|
|
|
66
94
|
events << event
|
|
67
95
|
end
|
|
68
96
|
|
|
97
|
+
return events, warnings
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.parse_all_event_observers(m, xml_node)
|
|
101
|
+
areas = [:global, :frontend, :adminhtml, :crontab]
|
|
102
|
+
events = {}
|
|
103
|
+
warnings = []
|
|
104
|
+
areas.each do |area|
|
|
105
|
+
e, w = parse_scoped_event_observers("/config/#{area}", xml_node.xpath("/config/#{area}"))
|
|
106
|
+
|
|
107
|
+
events[area] = e if e.size > 0
|
|
108
|
+
warnings.concat w
|
|
109
|
+
end
|
|
110
|
+
m[:events] = events if events.keys.size > 0
|
|
111
|
+
|
|
112
|
+
warnings << "the 'admin' area should not contain events (/config/admin/events)" unless xml_node.at_xpath("/config/admin/events").nil?
|
|
113
|
+
|
|
114
|
+
return warnings
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.collect_scoped_event_observers(area, sorted_modules)
|
|
118
|
+
events = Hash.new
|
|
119
|
+
|
|
120
|
+
sorted_modules.each do |m|
|
|
121
|
+
if m.include? :events and m[:events].include? area then
|
|
122
|
+
m[:events][area].each do |event|
|
|
123
|
+
event_name = event[:name]
|
|
124
|
+
events[event_name] ||= Hash.new
|
|
125
|
+
event[:observers].each do |observer|
|
|
126
|
+
observer_name = observer[:name]
|
|
127
|
+
if events[event_name].include? observer_name
|
|
128
|
+
add_module_config_warning(m, "event_observer:#{area}/#{event_name}/#{observer_name} - defined in #{events[event_name][observer_name][:module]} and redefined in #{m[:name]}")
|
|
129
|
+
end
|
|
130
|
+
events[event_name][observer_name] = observer
|
|
131
|
+
events[event_name][observer_name][:module] = m[:name]
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
69
137
|
events
|
|
70
138
|
end
|
|
71
139
|
|
|
72
|
-
def self.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
140
|
+
def self.collect_event_observers(sorted_modules)
|
|
141
|
+
areas = [:global, :frontend, :adminhtml, :crontab]
|
|
142
|
+
events = {}
|
|
143
|
+
|
|
144
|
+
areas.each do |area|
|
|
145
|
+
events[area] = collect_scoped_event_observers(area, sorted_modules)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
events
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
def self.add_module_config_warning(m, msg)
|
|
154
|
+
m[:warnings] ||= []
|
|
155
|
+
m[:warnings] << { :file => m[:config_path], :message => msg }
|
|
80
156
|
end
|
|
81
157
|
|
|
82
158
|
end
|
|
@@ -90,6 +90,11 @@ module Maruto::ModuleDefinition
|
|
|
90
90
|
m[:active] = false
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
|
+
else
|
|
94
|
+
if m[:code_pool] == :core and m[:name].to_s.start_with? 'Mage_' then
|
|
95
|
+
m[:warnings] ||= []
|
|
96
|
+
m[:warnings] << { :file => m[:defined], :message => "core/#{m[:name]} is inactive, but models and helpers will still be loaded" }
|
|
97
|
+
end
|
|
93
98
|
end
|
|
94
99
|
end
|
|
95
100
|
# remove inactive modules
|
data/lib/maruto/runner.rb
CHANGED
|
@@ -43,6 +43,7 @@ class Maruto::Runner < Thor
|
|
|
43
43
|
|
|
44
44
|
desc "warnings", "list potential problems found in the config"
|
|
45
45
|
method_option :magento_root, :aliases => "-m", :default => "."
|
|
46
|
+
method_option :with_core, :type => :boolean, :aliases => "-c", :default => false
|
|
46
47
|
def warnings()
|
|
47
48
|
|
|
48
49
|
magento_root = check_magento_folder()
|
|
@@ -52,11 +53,19 @@ class Maruto::Runner < Thor
|
|
|
52
53
|
|
|
53
54
|
# next gen maruto:
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
with_core = options[:with_core]
|
|
57
|
+
|
|
58
|
+
magento = Maruto::MagentoInstance.load(magento_root)
|
|
59
|
+
|
|
60
|
+
magento[:warnings].group_by { |e| e[:module] }.each do |m,module_warnings|
|
|
61
|
+
if with_core or magento[:all_modules][m][:code_pool] != :core then
|
|
62
|
+
puts "[module:#{m}]"
|
|
63
|
+
module_warnings.group_by { |e| e[:file] }.each do |file,warnings|
|
|
64
|
+
puts " [file:#{file}]"
|
|
65
|
+
warnings.each do |w|
|
|
66
|
+
puts " #{w[:message]}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
60
69
|
end
|
|
61
70
|
end
|
|
62
71
|
|
|
@@ -77,18 +86,41 @@ class Maruto::Runner < Thor
|
|
|
77
86
|
|
|
78
87
|
end
|
|
79
88
|
|
|
80
|
-
desc "observers", "list observers sorted and grouped by their
|
|
89
|
+
desc "observers", "list observers sorted and grouped by their event or area"
|
|
81
90
|
method_option :magento_root, :aliases => "-m", :default => "."
|
|
91
|
+
method_option :group_by_scope, :type => :boolean, :aliases => "-s", :default => false
|
|
82
92
|
def observers()
|
|
83
93
|
|
|
84
94
|
magento_root = check_magento_folder()
|
|
85
95
|
|
|
86
|
-
|
|
96
|
+
magento = Maruto::MagentoInstance.load(magento_root)
|
|
97
|
+
|
|
98
|
+
group_by_scope = options[:group_by_scope]
|
|
87
99
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
100
|
+
if group_by_scope then
|
|
101
|
+
magento[:event_observers].each do |area, events|
|
|
102
|
+
events.each do |event, observers|
|
|
103
|
+
puts "#{area}/#{event}"
|
|
104
|
+
observers.each do |name, observer|
|
|
105
|
+
puts " #{name} (module:#{observer[:module]} type:#{observer[:type]} class:#{observer[:class]} method:#{observer[:method]})"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
grouped_by_events = Hash.new
|
|
111
|
+
magento[:event_observers].each do |area, events|
|
|
112
|
+
events.each do |event, observers|
|
|
113
|
+
grouped_by_events[event] ||= Hash.new
|
|
114
|
+
grouped_by_events[event][area] = observers
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
grouped_by_events.sort_by { |k, v| k }.each do |event, areas|
|
|
118
|
+
puts "#{event}"
|
|
119
|
+
areas.each do |area, observers|
|
|
120
|
+
observers.each do |name, observer|
|
|
121
|
+
puts " #{area}/#{name} (module:#{observer[:module]} type:#{observer[:type]} class:#{observer[:class]} method:#{observer[:method]})"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
92
124
|
end
|
|
93
125
|
end
|
|
94
126
|
|
data/lib/maruto/version.rb
CHANGED
|
@@ -61,6 +61,9 @@ describe Maruto::ModuleDefinition do
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "will find dependencies" do
|
|
64
|
+
h = Maruto::ModuleDefinition.parse_module_definition(@xml_nodes[:Mage_Core])
|
|
65
|
+
h.wont_include :dependencies
|
|
66
|
+
|
|
64
67
|
h = Maruto::ModuleDefinition.parse_module_definition(@xml_nodes[:Mage_Eav])
|
|
65
68
|
h.must_include :dependencies
|
|
66
69
|
h[:dependencies].size.must_equal 1
|
|
@@ -179,15 +182,25 @@ describe Maruto::ModuleDefinition do
|
|
|
179
182
|
end
|
|
180
183
|
it "will not include inactive modules (in Array or Hash)" do
|
|
181
184
|
parsed_module_definitions = [
|
|
182
|
-
@module_a.merge({ :active => false}),
|
|
185
|
+
@module_a.merge({ :active => false }),
|
|
186
|
+
]
|
|
187
|
+
a,h = Maruto::ModuleDefinition.analyse_module_definitions(parsed_module_definitions)
|
|
188
|
+
a.size.must_equal 0
|
|
189
|
+
h.size.must_equal 0
|
|
190
|
+
end
|
|
191
|
+
it "will warn when a core/Mage_ module is inactive" do
|
|
192
|
+
parsed_module_definitions = [
|
|
193
|
+
@module_a.merge({ :active => false, :warnings => ['first warning'] }),
|
|
183
194
|
]
|
|
184
195
|
a,h = Maruto::ModuleDefinition.analyse_module_definitions(parsed_module_definitions)
|
|
185
196
|
a.size.must_equal 0
|
|
186
197
|
h.size.must_equal 0
|
|
198
|
+
parsed_module_definitions[0][:warnings].size.must_equal 2
|
|
199
|
+
parsed_module_definitions[0][:warnings][-1][:message].must_include 'inactive'
|
|
187
200
|
end
|
|
188
201
|
it "will remove missing dependencies and add a warning" do
|
|
189
202
|
parsed_module_definitions = [
|
|
190
|
-
@module_a.merge({ :active => true, :dependencies => [:Mage_B, :Mage_C], :warnings => ['first warning']}),
|
|
203
|
+
@module_a.merge({ :active => true, :dependencies => [:Mage_B, :Mage_C], :warnings => ['first warning'] }),
|
|
191
204
|
@module_b.merge({ :active => true }),
|
|
192
205
|
@module_c.merge({ :active => false }),
|
|
193
206
|
]
|
|
@@ -198,7 +211,7 @@ describe Maruto::ModuleDefinition do
|
|
|
198
211
|
end
|
|
199
212
|
it "will remove duplicate dependencies and add a warning" do
|
|
200
213
|
parsed_module_definitions = [
|
|
201
|
-
@module_a.merge({ :active => true, :dependencies => [:Mage_B, :Mage_C, :Mage_B], :warnings => ['first warning']}),
|
|
214
|
+
@module_a.merge({ :active => true, :dependencies => [:Mage_B, :Mage_C, :Mage_B], :warnings => ['first warning'] }),
|
|
202
215
|
@module_b.merge({ :active => true }),
|
|
203
216
|
@module_c.merge({ :active => true }),
|
|
204
217
|
]
|
data/spec/module_events_spec.rb
CHANGED
|
@@ -6,166 +6,426 @@ module Maruto
|
|
|
6
6
|
|
|
7
7
|
describe ModuleConfiguration do
|
|
8
8
|
|
|
9
|
-
describe "when parsing a module config.xml" do
|
|
10
|
-
describe "and reading events observers" do
|
|
11
|
-
before do
|
|
12
|
-
@xml_node = Nokogiri::XML('''
|
|
13
|
-
<events>
|
|
14
|
-
<first_event>
|
|
15
|
-
<observers>
|
|
16
|
-
<first_observer>
|
|
17
|
-
<type>model</type> <!-- model, object or singleton -->
|
|
18
|
-
<class>Mage_A_Model_Observer</class> <!-- observers class or class alias -->
|
|
19
|
-
<method>methodName</method> <!-- observer\'s method to be called -->
|
|
20
|
-
<args></args> <!-- additional arguments passed to observer -->
|
|
21
|
-
</first_observer>
|
|
22
|
-
</observers>
|
|
23
|
-
</first_event>
|
|
24
|
-
<second_event>
|
|
25
|
-
<observers>
|
|
26
|
-
<second_observer>
|
|
27
|
-
<type>object</type>
|
|
28
|
-
<class>Mage_B_Model_Observer</class>
|
|
29
|
-
<method>doSomething</method>
|
|
30
|
-
</second_observer>
|
|
31
|
-
<third_observer>
|
|
32
|
-
<type>singleton</type>
|
|
33
|
-
<class>Mage_C_Model_Observer</class>
|
|
34
|
-
<method>helloWorld</method>
|
|
35
|
-
</third_observer>
|
|
36
|
-
</observers>
|
|
37
|
-
</second_event>
|
|
38
|
-
</events>
|
|
39
|
-
''').root.at_xpath('/')
|
|
40
|
-
end
|
|
41
|
-
it "will return a array of events" do
|
|
42
|
-
e = ModuleConfiguration.parse_scoped_events_observers('', @xml_node)
|
|
43
|
-
e.must_be_kind_of Array
|
|
44
|
-
e.size.must_equal 2
|
|
45
|
-
end
|
|
46
|
-
it "will handle a missing <events> element or a nil node" do
|
|
47
|
-
node = Nokogiri::XML('''
|
|
48
|
-
<hello></hello>
|
|
49
|
-
''').root.at_xpath('/')
|
|
50
|
-
e = ModuleConfiguration.parse_scoped_events_observers('', node)
|
|
51
|
-
e.must_be_kind_of Array
|
|
52
|
-
e.size.must_equal 0
|
|
53
|
-
|
|
54
|
-
e = ModuleConfiguration.parse_scoped_events_observers('', nil)
|
|
55
|
-
e.must_be_kind_of Array
|
|
56
|
-
e.size.must_equal 0
|
|
57
|
-
end
|
|
58
|
-
it "will build the path to an event" do
|
|
59
|
-
e = ModuleConfiguration.parse_scoped_events_observers('root', @xml_node)
|
|
60
|
-
e[0][:path].must_equal 'root/events/first_event'
|
|
61
|
-
end
|
|
62
|
-
it "will read the name type class and method of an observer" do
|
|
63
|
-
e = ModuleConfiguration.parse_scoped_events_observers('', @xml_node)
|
|
64
|
-
e[0][:observers][0][:name].must_equal 'first_observer'
|
|
65
|
-
e[0][:observers][0][:type].must_equal 'model'
|
|
66
|
-
e[0][:observers][0][:class].must_equal 'Mage_A_Model_Observer'
|
|
67
|
-
e[0][:observers][0][:method].must_equal 'methodName'
|
|
68
|
-
end
|
|
69
|
-
it "will build the path to an event observer" do
|
|
70
|
-
e = ModuleConfiguration.parse_scoped_events_observers('root', @xml_node)
|
|
71
|
-
e[0][:observers][0][:path].must_equal 'root/events/first_event/observers/first_observer'
|
|
72
|
-
end
|
|
73
|
-
it "will group observers by events" do
|
|
74
|
-
e = ModuleConfiguration.parse_scoped_events_observers('', @xml_node)
|
|
75
|
-
e.size.must_equal 2
|
|
76
|
-
e[0].must_include :name
|
|
77
|
-
e[0].must_include :observers
|
|
78
|
-
e[0][:name].must_equal 'first_event'
|
|
79
|
-
e[0][:observers].size.must_equal 1
|
|
80
|
-
e[1][:name].must_equal 'second_event'
|
|
81
|
-
e[1][:observers].size.must_equal 2
|
|
82
|
-
end
|
|
83
9
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
10
|
+
describe "when parsing a module config.xml and reading scoped event observers" do
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
@events_root = Nokogiri::XML('''
|
|
14
|
+
<events>
|
|
15
|
+
<first_event>
|
|
16
|
+
<observers>
|
|
17
|
+
<first_observer>
|
|
18
|
+
<type>model</type> <!-- model, singleton or disabled, default is singleton (object is an alias for model) -->
|
|
19
|
+
<class>Mage_A_Model_Observer</class> <!-- observers class or class alias -->
|
|
20
|
+
<method>methodName</method> <!-- observer\'s method to be called -->
|
|
21
|
+
<args></args> <!-- additional arguments passed to observer -->
|
|
22
|
+
</first_observer>
|
|
23
|
+
</observers>
|
|
24
|
+
</first_event>
|
|
25
|
+
<second_event>
|
|
26
|
+
<observers>
|
|
27
|
+
<second_observer>
|
|
28
|
+
<class>Mage_B_Model_Observer</class>
|
|
29
|
+
<method>doSomething</method>
|
|
30
|
+
</second_observer>
|
|
31
|
+
<third_observer>
|
|
32
|
+
<type>object</type>
|
|
33
|
+
<class>Mage_C_Model_Observer</class>
|
|
34
|
+
<method>helloWorld</method>
|
|
35
|
+
</third_observer>
|
|
36
|
+
<disabled_observer>
|
|
37
|
+
<type>disabled</type>
|
|
38
|
+
<class>Mage_C_Model_Observer</class>
|
|
39
|
+
<method>helloWorld</method>
|
|
40
|
+
</disabled_observer>
|
|
41
|
+
</observers>
|
|
42
|
+
</second_event>
|
|
43
|
+
</events>
|
|
44
|
+
''').root.xpath('/')
|
|
111
45
|
end
|
|
112
46
|
|
|
113
|
-
it "will
|
|
47
|
+
it "will return a array of events" do
|
|
48
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
49
|
+
events.must_be_kind_of Array
|
|
50
|
+
events.size.must_equal 2
|
|
51
|
+
end
|
|
52
|
+
it "will return a array of warnings" do
|
|
53
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
54
|
+
warnings.must_be_kind_of Array
|
|
55
|
+
end
|
|
56
|
+
it "will handle a missing <events> element or a nil node" do
|
|
57
|
+
node = Nokogiri::XML('''
|
|
58
|
+
<hello></hello>
|
|
59
|
+
''').root.xpath('/')
|
|
60
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', node)
|
|
61
|
+
events.must_be_kind_of Array
|
|
62
|
+
events.size.must_equal 0
|
|
63
|
+
|
|
64
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', nil)
|
|
65
|
+
events.must_be_kind_of Array
|
|
66
|
+
events.size.must_equal 0
|
|
67
|
+
end
|
|
68
|
+
it "will build the path to an event" do
|
|
69
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', @events_root)
|
|
70
|
+
events[0][:path].must_equal 'root/events/first_event'
|
|
71
|
+
end
|
|
72
|
+
it "will read the name, class, and method of an observer" do
|
|
73
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
74
|
+
events[0][:observers][0][:name].must_equal 'first_observer'
|
|
75
|
+
events[0][:observers][0][:class].must_equal 'Mage_A_Model_Observer'
|
|
76
|
+
events[0][:observers][0][:method].must_equal 'methodName'
|
|
77
|
+
end
|
|
78
|
+
# see Mage_Core_Model_App::dispatchEvent
|
|
79
|
+
it "will read the type of an observer" do
|
|
80
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
81
|
+
events[0][:observers][0][:type].must_equal :model
|
|
82
|
+
end
|
|
83
|
+
it "will handle observer declarations with default type" do
|
|
84
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
85
|
+
events[1][:observers][0][:type].must_equal :singleton
|
|
86
|
+
end
|
|
87
|
+
it "will treat type 'object' as an alias to 'model'" do
|
|
88
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
89
|
+
events[1][:observers][1][:type].must_equal :model
|
|
90
|
+
end
|
|
91
|
+
it "will handle disabled observers" do
|
|
92
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
93
|
+
events[1][:observers][2][:type].must_equal :disabled
|
|
94
|
+
end
|
|
95
|
+
it "will handle observers with an invalid type and add a warning" do
|
|
96
|
+
node = Nokogiri::XML('''
|
|
97
|
+
<events>
|
|
98
|
+
<first_event>
|
|
99
|
+
<observers>
|
|
100
|
+
<invalid_type>
|
|
101
|
+
<type>something</type>
|
|
102
|
+
<class>Hello_World</class>
|
|
103
|
+
<method>helloWorld</method>
|
|
104
|
+
</invalid_type>
|
|
105
|
+
</observers>
|
|
106
|
+
</first_event>
|
|
107
|
+
</events>
|
|
108
|
+
''').root.xpath('/')
|
|
109
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', node)
|
|
110
|
+
events.size.must_equal 1
|
|
111
|
+
events[0][:observers].size.must_equal 1
|
|
112
|
+
events[0][:observers][0].must_include :type
|
|
113
|
+
events[0][:observers][0][:type].must_equal :singleton
|
|
114
|
+
warnings.size.must_equal 1
|
|
115
|
+
warnings[0].must_include 'root/events/first_event/observers/invalid_type/type'
|
|
116
|
+
warnings[0].must_include 'singleton'
|
|
117
|
+
warnings[0].must_include 'something'
|
|
118
|
+
end
|
|
119
|
+
it "will build the path to an event observer" do
|
|
120
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', @events_root)
|
|
121
|
+
events[0][:observers][0][:path].must_equal 'root/events/first_event/observers/first_observer'
|
|
122
|
+
end
|
|
123
|
+
it "will group observers by event" do
|
|
124
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('', @events_root)
|
|
125
|
+
events.size.must_equal 2
|
|
126
|
+
events[0].must_include :name
|
|
127
|
+
events[0].must_include :observers
|
|
128
|
+
events[0][:name].must_equal 'first_event'
|
|
129
|
+
events[0][:observers].size.must_equal 1
|
|
130
|
+
events[1][:name].must_equal 'second_event'
|
|
131
|
+
events[1][:observers].size.must_equal 3
|
|
132
|
+
end
|
|
133
|
+
it "will handle incomplete observer declarations" do
|
|
134
|
+
node = Nokogiri::XML('''
|
|
135
|
+
<events>
|
|
136
|
+
<first_event>
|
|
137
|
+
<observers>
|
|
138
|
+
<o1></o1>
|
|
139
|
+
<o2>
|
|
140
|
+
<class></class>
|
|
141
|
+
<method></method>
|
|
142
|
+
</o2>
|
|
143
|
+
</observers>
|
|
144
|
+
</first_event>
|
|
145
|
+
</events>
|
|
146
|
+
''').root.xpath('/')
|
|
147
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', node)
|
|
148
|
+
events.size.must_equal 1
|
|
149
|
+
events[0][:observers].size.must_be :>, 0
|
|
150
|
+
end
|
|
151
|
+
# it "will warn if an observers class is invalid" do
|
|
152
|
+
# # TODO
|
|
153
|
+
# end
|
|
154
|
+
it "will handle duplicate areas and add a warning" do
|
|
114
155
|
node = Nokogiri::XML('''<config>
|
|
115
|
-
<
|
|
156
|
+
<area>
|
|
116
157
|
<events>
|
|
117
158
|
<e1><observers></observers></e1>
|
|
118
159
|
</events>
|
|
119
|
-
</
|
|
120
|
-
<
|
|
160
|
+
</area>
|
|
161
|
+
<area>
|
|
121
162
|
<events>
|
|
122
163
|
<e2><observers></observers></e2>
|
|
123
|
-
<e3></e3>
|
|
124
164
|
</events>
|
|
125
|
-
</
|
|
126
|
-
<adminhtml>
|
|
127
|
-
<events>
|
|
128
|
-
<e4></e4>
|
|
129
|
-
<e5></e5>
|
|
130
|
-
<e6></e6>
|
|
131
|
-
</events>
|
|
132
|
-
</adminhtml>
|
|
165
|
+
</area>
|
|
133
166
|
</config>''').root
|
|
167
|
+
events, warnings = ModuleConfiguration.parse_scoped_event_observers('/config/area', node.xpath('/config/area'))
|
|
168
|
+
events.size.must_equal 2
|
|
169
|
+
warnings.size.must_equal 1
|
|
170
|
+
warnings[0].must_include '/config/area'
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe "when parsing all event observers" do
|
|
175
|
+
|
|
176
|
+
before do
|
|
177
|
+
@module_a = { :name => :Mage_A, :active => true, :code_pool => :core, :defined => 'a', :config_path => 'app/code/core/Mage/A/etc/config.xml' }
|
|
178
|
+
@xml_root = Nokogiri::XML('''
|
|
179
|
+
<config>
|
|
180
|
+
<global>
|
|
181
|
+
<events>
|
|
182
|
+
<e1><observers><o1><type>invalid</type></o1></observers></e1>
|
|
183
|
+
</events>
|
|
184
|
+
</global>
|
|
185
|
+
<frontend>
|
|
186
|
+
<events>
|
|
187
|
+
<e2><observers></observers></e2>
|
|
188
|
+
<e3></e3>
|
|
189
|
+
</events>
|
|
190
|
+
</frontend>
|
|
191
|
+
<adminhtml>
|
|
192
|
+
<events>
|
|
193
|
+
<e4></e4>
|
|
194
|
+
<e5></e5>
|
|
195
|
+
<e6></e6>
|
|
196
|
+
</events>
|
|
197
|
+
</adminhtml>
|
|
198
|
+
<crontab>
|
|
199
|
+
<events>
|
|
200
|
+
<e1></e1>
|
|
201
|
+
</events>
|
|
202
|
+
</crontab>
|
|
203
|
+
</config>
|
|
204
|
+
''').root
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "will add events to the module" do
|
|
208
|
+
@module_a.wont_include :events
|
|
209
|
+
ModuleConfiguration.parse_all_event_observers(@module_a, @xml_root)
|
|
210
|
+
@module_a.must_include :events
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "will collect warnings into an array" do
|
|
214
|
+
warnings = ModuleConfiguration.parse_all_event_observers(@module_a, @xml_root)
|
|
215
|
+
warnings.size.must_be :>, 0
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
it "will group events by scope and build the correct path" do
|
|
220
|
+
@module_a.wont_include :events
|
|
221
|
+
ModuleConfiguration.parse_all_event_observers(@module_a, @xml_root)
|
|
222
|
+
@module_a.must_include :events
|
|
134
223
|
|
|
135
|
-
|
|
224
|
+
@module_a[:events].must_be_kind_of Hash
|
|
225
|
+
@module_a[:events].must_include :global
|
|
226
|
+
@module_a[:events].must_include :frontend
|
|
227
|
+
@module_a[:events].must_include :adminhtml
|
|
136
228
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
e.must_include :adminhtml
|
|
229
|
+
@module_a[:events][:global].size.must_equal 1
|
|
230
|
+
@module_a[:events][:global][0][:name].must_equal 'e1'
|
|
231
|
+
@module_a[:events][:global][0][:path].must_include '/config/global/events'
|
|
141
232
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
233
|
+
@module_a[:events][:frontend].size.must_equal 2
|
|
234
|
+
@module_a[:events][:frontend][0][:name].must_equal 'e2'
|
|
235
|
+
@module_a[:events][:frontend][0][:path].must_include '/config/frontend/events'
|
|
145
236
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
237
|
+
@module_a[:events][:adminhtml].size.must_equal 3
|
|
238
|
+
@module_a[:events][:adminhtml][0][:name].must_equal 'e4'
|
|
239
|
+
@module_a[:events][:adminhtml][0][:path].must_include '/config/adminhtml/events'
|
|
149
240
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
241
|
+
@module_a[:events][:crontab].size.must_equal 1
|
|
242
|
+
@module_a[:events][:crontab][0][:name].must_equal 'e1'
|
|
243
|
+
@module_a[:events][:crontab][0][:path].must_include '/config/crontab/events'
|
|
153
244
|
end
|
|
245
|
+
|
|
154
246
|
it "will skip scopes without events" do
|
|
155
|
-
node = Nokogiri::XML('''
|
|
247
|
+
node = Nokogiri::XML('''<config>
|
|
248
|
+
<global>
|
|
249
|
+
<events>
|
|
250
|
+
<e1><observers><o1></o1></observers></e1>
|
|
251
|
+
</events>
|
|
252
|
+
</global>
|
|
253
|
+
</config>''').root
|
|
254
|
+
|
|
255
|
+
@module_a.wont_include :events
|
|
256
|
+
ModuleConfiguration.parse_all_event_observers(@module_a, node)
|
|
257
|
+
@module_a.must_include :events
|
|
258
|
+
|
|
259
|
+
@module_a[:events].wont_include :frontend
|
|
260
|
+
@module_a[:events].wont_include :adminhtml
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "will skip :events without events" do
|
|
264
|
+
node = Nokogiri::XML('''<config>
|
|
156
265
|
<global>
|
|
157
266
|
<events>
|
|
158
267
|
</events>
|
|
159
268
|
</global>
|
|
160
269
|
<frontend>
|
|
161
270
|
</frontend>
|
|
162
|
-
''').root
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
271
|
+
</config>''').root
|
|
272
|
+
|
|
273
|
+
@module_a.wont_include :events
|
|
274
|
+
warnings = ModuleConfiguration.parse_all_event_observers(@module_a, node)
|
|
275
|
+
@module_a.wont_include :events
|
|
276
|
+
|
|
277
|
+
warnings.size.must_equal 0
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "will add a warning for events in the 'admin' area" do
|
|
281
|
+
node = Nokogiri::XML('''<config>
|
|
282
|
+
<admin>
|
|
283
|
+
<events>
|
|
284
|
+
</events>
|
|
285
|
+
</admin>
|
|
286
|
+
</config>''').root
|
|
287
|
+
|
|
288
|
+
@module_a.wont_include :events
|
|
289
|
+
warnings = ModuleConfiguration.parse_all_event_observers(@module_a, node)
|
|
290
|
+
@module_a.wont_include :events
|
|
291
|
+
|
|
292
|
+
warnings.size.must_equal 1
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
describe "when collecting all event observers" do
|
|
298
|
+
before do
|
|
299
|
+
@module_a = { :name => :Mage_A, :active => true, :code_pool => :core, :defined => 'a', :config_path => 'app/code/core/Mage/A/etc/config.xml' }
|
|
300
|
+
@module_b = { :name => :Mage_B, :active => true, :code_pool => :core, :defined => 'b', :config_path => 'app/code/core/Mage/B/etc/config.xml' }
|
|
301
|
+
@module_c = { :name => :Mage_C, :active => true, :code_pool => :core, :defined => 'c', :config_path => 'app/code/core/Mage/C/etc/config.xml' }
|
|
302
|
+
@module_d = { :name => :Mage_D, :active => true, :code_pool => :core, :defined => 'd', :config_path => 'app/code/core/Mage/D/etc/config.xml' }
|
|
303
|
+
|
|
304
|
+
@observer_1 = { :name => 'a_o1', :type => 'singleton', :class => 'Mage_A_Model_Observer', :method => 'global_1' }
|
|
305
|
+
|
|
306
|
+
@module_a[:events] = {
|
|
307
|
+
:global => [{ :name => 'e1', :observers => [
|
|
308
|
+
@observer_1,
|
|
309
|
+
{ :name => 'a_o2', :type => 'singleton', :class => 'Mage_A_Model_Observer', :method => 'global_2' }
|
|
310
|
+
] }],
|
|
311
|
+
:adminhtml => [{ :name => 'e1', :observers => [
|
|
312
|
+
{ :name => 'a_o1', :type => 'singleton', :class => 'Mage_A_Model_Observer', :method => 'adminhtml_1' }
|
|
313
|
+
] }],
|
|
314
|
+
:frontend => [{ :name => 'e1', :observers => [
|
|
315
|
+
{ :name => 'a_o1', :type => 'singleton', :class => 'Mage_A_Model_Observer', :method => 'frontend_1' }
|
|
316
|
+
] }]
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@sorted_modules = [@module_a]
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "will group observers by event" do
|
|
323
|
+
h = ModuleConfiguration.collect_scoped_event_observers(:global, @sorted_modules)
|
|
324
|
+
h.must_include 'e1'
|
|
325
|
+
h['e1'].must_include 'a_o1'
|
|
326
|
+
h['e1'].must_include 'a_o2'
|
|
327
|
+
|
|
328
|
+
[:name, :type, :class, :method].each do |key|
|
|
329
|
+
h['e1']['a_o1'].must_include key
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
@module_a.wont_include :warnings
|
|
333
|
+
end
|
|
334
|
+
it "will add the source module to the observer" do
|
|
335
|
+
h, w = ModuleConfiguration.collect_scoped_event_observers(:global, @sorted_modules)
|
|
336
|
+
h['e1']['a_o1'].must_include :module
|
|
337
|
+
h['e1']['a_o1'][:module].must_equal :Mage_A
|
|
338
|
+
@module_a.wont_include :warnings
|
|
168
339
|
end
|
|
340
|
+
it "will add a warning when overwriting an observer" do
|
|
341
|
+
@module_b[:events] = {
|
|
342
|
+
:global => [{ :name => 'e1', :observers => [ @observer_1 ] }]
|
|
343
|
+
}
|
|
344
|
+
h = ModuleConfiguration.collect_scoped_event_observers(:global, [@module_a, @module_b])
|
|
345
|
+
|
|
346
|
+
@module_b.must_include :warnings
|
|
347
|
+
@module_b[:warnings].size.must_equal 1
|
|
348
|
+
end
|
|
349
|
+
it "will add a warning when overwriting an observer without module dependency" do
|
|
350
|
+
# TODO
|
|
351
|
+
end
|
|
352
|
+
it "wont add a warning when overwriting an observer to disable it" do
|
|
353
|
+
# TODO
|
|
354
|
+
end
|
|
355
|
+
it "will add a warning when disabling a non-existing observer" do
|
|
356
|
+
# TODO
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
it "will include all areas" do
|
|
361
|
+
h = ModuleConfiguration.collect_event_observers([])
|
|
362
|
+
|
|
363
|
+
h.keys.size.must_equal 4
|
|
364
|
+
|
|
365
|
+
h.must_include :global
|
|
366
|
+
h.must_include :adminhtml
|
|
367
|
+
h.must_include :frontend
|
|
368
|
+
h.must_include :crontab
|
|
369
|
+
|
|
370
|
+
h[:global].must_be_kind_of Hash
|
|
371
|
+
h[:global].size.must_equal 0
|
|
372
|
+
|
|
373
|
+
h[:adminhtml].must_be_kind_of Hash
|
|
374
|
+
h[:adminhtml].size.must_equal 0
|
|
375
|
+
|
|
376
|
+
h[:frontend].must_be_kind_of Hash
|
|
377
|
+
h[:frontend].size.must_equal 0
|
|
378
|
+
|
|
379
|
+
h[:crontab].must_be_kind_of Hash
|
|
380
|
+
h[:crontab].size.must_equal 0
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it "will group observers by area" do
|
|
384
|
+
h = ModuleConfiguration.collect_event_observers(@sorted_modules)
|
|
385
|
+
|
|
386
|
+
h[:global].must_include 'e1'
|
|
387
|
+
h[:global]['e1'].must_include 'a_o1'
|
|
388
|
+
h[:global]['e1'].must_include 'a_o2'
|
|
389
|
+
|
|
390
|
+
h[:adminhtml].must_include 'e1'
|
|
391
|
+
h[:adminhtml]['e1'].must_include 'a_o1'
|
|
392
|
+
h[:adminhtml]['e1'].wont_include 'a_o2'
|
|
393
|
+
|
|
394
|
+
h[:frontend].must_include 'e1'
|
|
395
|
+
h[:frontend]['e1'].must_include 'a_o1'
|
|
396
|
+
h[:frontend]['e1'].wont_include 'a_o2'
|
|
397
|
+
|
|
398
|
+
h[:crontab].wont_include 'e1'
|
|
399
|
+
|
|
400
|
+
@module_a.wont_include :warnings
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
describe "when analysing event observers" do
|
|
405
|
+
|
|
406
|
+
it "will add a warning when an observer has already been declared" do
|
|
407
|
+
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# it "will warn when an event has no observers" do
|
|
411
|
+
# xml_node_no_obs = Nokogiri::XML('''
|
|
412
|
+
# <config><scope><events><first_event></first_event></events></scope></config>
|
|
413
|
+
# ''').root
|
|
414
|
+
# events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', xml_node_no_obs.xpath('/config/scope'))
|
|
415
|
+
# events.size.must_equal 0
|
|
416
|
+
# warnings.size.must_equal 1
|
|
417
|
+
# warnings[0].must_include 'root/events/first_event'
|
|
418
|
+
# end
|
|
419
|
+
# it "will warn when an event has an empty observers node" do
|
|
420
|
+
# xml_node_empty_obs = Nokogiri::XML('''
|
|
421
|
+
# <config><scope><events><first_event><observers></observers></first_event></events></scope></config>
|
|
422
|
+
# ''').root
|
|
423
|
+
# events, warnings = ModuleConfiguration.parse_scoped_event_observers('root', xml_node_empty_obs.xpath('/config/scope'))
|
|
424
|
+
# events.size.must_equal 0
|
|
425
|
+
# warnings.size.must_equal 1
|
|
426
|
+
# warnings[0].must_include 'root/events/first_event/observers'
|
|
427
|
+
# end
|
|
428
|
+
|
|
169
429
|
end
|
|
170
430
|
end
|
|
171
431
|
end
|
data/spec/module_version_spec.rb
CHANGED
|
@@ -20,29 +20,24 @@ module Maruto
|
|
|
20
20
|
''').root
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
it "will return the
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
m.must_equal @module_a
|
|
23
|
+
it "will return the an array of warnings" do
|
|
24
|
+
warnings = ModuleConfiguration.parse_module_version(@module_a, @xml_config_root)
|
|
25
|
+
warnings.must_be_kind_of Array
|
|
27
26
|
end
|
|
28
|
-
it "will add the version to the
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
it "will add the version to the module" do
|
|
28
|
+
ModuleConfiguration.parse_module_version(@module_a, @xml_config_root)
|
|
29
|
+
@module_a.must_include :version
|
|
30
|
+
@module_a[:version].must_equal '0.0.1'
|
|
32
31
|
end
|
|
33
32
|
it "will add a warning when then modules node is missing" do
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
m[:warnings][-1][:file].must_equal m[:config_path]
|
|
38
|
-
m[:warnings][-1][:message].must_include '/config/modules'
|
|
33
|
+
warnings = ModuleConfiguration.parse_module_version(@module_a, Nokogiri::XML('<config><a></a></config>').root)
|
|
34
|
+
warnings.size.must_equal 1
|
|
35
|
+
warnings[0].must_include '/config/modules'
|
|
39
36
|
end
|
|
40
37
|
it "will add a warning when then node with the module's name is missing" do
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
m[:warnings][-1][:file].must_equal m[:config_path]
|
|
45
|
-
m[:warnings][-1][:message].must_include '/config/modules/Mage_A'
|
|
38
|
+
warnings = ModuleConfiguration.parse_module_version(@module_a, Nokogiri::XML('<config><modules></modules></config>').root)
|
|
39
|
+
warnings.size.must_equal 1
|
|
40
|
+
warnings[0].must_include '/config/modules/Mage_A'
|
|
46
41
|
end
|
|
47
42
|
it "will add a warning when there is a node from a different module" do
|
|
48
43
|
xml_config_root = Nokogiri::XML('''
|
|
@@ -55,13 +50,10 @@ module Maruto
|
|
|
55
50
|
</Mage_B>
|
|
56
51
|
</modules></config>
|
|
57
52
|
''').root
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
m[:warnings][-1][:file].must_equal m[:config_path]
|
|
62
|
-
m[:warnings][-1][:message].must_include 'Mage_B'
|
|
53
|
+
warnings = ModuleConfiguration.parse_module_version(@module_a, xml_config_root)
|
|
54
|
+
warnings.size.must_equal 1
|
|
55
|
+
warnings[0].must_include 'Mage_B'
|
|
63
56
|
end
|
|
64
57
|
|
|
65
58
|
end
|
|
66
|
-
|
|
67
59
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: maruto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.6
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-05-
|
|
12
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: nokogiri
|