aquarium 0.3.0 → 0.3.1
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/Aquarium.ipr +253 -0
- data/Aquarium.iws +629 -0
- data/CHANGES +43 -0
- data/UPGRADE +13 -7
- data/examples/method_tracing_example_spec.rb +4 -1
- data/lib/aquarium/aspects/aspect.rb +28 -11
- data/lib/aquarium/aspects/exclusion_handler.rb +1 -1
- data/lib/aquarium/aspects/join_point.rb +58 -14
- data/lib/aquarium/aspects/pointcut.rb +5 -6
- data/lib/aquarium/extras/design_by_contract.rb +1 -1
- data/lib/aquarium/finders/method_finder.rb +1 -4
- data/lib/aquarium/finders/type_finder.rb +8 -1
- data/lib/aquarium/utils.rb +1 -0
- data/lib/aquarium/utils/default_logger.rb +20 -0
- data/lib/aquarium/utils/options_utils.rb +74 -12
- data/lib/aquarium/utils/type_utils.rb +1 -7
- data/lib/aquarium/version.rb +1 -1
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +1 -1
- data/spec/aquarium/aspects/advice_spec.rb +1 -1
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +1531 -1465
- data/spec/aquarium/aspects/aspect_spec.rb +22 -27
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +1 -1
- data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +1 -1
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
- data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +434 -424
- data/spec/aquarium/aspects/join_point_spec.rb +27 -4
- data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +98 -102
- data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +95 -107
- data/spec/aquarium/aspects/pointcut_spec.rb +1365 -1382
- data/spec/aquarium/extensions/hash_spec.rb +1 -1
- data/spec/aquarium/extensions/set_spec.rb +1 -1
- data/spec/aquarium/finders/finder_result_spec.rb +1 -1
- data/spec/aquarium/finders/method_finder_spec.rb +1 -1
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +63 -145
- data/spec/aquarium/{spec_example_classes.rb → spec_example_types.rb} +35 -0
- data/spec/aquarium/utils/default_logger_spec.rb +28 -0
- data/spec/aquarium/utils/hash_utils_spec.rb +1 -1
- data/spec/aquarium/utils/logic_error_spec.rb +1 -1
- data/spec/aquarium/utils/name_utils_spec.rb +1 -1
- data/spec/aquarium/utils/nil_object_spec.rb +1 -1
- data/spec/aquarium/utils/options_utils_spec.rb +122 -0
- data/spec/aquarium/utils/set_utils_spec.rb +1 -1
- metadata +9 -4
data/CHANGES
CHANGED
@@ -1,3 +1,46 @@
|
|
1
|
+
== Version 0.3.1
|
2
|
+
|
3
|
+
V0.3.1 adds numerous performance improvements, especially in the RSpec suite, and some minor API additions.
|
4
|
+
|
5
|
+
Bug fixes:
|
6
|
+
N.A.
|
7
|
+
|
8
|
+
Enhancements:
|
9
|
+
14447 Unify internal handling of reporting errors to the user
|
10
|
+
17514 Provide an Aquarium library-wide logger with configuration parameters and instance overrides
|
11
|
+
17515 Add an optional warning if an aspect doesn't match any join points
|
12
|
+
17516 Remove unnecessary examples that use :types_and_descendents to shorten time to run the RSpec suite
|
13
|
+
17565 JoinPoint.new should convert a type name, symbol, or regex to the type and only allow one type
|
14
|
+
|
15
|
+
These first two enhancements are related. There is a now an Aquarium::Utils::DefaultLogger
|
16
|
+
module with static accessors for getting and setting the "system-wide" logger.
|
17
|
+
|
18
|
+
When instance-level overrides are necessary, the Aquarium::Utils::OptionsUtils provides
|
19
|
+
"universal" options (but currently used only by Aspect and Pointcut) for specifying a logger
|
20
|
+
(with the new :logger parameter), or alternatively, specifying just the output stream
|
21
|
+
(:logger_stream) and/or the severity (:severity, one of the standard library's
|
22
|
+
Logger::Severity-defined constants). If either of the latter two options is specified, a
|
23
|
+
separate logger instance is created, rather than changing parameters for the global logger.
|
24
|
+
|
25
|
+
OptionsUtils also supports a :noop parameter, which classes interpret to mean do none (or
|
26
|
+
perhaps only some) of the processing. Useful for debugging.
|
27
|
+
|
28
|
+
#17515 adds a helpful warning to the system (or aspect-instance's) logger if an aspect
|
29
|
+
matches no join points. This warning will be suppressed if (i) the severity level for the
|
30
|
+
logger is above WARN or (ii) the aspect was created with the option
|
31
|
+
:ignore_no_matching_join_points => true.
|
32
|
+
|
33
|
+
#17516 fixes halved the long execution times for the whole RSpec suite by refactoring some examples
|
34
|
+
that used type finders with the :types_and_descendents option unnecessarily. It is a very intensive
|
35
|
+
computation! Note that I stubbed out these calls using an aspect with around advise, a useful
|
36
|
+
"development-time" aspect. See Aquarium::TypeUtilsStub (in spec_example_types.rb) and how it's used
|
37
|
+
in pointcut_spec.rb. Using this technique and other optimizations, the time to run the suite was
|
38
|
+
reduced from ~5 minutes to about 1 minute.
|
39
|
+
|
40
|
+
#17565 fixes a "hole" in JoinPoint, where it doesn't confirm that a specified type string, symbol
|
41
|
+
or regex matches a class that exists and only one class. Now it does and it stores the type, rather
|
42
|
+
than the original "specification" for it.
|
43
|
+
|
1
44
|
== Version 0.3.0
|
2
45
|
|
3
46
|
V0.3.0 adds numerous improvements to the DSL, making aspect specification more intuitive and
|
data/UPGRADE
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
==
|
1
|
+
== Updating to Aquarium-0.3.1
|
2
|
+
|
3
|
+
There should be no upgrade issues with this release. However, the enhancement #17565 now ensures that a
|
4
|
+
JoinPoint is only specified with one type and a type that actually exists, when a string, symbol, or
|
5
|
+
regex is used to specify the type.
|
6
|
+
|
7
|
+
== Updating to Aquarium-0.3.0
|
2
8
|
|
3
9
|
There are no known upgrade issues with this release. Although many new synonyms were added for API method
|
4
10
|
parameters, all changes are backwards compatible.
|
5
11
|
|
6
|
-
==
|
12
|
+
== Updating to Aquarium-0.2.0
|
7
13
|
|
8
14
|
This release changes the expected advice parameter list from |join_point, *method_args| to
|
9
15
|
|join_point, object, *method_args|, where "object" is the current object receiving the message
|
@@ -14,22 +20,22 @@ Aquarium will raise an exception if the advice block or proc has this obsolete s
|
|
14
20
|
|
15
21
|
Note that "JoinPoint#Context.advised_object" is still supported, even if it is now less useful.
|
16
22
|
|
17
|
-
==
|
23
|
+
== Updating to Aquarium-0.1.8
|
18
24
|
|
19
25
|
V0.1.7 did not successfully "register" at rubyforge. This releases fixes that problem and also adds
|
20
26
|
several feature enhancements and refactorings. There are no known upgrade issues.
|
21
27
|
|
22
|
-
==
|
28
|
+
== Updating to Aquarium-0.1.7
|
23
29
|
|
24
30
|
This is primarily a bug-fix release, so there should be no upgrading or incompatibility issues.
|
25
31
|
|
26
|
-
==
|
32
|
+
== Updating to Aquarium-0.1.6
|
27
33
|
|
28
34
|
As described in the CHANGES, the JoinPoint#type, JoinPoint#type=, JoinPoint#object, and JoinPoint#object=
|
29
35
|
are now deprecated. Client code that uses these methods will still work, but warning messages will be
|
30
36
|
written to STDOUT. See CHANGES for more details.
|
31
37
|
|
32
|
-
==
|
38
|
+
== Updating to Aquarium-0.1.5
|
33
39
|
|
34
40
|
This is mostly a bug-fix release, but it did have to introduce one API change, as described in the
|
35
41
|
CHANGES. In particular, the aspect "DSL" methods are no longer automatically to Object, as some of
|
@@ -69,6 +75,6 @@ object.extend(Aquarium::Aspects::DSL::AspectDSL)
|
|
69
75
|
|
70
76
|
See the CHANGES for more details.
|
71
77
|
|
72
|
-
==
|
78
|
+
== Updating existing code to Aquarium-0.1.0
|
73
79
|
|
74
80
|
This is the first release of Aquarium.
|
@@ -79,8 +79,11 @@ end
|
|
79
79
|
|
80
80
|
describe "An example with advice on the public instance methods (excluding ancestor methods) of Bar" do
|
81
81
|
it "should not trace any calls to the public methods defined by the included BarModule" do
|
82
|
+
# Suppress warnings about no join points matched with :ignore_no_matching_join_points => true
|
82
83
|
aspect = Aquarium::Aspects::Aspect.new :around,
|
83
|
-
:invocations_of => :all_methods, :for_type => Aquarium::Bar,
|
84
|
+
:invocations_of => :all_methods, :for_type => Aquarium::Bar,
|
85
|
+
:restricting_methods_to => :exclude_ancestor_methods,
|
86
|
+
:ignore_no_matching_join_points => true do |execution_point, obj, *args|
|
84
87
|
begin
|
85
88
|
obj.log "Entering: #{execution_point.target_type.name}##{execution_point.method_name}: args = #{args.inspect}"
|
86
89
|
execution_point.proceed
|
@@ -35,7 +35,8 @@ module Aquarium
|
|
35
35
|
CANONICAL_OPTIONS = Pointcut::CANONICAL_OPTIONS.merge({
|
36
36
|
"advice" => %w[action do_action use_advice advise_with invoke call],
|
37
37
|
"pointcuts" => %w[pointcut within_pointcuts within_pointcut on_pointcuts on_pointcut],
|
38
|
-
"exclude_pointcuts" => %w[exclude_pointcut exclude_on_pointcut exclude_on_pointcuts exclude_within_pointcut exclude_within_pointcuts]
|
38
|
+
"exclude_pointcuts" => %w[exclude_pointcut exclude_on_pointcut exclude_on_pointcuts exclude_within_pointcut exclude_within_pointcuts],
|
39
|
+
"ignore_no_matching_join_points" => %[ignore_no_jps]
|
39
40
|
})
|
40
41
|
|
41
42
|
ALL_ALLOWED_OPTIONS = CANONICAL_OPTIONS.keys.inject([]) {|ary,i| ary << i << CANONICAL_OPTIONS[i]}.flatten +
|
@@ -103,15 +104,18 @@ module Aquarium
|
|
103
104
|
# One or an array of Pointcut or JoinPoint objects. Mutually-exclusive with the :types, :objects,
|
104
105
|
# :methods, :attributes, :method_options, and :attribute_options parameters.
|
105
106
|
#
|
106
|
-
# <tt>:
|
107
|
-
#
|
107
|
+
# <tt>:ignore_no_matching_join_points => true | false</tt>
|
108
|
+
# <tt>ignore_no_jps => true | false</tt>::
|
109
|
+
# Do not issue a warning if no join points are actually matched by the aspect. By default, the value
|
110
|
+
# is false, meaning that a WARN-level message will be written to the log. It is usually very helpful
|
111
|
+
# to be warned when no matches occurred, for diagnostic purposes!
|
108
112
|
#
|
109
|
-
#
|
110
|
-
# :methods, etc.
|
113
|
+
# Aspect.new also accepts all the same options that Pointcut accepts, including the synonyms for :types,
|
114
|
+
# :methods, etc. It also accepts the "universal" options documented in OptionsUtils.
|
111
115
|
def initialize *options, &block
|
112
116
|
@first_option_that_was_method = []
|
113
117
|
opts = rationalize options
|
114
|
-
init_specification opts,
|
118
|
+
init_specification opts, CANONICAL_OPTIONS, &block
|
115
119
|
init_pointcuts
|
116
120
|
validate_specification
|
117
121
|
return if noop
|
@@ -126,9 +130,6 @@ module Aquarium
|
|
126
130
|
get_jps :join_points_not_matched
|
127
131
|
end
|
128
132
|
|
129
|
-
def canonical_options
|
130
|
-
CANONICAL_OPTIONS
|
131
|
-
end
|
132
133
|
def all_allowed_option_symbols
|
133
134
|
ALL_ALLOWED_OPTION_SYMBOLS + @first_option_that_was_method
|
134
135
|
end
|
@@ -213,8 +214,25 @@ module Aquarium
|
|
213
214
|
pointcuts << Pointcut.new(pc_options)
|
214
215
|
end
|
215
216
|
@pointcuts = Set.new(remove_excluded_join_points_and_empty_pointcuts(pointcuts))
|
217
|
+
warn_if_no_join_points_matched
|
216
218
|
end
|
217
219
|
|
220
|
+
def warn_if_no_join_points_matched
|
221
|
+
return unless should_warn_if_no_matching_join_points
|
222
|
+
@pointcuts.each do |pc|
|
223
|
+
if pc.join_points_matched.size > 0
|
224
|
+
return
|
225
|
+
end
|
226
|
+
end
|
227
|
+
logger.warn "Warning: No join points were matched. The options specified were #{@original_options.inspect}"
|
228
|
+
end
|
229
|
+
|
230
|
+
def should_warn_if_no_matching_join_points
|
231
|
+
@specification[:ignore_no_matching_join_points].nil? or
|
232
|
+
@specification[:ignore_no_matching_join_points].empty? or
|
233
|
+
@specification[:ignore_no_matching_join_points].to_a.first == false
|
234
|
+
end
|
235
|
+
|
218
236
|
def remove_excluded_join_points_and_empty_pointcuts pointcuts
|
219
237
|
pointcuts.reject do |pc|
|
220
238
|
pc.join_points_matched.delete_if do |jp|
|
@@ -328,7 +346,6 @@ module Aquarium
|
|
328
346
|
Aspect.is_type_join_point?(join_point) ? "" : "remove_method :#{join_point.method_name}"
|
329
347
|
end
|
330
348
|
|
331
|
-
# TODO Move to JoinPoint
|
332
349
|
def self.is_type_join_point? join_point
|
333
350
|
Aquarium::Utils::TypeUtils.is_type? join_point.type_or_object
|
334
351
|
end
|
@@ -473,7 +490,7 @@ module Aquarium
|
|
473
490
|
bad_options(":after can't be used with :after_raising.") if after_given_with? :after_raising
|
474
491
|
bad_options(":after_returning can't be used with :after_raising.") if after_returning_given_with? :after_raising
|
475
492
|
unless some_type_or_pc_option_given?
|
476
|
-
bad_options("At least one of :pointcut(s), :type(s), :type(s)
|
493
|
+
bad_options("At least one of :pointcut(s), :type(s), :type(s)_and_ancestors, :type(s)_and_descendents, :object(s) is required.")
|
477
494
|
end
|
478
495
|
if pointcuts_given? and (some_type_option_given? or objects_given?)
|
479
496
|
bad_options("Can't specify both :pointcut(s) and one or more of :type(s), and/or :object(s).")
|
@@ -18,7 +18,7 @@ module Aquarium
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
# Using @specification[:exclude_join_points].include?(jp) doesn't always work correctly (it probably uses equal())!
|
21
|
+
# Using @specification[:exclude_join_points].include?(jp) doesn't always work correctly (it probably uses equal?())!
|
22
22
|
def is_excluded_join_point? jp
|
23
23
|
return false if @specification[:exclude_join_points].nil?
|
24
24
|
@specification[:exclude_join_points].find {|jp2| jp2 == jp || jp2.eql?(jp)}
|
@@ -17,6 +17,20 @@ module Aquarium
|
|
17
17
|
alias :target_object :advised_object
|
18
18
|
alias :target_object= :advised_object=
|
19
19
|
|
20
|
+
# Create a join point object. It must have one and only type _or_ object and one method or the special keywords <tt>:all</tt>.
|
21
|
+
# Usage:
|
22
|
+
# join_point = JoinPoint.new.find :type => ..., :method_name => ... [, (:class_method | :instance_method) => (true | false) ]
|
23
|
+
# where
|
24
|
+
# <tt>:type => type_or_type_name_or_regexp</tt>::
|
25
|
+
# A single type, type name or regular expression matching only one type. One and only one
|
26
|
+
# type _or_ object is required. An error is raised otherwise.
|
27
|
+
#
|
28
|
+
# <tt>:method_name => method_name_or_sym</tt>::
|
29
|
+
# <tt>:method => method_name_or_sym</tt>::
|
30
|
+
# A single method name or symbol. Only one is allowed, although the special flag <tt>:all</tt> is allowed.
|
31
|
+
#
|
32
|
+
# <tt>(:class_method | :instance_method) => (true | false)</tt>::
|
33
|
+
# Is the method a class or instance method? Defaults to <tt>:instance_method => true</tt>.
|
20
34
|
def initialize options
|
21
35
|
update options
|
22
36
|
assert_valid options
|
@@ -91,7 +105,7 @@ module Aquarium
|
|
91
105
|
end
|
92
106
|
|
93
107
|
def initialize options = {}
|
94
|
-
@target_type = options
|
108
|
+
@target_type = resolve_type options
|
95
109
|
@target_object = options[:object]
|
96
110
|
@method_name = options[:method_name] || options[:method]
|
97
111
|
class_method = options[:class_method].nil? ? false : options[:class_method]
|
@@ -143,24 +157,26 @@ module Aquarium
|
|
143
157
|
new_jp
|
144
158
|
end
|
145
159
|
|
160
|
+
# Needed for comparing this field in #compare_field
|
161
|
+
def instance_method
|
162
|
+
@instance_method
|
163
|
+
end
|
164
|
+
|
146
165
|
# We require the same object id, not just equal objects.
|
147
166
|
def <=> other
|
148
167
|
return 0 if object_id == other.object_id
|
149
168
|
return 1 if other.nil?
|
150
|
-
result = self.class <=> other.class
|
151
|
-
return result unless result == 0
|
152
|
-
result = (self.target_type.nil? and other.target_type.nil?) ? 0 : self.target_type.to_s <=> other.target_type.to_s
|
169
|
+
result = self.class <=> other.class
|
153
170
|
return result unless result == 0
|
154
|
-
result = (
|
171
|
+
result = compare_field(:target_object, other) {|f1,f2| f1.object_id <=> f2.object_id}
|
155
172
|
return result unless result == 0
|
156
|
-
result = (
|
173
|
+
result = compare_field(:instance_method, other) {|f1,f2| boolean_compare(f1,f2)}
|
157
174
|
return result unless result == 0
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
return self.context <=> other.context
|
175
|
+
[:target_type, :method_name, :context].each do |field|
|
176
|
+
result = compare_field field, other
|
177
|
+
return result unless result == 0
|
178
|
+
end
|
179
|
+
0
|
164
180
|
end
|
165
181
|
|
166
182
|
def eql? other
|
@@ -179,9 +195,37 @@ module Aquarium
|
|
179
195
|
|
180
196
|
protected
|
181
197
|
|
198
|
+
def compare_field field_reader, other
|
199
|
+
field1 = self.method(field_reader).call
|
200
|
+
field2 = other.method(field_reader).call
|
201
|
+
if field1.nil?
|
202
|
+
return field2.nil? ? 0 : -1
|
203
|
+
else
|
204
|
+
return 1 if field2.nil?
|
205
|
+
end
|
206
|
+
block_given? ? (yield field1, field2) : (field1 <=> field2)
|
207
|
+
end
|
208
|
+
|
209
|
+
def boolean_compare b1, b2
|
210
|
+
return 0 if b1 == b2
|
211
|
+
return b1 == true ? 1 : -1
|
212
|
+
end
|
213
|
+
|
214
|
+
def resolve_type options
|
215
|
+
type = options[:type]
|
216
|
+
return type if type.nil? # okay, if they specified an object!
|
217
|
+
return type if type.kind_of? Module
|
218
|
+
found = Aquarium::Finders::TypeFinder.new.find :type => type
|
219
|
+
if found.matched.empty?
|
220
|
+
bad_attributes("No type matched the string or regular expression: #{type}", options)
|
221
|
+
elsif found.matched.size > 1
|
222
|
+
bad_attributes("More than one type matched the string or regular expression: #{type}", options)
|
223
|
+
end
|
224
|
+
found.matched.keys.first
|
225
|
+
end
|
226
|
+
|
182
227
|
# Since JoinPoints can be declared for non-existent methods, tolerate "nil" for the visibility.
|
183
|
-
def assert_valid options
|
184
|
-
error_message = ""
|
228
|
+
def assert_valid options, error_message = ""
|
185
229
|
error_message << "Must specify a :method_name. " unless method_name
|
186
230
|
error_message << "Must specify either a :type or :object. " unless (target_type or target_object)
|
187
231
|
error_message << "Can't specify both a :type or :object. " if (target_type and target_object)
|
@@ -158,8 +158,10 @@ module Aquarium
|
|
158
158
|
# Exclude the specified types and their descendents, ancestors.
|
159
159
|
# If you want to exclude both the descendents _and_ ancestors, use both options.
|
160
160
|
#
|
161
|
+
# Pointcut.new also accepts all the "universal" options documented in OptionsUtils.
|
161
162
|
def initialize options = {}
|
162
|
-
init_specification options,
|
163
|
+
init_specification options, CANONICAL_OPTIONS
|
164
|
+
return if noop
|
163
165
|
init_candidate_types
|
164
166
|
init_candidate_objects
|
165
167
|
init_candidate_join_points
|
@@ -177,8 +179,8 @@ module Aquarium
|
|
177
179
|
candidate_types == other.candidate_types &&
|
178
180
|
candidate_types_excluded == other.candidate_types_excluded &&
|
179
181
|
candidate_objects == other.candidate_objects &&
|
180
|
-
|
181
|
-
|
182
|
+
join_points_not_matched == other.join_points_not_matched &&
|
183
|
+
join_points_matched == other.join_points_matched) # not_matched is probably smaller, so do first.
|
182
184
|
end
|
183
185
|
|
184
186
|
alias :== :eql?
|
@@ -220,9 +222,6 @@ module Aquarium
|
|
220
222
|
|
221
223
|
ALL_ALLOWED_OPTION_SYMBOLS = ALL_ALLOWED_OPTIONS.map {|o| o.intern}
|
222
224
|
|
223
|
-
def canonical_options
|
224
|
-
CANONICAL_OPTIONS
|
225
|
-
end
|
226
225
|
def all_allowed_option_symbols
|
227
226
|
ALL_ALLOWED_OPTION_SYMBOLS
|
228
227
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# A simple Design by Contract module. Adds advice to test that the contract, which is specified with
|
2
2
|
# a block passes. Note that it doesn't attempt to handle the correct behavior under contract
|
3
|
-
# inheritance
|
3
|
+
# inheritance.
|
4
4
|
# Warning: This module automatically includes Aquarium::Aspects::DSL::AspectDSL into the class with
|
5
5
|
# the contract and it adds the :precondition, :postcondition, and the :invariant methods to Object!
|
6
6
|
require 'aquarium'
|
@@ -90,7 +90,7 @@ module Aquarium
|
|
90
90
|
# +Derived+ class that is defined in the +Base+ class, you won't find it!
|
91
91
|
#
|
92
92
|
def find options = {}
|
93
|
-
init_specification options,
|
93
|
+
init_specification options, CANONICAL_OPTIONS
|
94
94
|
return Aquarium::Finders::FinderResult.new if nothing_to_find?
|
95
95
|
types_and_objects = input_types + input_objects
|
96
96
|
method_names_or_regexps = input_methods
|
@@ -126,9 +126,6 @@ module Aquarium
|
|
126
126
|
|
127
127
|
ALL_ALLOWED_OPTION_SYMBOLS = ALL_ALLOWED_OPTIONS.map {|o| o.intern}
|
128
128
|
|
129
|
-
def canonical_options
|
130
|
-
CANONICAL_OPTIONS
|
131
|
-
end
|
132
129
|
def all_allowed_option_symbols
|
133
130
|
ALL_ALLOWED_OPTION_SYMBOLS
|
134
131
|
end
|
@@ -14,6 +14,8 @@ module Aquarium
|
|
14
14
|
include Aquarium::Utils::ArrayUtils
|
15
15
|
include Aquarium::Utils::TypeUtils
|
16
16
|
|
17
|
+
TYPES_SYNONYMS = %w[name names type types]
|
18
|
+
|
17
19
|
# Usage:
|
18
20
|
# finder_result = TypeFinder.new.find [options => [...] ]
|
19
21
|
# where
|
@@ -88,11 +90,13 @@ module Aquarium
|
|
88
90
|
# Note: a common idiom in aspects is to include descendents of a type, but not the type
|
89
91
|
# itself. You can do as in the following example:
|
90
92
|
# <tt>... :type_and_descendents => "Foo", :exclude_type => "Foo"
|
93
|
+
# TODO: Use the new OptionsUtils.
|
91
94
|
def find options = {}
|
92
95
|
result = Aquarium::Finders::FinderResult.new
|
93
96
|
excluded = Aquarium::Finders::FinderResult.new
|
94
97
|
unknown_options = []
|
95
98
|
input_type_nil = false
|
99
|
+
noop = false
|
96
100
|
options.each do |option, value|
|
97
101
|
unless TypeFinder.is_recognized_option option
|
98
102
|
unknown_options << option
|
@@ -102,6 +106,8 @@ module Aquarium
|
|
102
106
|
input_type_nil = true
|
103
107
|
next
|
104
108
|
end
|
109
|
+
noop = value if option == :noop
|
110
|
+
next if noop
|
105
111
|
if option.to_s =~ /^exclude_/
|
106
112
|
excluded << find_matching(value, option)
|
107
113
|
else
|
@@ -122,11 +128,12 @@ module Aquarium
|
|
122
128
|
end
|
123
129
|
|
124
130
|
def self.is_recognized_option option_or_symbol
|
125
|
-
|
131
|
+
TYPES_SYNONYMS.each do |t|
|
126
132
|
['', "exclude_"].each do |excl|
|
127
133
|
return true if ["#{excl}#{t}", "#{excl}#{t}_and_descendents", "#{excl}#{t}_and_ancestors"].include?(option_or_symbol.to_s)
|
128
134
|
end
|
129
135
|
end
|
136
|
+
return true if option_or_symbol.to_s.eql?("noop")
|
130
137
|
false
|
131
138
|
end
|
132
139
|
|
data/lib/aquarium/utils.rb
CHANGED
@@ -6,6 +6,7 @@ require 'aquarium/utils/method_utils'
|
|
6
6
|
require 'aquarium/utils/name_utils'
|
7
7
|
require 'aquarium/utils/options_utils'
|
8
8
|
|
9
|
+
require 'aquarium/utils/default_logger'
|
9
10
|
require 'aquarium/utils/html_escaper'
|
10
11
|
require 'aquarium/utils/invalid_options'
|
11
12
|
require 'aquarium/utils/logic_error'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Aquarium
|
4
|
+
module Utils
|
5
|
+
# DefaultLogger holds the Aquarium-wide "default" Ruby standard library logger.
|
6
|
+
# Individual objects may chose to create their own loggers.
|
7
|
+
module DefaultLogger
|
8
|
+
|
9
|
+
@@default_logger = Logger.new STDERR
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
@@default_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.logger= logger
|
16
|
+
@@default_logger = logger
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|