aquarium 0.4.2 → 0.4.3

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.
Files changed (45) hide show
  1. data/CHANGES +27 -0
  2. data/{MIT-LICENSE → MIT_LICENSE} +0 -0
  3. data/Rakefile +1 -1
  4. data/examples/aspect_design_example.rb +0 -0
  5. data/examples/design_by_contract_example.rb +0 -0
  6. data/examples/exception_wrapping_example.rb +0 -0
  7. data/examples/introductions_example_spec.rb +1 -1
  8. data/examples/method_missing_example.rb +0 -0
  9. data/examples/method_tracing_example.rb +0 -0
  10. data/examples/reusable_aspect_hack_example.rb +0 -0
  11. data/lib/aquarium.rb +1 -0
  12. data/lib/aquarium/extras/design_by_contract.rb +21 -1
  13. data/lib/aquarium/finders/method_finder.rb +28 -8
  14. data/lib/aquarium/finders/type_finder.rb +18 -11
  15. data/lib/aquarium/version.rb +1 -1
  16. data/spec/aquarium/aspects/advice_chain_node_spec.rb +1 -1
  17. data/spec/aquarium/aspects/advice_spec.rb +1 -1
  18. data/spec/aquarium/aspects/aspect_invocation_spec.rb +3 -3
  19. data/spec/aquarium/aspects/aspect_spec.rb +1 -2
  20. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +1 -1
  21. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +1 -1
  22. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +2 -2
  23. data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +2 -2
  24. data/spec/aquarium/aspects/join_point_spec.rb +1 -2
  25. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +1 -1
  26. data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +1 -1
  27. data/spec/aquarium/aspects/pointcut_spec.rb +2 -2
  28. data/spec/aquarium/dsl/aspect_dsl_spec.rb +1 -1
  29. data/spec/aquarium/extensions/hash_spec.rb +1 -1
  30. data/spec/aquarium/extensions/set_spec.rb +1 -1
  31. data/spec/aquarium/extras/design_by_contract_spec.rb +26 -0
  32. data/spec/aquarium/finders/finder_result_spec.rb +1 -1
  33. data/spec/aquarium/finders/method_finder_spec.rb +65 -9
  34. data/spec/aquarium/finders/type_finder_spec.rb +0 -0
  35. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +1 -1
  36. data/spec/aquarium/finders/{type_finder_with_nested_types.rb → type_finder_with_nested_types_spec.rb} +5 -5
  37. data/spec/aquarium/spec_helper.rb +2 -1
  38. data/spec/aquarium/utils/array_utils_spec.rb +0 -0
  39. data/spec/aquarium/utils/hash_utils_spec.rb +1 -1
  40. data/spec/aquarium/utils/logic_error_spec.rb +1 -1
  41. data/spec/aquarium/utils/name_utils_spec.rb +1 -1
  42. data/spec/aquarium/utils/nil_object_spec.rb +1 -1
  43. data/spec/aquarium/utils/set_utils_spec.rb +5 -2
  44. data/spec/aquarium/utils/type_utils_spec.rb +4 -4
  45. metadata +7 -7
data/CHANGES CHANGED
@@ -1,3 +1,30 @@
1
+ == Version 0.4.3
2
+
3
+ V0.4.3 adds a few bug fixes and enhancements, and several internal refactorings to improve
4
+ performance, etc.
5
+
6
+ Bug fixes:
7
+ [none]
8
+
9
+ Enhancements:
10
+ 14165 Support Ruby 1.8.2, 1.8.5, 1.8.6, 1.9.X and 2.0 releases and snapshots
11
+ 21283 Allow "_of" suffix at end of "*_and_descendents", "*_and_ancestors", and "*_nested_types"
12
+ 21924 Should be able to turn off contract-testing aspects globally in the Design by Contract extra module
13
+ 21993 By default, don't advise "system" methods that being with "_", but provide an option to do so
14
+
15
+ 14165: I closed this one because it's too broad. Aquarium currently runs with 1.8.6. I will open a
16
+ new enhancement specifically for 1.9.
17
+ 21283: Sometimes appending "_of" makes the specification read more smoothly, so it's now an option.
18
+ 21924: To class-level methods in DesignByContract, enable_all and disable_all, globally turn contracts
19
+ on or off. See their documentation for details.
20
+ 21993: Now, by default, MethodFinder won't match any method that starts with two underscores ("__"), so
21
+ you don't have to :exclude_ancestors as much just to avoid matching methods like "__id__" and
22
+ "__send__". There is also a new :method_options called :include_system_methods that will not suppress
23
+ matching these methods. So, I'm calling these special methods "system methods". I don't yet provide a
24
+ way to configure this list (RSpec methods would be good additions...). The list is currently defined
25
+ as an array of regex's, MethodFinder::IGNORED_SYSTEM_METHODS. NOTE: This is effectively a behavior
26
+ change, although it's not likely to affect anyone.
27
+
1
28
  == Version 0.4.2
2
29
 
3
30
  V0.4.2 adds a few bug fixes and enhancements, greatly improved RDoc output, and internal
File without changes
data/Rakefile CHANGED
@@ -65,7 +65,7 @@ desc 'Generate RDoc'
65
65
  rd = Rake::RDocTask.new do |rdoc|
66
66
  rdoc.rdoc_dir = '../doc/output/rdoc'
67
67
  rdoc.options << '--title' << 'Aquarium' << '--line-numbers' << '--inline-source' << '--main' << 'README'
68
- rdoc.rdoc_files.include('README', 'CHANGES', 'MIT-LICENSE', 'examples/**/*.rb', 'UPGRADE', 'lib/**/*.rb') # 'EXAMPLES.rd'
68
+ rdoc.rdoc_files.include('README', 'CHANGES', 'MIT_LICENSE', 'examples/**/*.rb', 'UPGRADE', 'lib/**/*.rb') # 'EXAMPLES.rd'
69
69
  end
70
70
 
71
71
  # desc "Generate EXAMPLES.rb"
File without changes
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../spec/aquarium/spec_helper'
2
2
  require 'aquarium'
3
3
 
4
- # Example demonstrating how to use the TypeFinder class to convenient "introduce" new
4
+ # Example demonstrating how to use the TypeFinder class to conveniently "introduce" new
5
5
  # methods and attributes in a set of types, like you might do with AspectJ in Java.
6
6
  # Of course, in Ruby, you can simply use Object#extend(module). However, if you want to
7
7
  # do this in a cross-cutting way, TypeFinder. is convenient.
File without changes
File without changes
File without changes
@@ -1,4 +1,5 @@
1
1
  # Does not include 'aquarium/extras'. Users have to include it explicitly if they want it.
2
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/..')
2
3
  require 'aquarium/utils'
3
4
  require 'aquarium/extensions'
4
5
  require 'aquarium/finders'
@@ -9,6 +9,9 @@ module Aquarium
9
9
  # a block passes. Note that it doesn't attempt to handle the correct behavior under contract
10
10
  # inheritance. A usage example is included in the Examples as part of the distribution and it is also
11
11
  # shown on the web site.
12
+ # Normally, you want to disable the contracts in production runs, so you avoid the overhead. To do this
13
+ # effectively, call DesignByContract.disable_all before any contracts are created. That will prevent
14
+ # all of the aspects from being created along with their overhead.
12
15
  # *Warning*: This module automatically includes Aquarium::DSL into the class with
13
16
  # the contract and it adds the :precondition, :postcondition, and the :invariant methods to Object!
14
17
  module DesignByContract
@@ -20,17 +23,34 @@ module Aquarium
20
23
  end
21
24
  end
22
25
 
26
+ @@enabled = true
27
+
28
+ # Enable creation and execution of contracts
29
+ def self.enable_all
30
+ @@enabled = true
31
+ end
32
+
33
+ # Disable creation of any subsequent contracts and disable execution of
34
+ # existing contracts. That is, while contracts are disabled, it no existing
35
+ # contracts will be executed and any attempts to define new contracts will be ignored.
36
+ def self.disable_all
37
+ @@enabled = false
38
+ end
39
+
23
40
  def precondition *args, &contract_block
41
+ return unless @@enabled
24
42
  message = handle_message_arg args
25
43
  add_advice :before, "precondition", message, *args, &contract_block
26
44
  end
27
45
 
28
46
  def postcondition *args, &contract_block
47
+ return unless @@enabled
29
48
  message = handle_message_arg args
30
49
  add_advice :after_returning, "postcondition", message, *args, &contract_block
31
50
  end
32
51
 
33
52
  def invariant *args, &contract_block
53
+ return unless @@enabled
34
54
  message = handle_message_arg args
35
55
  Aspect.new make_args(:around, *args) do |jp, obj, *params|
36
56
  DesignByContract.test_condition "invariant failure (before invocation): #{message}", jp, obj, *params, &contract_block
@@ -43,7 +63,7 @@ module Aquarium
43
63
  private
44
64
 
45
65
  def self.test_condition message, jp, obj, *args
46
- unless yield(jp, obj, *args)
66
+ if @@enabled and yield(jp, obj, *args) == false
47
67
  raise ContractError.new(message)
48
68
  end
49
69
  end
@@ -1,10 +1,10 @@
1
1
  require 'set'
2
- require File.dirname(__FILE__) + '/../utils/array_utils'
3
- require File.dirname(__FILE__) + '/../utils/invalid_options'
4
- require File.dirname(__FILE__) + '/../utils/set_utils'
5
- require File.dirname(__FILE__) + '/../utils/type_utils'
6
- require File.dirname(__FILE__) + '/../utils/options_utils'
7
- require File.dirname(__FILE__) + '/finder_result'
2
+ require 'aquarium/utils/array_utils'
3
+ require 'aquarium/utils/set_utils'
4
+ require 'aquarium/utils/type_utils'
5
+ require 'aquarium/utils/options_utils'
6
+ require 'aquarium/utils/invalid_options'
7
+ require 'aquarium/finders/finder_result'
8
8
 
9
9
  # Find methods and types and objects.
10
10
  module Aquarium
@@ -74,6 +74,7 @@ module Aquarium
74
74
  # <tt>:instance</tt> or <tt>:instance_methods</tt>:: Search for instance methods.
75
75
  # <tt>:class</tt> or <tt>:class_methods</tt>:: Search for class methods.
76
76
  # <tt>:singleton</tt> or <tt>:singleton_methods</tt>:: Search for singleton methods.
77
+ # <tt>:include_system_methods</tt>:: Also search for "system" methods like __id__ that are normally ignored (See IGNORED_SYSTEM_MEHTODS).
77
78
  #
78
79
  # Note: specifying <tt>:class</tt> when objects are specified won't work.
79
80
  # Also, <tt>:class</tt>, <tt>:public</tt>, <tt>:protected</tt>, and <tt>:private</tt>
@@ -139,9 +140,14 @@ module Aquarium
139
140
  "instance" => %w[instance_methods],
140
141
  "class" => %w[class_methods],
141
142
  "singleton" => %w[singleton_methods],
142
- "exclude_ancestor_methods" => %w[exclude_ancestors exclude_ancestors_methods suppress_ancestors suppress_ancestor_methods suppress_ancestors_methods]
143
+ "exclude_ancestor_methods" => %w[exclude_ancestors exclude_ancestors_methods suppress_ancestors suppress_ancestor_methods suppress_ancestors_methods],
144
+ "include_system_methods" => %w[include_all_system_methods]
143
145
  }
144
-
146
+
147
+ # Methods we ignore by default, because users rarely want to advice them and so it makes
148
+ # finding what you want easier.
149
+ IGNORED_SYSTEM_METHODS = [/^__/]
150
+
145
151
  def self.init_method_options scope_options_set
146
152
  return Set.new([]) if scope_options_set.nil?
147
153
  options = []
@@ -196,6 +202,8 @@ module Aquarium
196
202
  end
197
203
  found_methods += method_array
198
204
  end
205
+ filter_ignored_methods(found_methods) unless include_system_methods?
206
+
199
207
  if found_methods.empty?
200
208
  types_and_objects_not_matched[type_or_object] = method_names_or_regexps
201
209
  else
@@ -205,6 +213,14 @@ module Aquarium
205
213
  Aquarium::Finders::FinderResult.new types_and_objects_to_matched_methods.merge(:not_matched => types_and_objects_not_matched)
206
214
  end
207
215
 
216
+ def filter_ignored_methods found_methods
217
+ IGNORED_SYSTEM_METHODS.each do |ism|
218
+ found_methods.reject! do |m|
219
+ m.match(ism)
220
+ end
221
+ end
222
+ end
223
+
208
224
  def finish_specification_initialization
209
225
  @specification[:method_options] = MethodFinder.init_method_options(@specification[:method_options]) if @specification[:method_options]
210
226
  extra_validation
@@ -318,6 +334,10 @@ module Aquarium
318
334
  end
319
335
  end
320
336
 
337
+ def include_system_methods?
338
+ @specification[:method_options].include?(:include_system_methods)
339
+ end
340
+
321
341
  def extra_validation
322
342
  method_options = @specification[:method_options]
323
343
  return if method_options.nil?
@@ -1,11 +1,11 @@
1
1
  require 'set'
2
- require File.dirname(__FILE__) + '/../utils/array_utils'
3
- require File.dirname(__FILE__) + '/../utils/type_utils'
4
- require File.dirname(__FILE__) + '/../utils/invalid_options'
5
- require File.dirname(__FILE__) + '/../extensions/hash'
6
- require File.dirname(__FILE__) + '/../extensions/regexp'
7
- require File.dirname(__FILE__) + '/../extensions/symbol'
8
- require File.dirname(__FILE__) + '/finder_result'
2
+ require 'aquarium/utils/array_utils'
3
+ require 'aquarium/utils/type_utils'
4
+ require 'aquarium/utils/invalid_options'
5
+ require 'aquarium/extensions/hash'
6
+ require 'aquarium/extensions/regexp'
7
+ require 'aquarium/extensions/symbol'
8
+ require 'aquarium/finders/finder_result'
9
9
 
10
10
  # Finds types known to the runtime environment.
11
11
  module Aquarium
@@ -26,10 +26,12 @@ module Aquarium
26
26
 
27
27
  def self.add_ancestors_descendents_and_nested_option_variants_for option, options_hash
28
28
  all_variants = options_hash[option].dup
29
- options_hash["#{option}_and_descendents"] = all_variants.map {|x| "#{x}_and_descendents"}
30
- options_hash["#{option}_and_ancestors"] = all_variants.map {|x| "#{x}_and_ancestors"}
31
- options_hash["#{option}_and_nested_types"] =
32
- all_variants.map {|x| "#{x}_and_nested_types"} + all_variants.map {|x| "#{x}_and_nested"}
29
+ %w[descendents ancestors nested_types].each do |suffix|
30
+ options_hash["#{option}_and_#{suffix}"] = all_variants.inject([]) do |memo, x|
31
+ memo << "#{x}_and_#{suffix}" << "#{x}_and_#{suffix}_of"
32
+ end
33
+ end
34
+ options_hash["#{option}_and_nested_types"] += all_variants.map {|x| "#{x}_and_nested"}
33
35
  end
34
36
 
35
37
  TYPE_FINDER_CANONICAL_OPTIONS = {
@@ -73,6 +75,7 @@ module Aquarium
73
75
  # * <tt>:names_and_descendents => types_and_type_names_and_regexps</tt>
74
76
  # * <tt>:type_and_descendents => types_and_type_names_and_regexps</tt>
75
77
  # * <tt>:name_and_descendents => types_and_type_names_and_regexps</tt>
78
+ # You can also append the suffix "_of" on any of these keys.
76
79
  #
77
80
  # ==== Types and Ancestors
78
81
  # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
@@ -81,6 +84,7 @@ module Aquarium
81
84
  # * <tt>:names_and_ancestors => types_and_type_names_and_regexps</tt>
82
85
  # * <tt>:type_and_ancestors => types_and_type_names_and_regexps</tt>
83
86
  # * <tt>:name_and_ancestors => types_and_type_names_and_regexps</tt>
87
+ # You can also append the suffix "_of" on any of these keys.
84
88
  #
85
89
  # ==== Types and Nested Types
86
90
  # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
@@ -93,6 +97,7 @@ module Aquarium
93
97
  # * <tt>:names_and_nested => types_and_type_names_and_regexps</tt>
94
98
  # * <tt>:type_and_nested => types_and_type_names_and_regexps</tt>
95
99
  # * <tt>:name_and_nested => types_and_type_names_and_regexps</tt>
100
+ # You can also append the suffix "_of" on any of the "*_types" keys.
96
101
  #
97
102
  # Note: This option will also match <tt>Class</tt>, <tt>Module</tt>, <i>etc.</>,
98
103
  # so use with caution!
@@ -123,6 +128,8 @@ module Aquarium
123
128
  # * <tt>:exclude_names_and_nested => types_and_type_names_and_regexps</tt>
124
129
  # * <tt>:exclude_type_and_nested => types_and_type_names_and_regexps</tt>
125
130
  # * <tt>:exclude_name_and_nested => types_and_type_names_and_regexps</tt>
131
+ # You can also append the suffix "_of" on any of the "*_descendents", "*_ancestors",
132
+ # and "*_types" keys.
126
133
  #
127
134
  # ==== Namespaces (Modules) and Regular Expressions
128
135
  # Because of the special sigificance of the module ("namespace") separator "::",
@@ -9,7 +9,7 @@ module Aquarium
9
9
  unless defined? MAJOR
10
10
  MAJOR = 0
11
11
  MINOR = 4
12
- TINY = 2
12
+ TINY = 3
13
13
  RELEASE_CANDIDATE = nil
14
14
 
15
15
  # RANDOM_TOKEN: 0.598704893979657
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium'
4
4
 
5
5
  include Aquarium::Aspects::Advice
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/aspects/advice'
4
4
  require 'aquarium/aspects/aspect'
5
5
  include Aquarium::Aspects
@@ -1,10 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
3
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_nested_types'
2
+ require 'aquarium/spec_example_types'
3
+ require 'aquarium/utils/type_utils_sample_nested_types'
4
4
  require 'aquarium/aspects/aspect'
5
5
  require 'aquarium/dsl'
6
6
  require 'aquarium/utils/array_utils'
7
- require File.dirname(__FILE__) + '/../finders/pointcut_finder_spec_test_classes'
7
+ require 'aquarium/finders/pointcut_finder_spec_test_classes'
8
8
 
9
9
  require 'profiler'
10
10
 
@@ -1,6 +1,5 @@
1
-
2
1
  require File.dirname(__FILE__) + '/../spec_helper'
3
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
4
3
  require 'aquarium/aspects'
5
4
  require 'logger'
6
5
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  require File.dirname(__FILE__) + '/../spec_helper'
3
- require File.dirname(__FILE__) + '/../spec_example_types'
3
+ require 'aquarium/spec_example_types'
4
4
  require 'aquarium/aspects'
5
5
 
6
6
  include Aquarium::Aspects
@@ -1,6 +1,6 @@
1
1
 
2
2
  require File.dirname(__FILE__) + '/../spec_helper'
3
- require File.dirname(__FILE__) + '/../spec_example_types'
3
+ require 'aquarium/spec_example_types'
4
4
  require 'aquarium/aspects'
5
5
 
6
6
  include Aquarium::Aspects
@@ -1,8 +1,8 @@
1
1
  # Specifically tests behavior when two or more advices apply to the same join point(s).
2
2
 
3
3
  require File.dirname(__FILE__) + '/../spec_helper'
4
- require File.dirname(__FILE__) + '/../spec_example_types'
5
- require File.dirname(__FILE__) + '/concurrently_accessed'
4
+ require 'aquarium/spec_example_types'
5
+ require 'aquarium/aspects/concurrently_accessed'
6
6
  require 'aquarium/aspects'
7
7
 
8
8
  include Aquarium::Aspects
@@ -2,8 +2,8 @@
2
2
  # where one advice is for the type and the other is for an object of the type.
3
3
 
4
4
  require File.dirname(__FILE__) + '/../spec_helper'
5
- require File.dirname(__FILE__) + '/../spec_example_types'
6
- require File.dirname(__FILE__) + '/concurrently_accessed'
5
+ require 'aquarium/spec_example_types'
6
+ require 'aquarium/aspects/concurrently_accessed'
7
7
  require 'aquarium/aspects'
8
8
 
9
9
  include Aquarium::Aspects
@@ -1,6 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
3
-
2
+ require 'aquarium/spec_example_types'
4
3
  require 'aquarium/extensions/hash'
5
4
  require 'aquarium/utils/nil_object'
6
5
  require 'aquarium/aspects/join_point'
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils'
4
4
  require 'aquarium/extensions'
5
5
  require 'aquarium/aspects/pointcut'
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils'
4
4
  require 'aquarium/extensions'
5
5
  require 'aquarium/aspects/pointcut'
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
3
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_nested_types'
2
+ require 'aquarium/spec_example_types'
3
+ require 'aquarium/utils/type_utils_sample_nested_types'
4
4
  require 'aquarium/utils/invalid_options'
5
5
  require 'aquarium/extensions/hash'
6
6
  require 'aquarium/aspects/join_point'
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/dsl/aspect_dsl'
4
4
 
5
5
  class DSLClass
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/extensions/hash'
4
4
  require 'aquarium/utils/array_utils'
5
5
  require 'aquarium/utils/hash_utils'
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/extensions/set'
4
4
 
5
5
  class Foo
@@ -75,3 +75,29 @@ describe Aquarium::Extras::DesignByContract, "invariant" do
75
75
  InvarCond.new.good_action.should == "good"
76
76
  end
77
77
  end
78
+
79
+ describe Aquarium::Extras::DesignByContract, "global enable/disable option" do
80
+ class ContractEnablement
81
+ include Aquarium::Extras::DesignByContract
82
+ def action *args
83
+ end
84
+
85
+ precondition :method => :action, :message => "Must pass more than one argument." do |jp, obj, *args|
86
+ args.size > 0
87
+ end
88
+ end
89
+
90
+ it "should disable creation of the contract aspects when the contracts are disabled" do
91
+ begin
92
+ Aquarium::Extras::DesignByContract.disable_all
93
+ lambda { ContractEnablement.new.action }.should_not raise_error(Aquarium::Extras::DesignByContract::ContractError)
94
+ ensure
95
+ Aquarium::Extras::DesignByContract.enable_all
96
+ end
97
+ end
98
+
99
+ it "should enable creation of the contract aspects when the contracts are enabled" do
100
+ Aquarium::Extras::DesignByContract.enable_all
101
+ lambda { ContractEnablement.new.action }.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
102
+ end
103
+ end
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
 
4
4
  require 'aquarium/finders/finder_result'
5
5
  require 'aquarium/extensions/set'
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/finders/method_finder'
4
4
 
5
5
  # :stopdoc:
@@ -327,6 +327,8 @@ end
327
327
  describe Aquarium::Finders::MethodFinder, "#find (searching for class methods)" do
328
328
  before(:each) do
329
329
  before_method_finder_spec
330
+ @expected_ClassWithPUblicClassMethod = Set.new(ClassWithPublicClassMethod.public_methods.reject{|m| m =~ /^__/}.sort.map{|m| m.intern})
331
+ @expected_ClassWithPrivateClassMethod = Set.new(ClassWithPrivateClassMethod.public_methods.reject{|m| m =~ /^__/}.sort.map{|m| m.intern})
330
332
  end
331
333
 
332
334
  it "should find all class methods specified by regular expression for types when :class is used." do
@@ -344,20 +346,36 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for class methods)"
344
346
  end
345
347
  end
346
348
 
349
+ it "should ignore any methods that start with double underscores '__' by default when searching with the :all method specification and the :class option." do
350
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicClassMethod, ClassWithPrivateClassMethod], :methods => :all, :method_options => :class
351
+ actual.matched.size.should == 2
352
+ actual.not_matched.size.should == 0
353
+ actual.matched[ClassWithPublicClassMethod].should == @expected_ClassWithPUblicClassMethod
354
+ actual.matched[ClassWithPrivateClassMethod].should == @expected_ClassWithPrivateClassMethod
355
+ end
356
+
357
+ it "should find any methods that start with double underscores '__' with the :include_system_methods option." do
358
+ class WithUnderScores
359
+ def self.__foo__; end
360
+ end
361
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [WithUnderScores], :methods => :all, :method_options => [:class, :include_system_methods]
362
+ actual.matched[WithUnderScores].include?(:__foo__).should be_true
363
+ end
364
+
347
365
  it "should find all public class methods in types when searching with the :all method specification and the :class option." do
348
366
  actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicClassMethod, ClassWithPrivateClassMethod], :methods => :all, :method_options => :class
349
367
  actual.matched.size.should == 2
350
368
  actual.not_matched.size.should == 0
351
- actual.matched[ClassWithPublicClassMethod].should == Set.new(ClassWithPublicClassMethod.public_methods.sort.map{|m| m.intern})
352
- actual.matched[ClassWithPrivateClassMethod].should == Set.new(ClassWithPrivateClassMethod.public_methods.sort.map{|m| m.intern})
369
+ actual.matched[ClassWithPublicClassMethod].should == @expected_ClassWithPUblicClassMethod
370
+ actual.matched[ClassWithPrivateClassMethod].should == @expected_ClassWithPrivateClassMethod
353
371
  end
354
372
 
355
373
  it "should accept :all_methods as a synonym for :all." do
356
374
  actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicClassMethod, ClassWithPrivateClassMethod], :methods => :all_methods, :method_options => :class
357
375
  actual.matched.size.should == 2
358
376
  actual.not_matched.size.should == 0
359
- actual.matched[ClassWithPublicClassMethod].should == Set.new(ClassWithPublicClassMethod.public_methods.sort.map{|m| m.intern})
360
- actual.matched[ClassWithPrivateClassMethod].should == Set.new(ClassWithPrivateClassMethod.public_methods.sort.map{|m| m.intern})
377
+ actual.matched[ClassWithPublicClassMethod].should == @expected_ClassWithPUblicClassMethod
378
+ actual.matched[ClassWithPrivateClassMethod].should == @expected_ClassWithPrivateClassMethod
361
379
  end
362
380
 
363
381
  it "should find all public class methods in types, but not ancestors, when searching with the :all method specification and the :class and :exclude_ancestor_methods options." do
@@ -400,8 +418,8 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for class methods de
400
418
  it "should find all public class methods in types when searching with the :all method specification and the :class option." do
401
419
  actual = Aquarium::Finders::MethodFinder.new.find :type => [M, M2], :methods => :all, :method_options => [:class]
402
420
  actual.matched.size.should == 2
403
- actual.matched[M].should == Set.new(M.public_methods.sort.map{|m| m.intern})
404
- actual.matched[M2].should == Set.new(M2.public_methods.sort.map{|m| m.intern})
421
+ actual.matched[M].should == Set.new(M.public_methods.reject{|m| m =~ /^__/}.sort.map{|m| m.intern})
422
+ actual.matched[M2].should == Set.new(M2.public_methods.reject{|m| m =~ /^__/}.sort.map{|m| m.intern})
405
423
  end
406
424
 
407
425
  it "should not find any module-defined class methods in classes that include the modules." do
@@ -422,11 +440,27 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for instance methods
422
440
  before_method_finder_spec
423
441
  end
424
442
 
443
+ it "should ignore any methods that start with double underscores '__' by default when searching with the :all method specification and the :class option." do
444
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod], :methods => :all
445
+ actual.matched.size.should == 3
446
+ [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod].each do |c|
447
+ actual.matched[c].each {|m| m.to_s.match('^__').should be_nil}
448
+ end
449
+ end
450
+
451
+ it "should find any methods that start with double underscores '__' with the :include_system_methods option." do
452
+ class WithUnderScores
453
+ def __foo__; end
454
+ end
455
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [WithUnderScores], :methods => :all, :method_options => [:include_system_methods]
456
+ actual.matched[WithUnderScores].include?(:__foo__).should be_true
457
+ end
458
+
425
459
  it "should find all public instance methods in classes when searching with the :all method specification." do
426
460
  actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod], :methods => :all
427
461
  actual.matched.size.should == 3
428
462
  [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod].each do |c|
429
- actual.matched[c].should == Set.new(c.public_instance_methods.sort.map {|m| m.intern})
463
+ actual.matched[c].should == Set.new(c.public_instance_methods.reject{|m| m =~ /^__/}.sort.map {|m| m.intern})
430
464
  end
431
465
  end
432
466
 
@@ -444,7 +478,7 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for instance methods
444
478
  actual = Aquarium::Finders::MethodFinder.new.find :objects => [pub, pro, pri], :methods => :all
445
479
  actual.matched.size.should == 3
446
480
  [pub, pro, pri].each do |c|
447
- actual.matched[c].should == Set.new(c.public_methods.sort.map {|m| m.intern})
481
+ actual.matched[c].should == Set.new(c.public_methods.reject{|m| m =~ /^__/}.sort.map {|m| m.intern})
448
482
  end
449
483
  end
450
484
 
@@ -1078,6 +1112,28 @@ describe Aquarium::Finders::MethodFinder, "#find (using :method_options => [:pub
1078
1112
  end
1079
1113
  end
1080
1114
 
1115
+ describe Aquarium::Finders::MethodFinder, "#find (using :method_options => [:include_system_methods])" do
1116
+ before(:each) do
1117
+ before_method_finder_spec
1118
+ end
1119
+
1120
+ it "should find instance methods otherwise excluded by the MethodFinder::IGNORED_SYSTEM_METHODS list of regex's" do
1121
+ class WithIgnored
1122
+ def __foo__; end
1123
+ end
1124
+ actual = Aquarium::Finders::MethodFinder.new.find :class => WithIgnored, :methods => :all, :method_options => [:include_system_methods, :exclude_ancestor_methods]
1125
+ actual.matched[WithIgnored].should include(:__foo__)
1126
+ end
1127
+
1128
+ it "should find class methods otherwise excluded by the MethodFinder::IGNORED_SYSTEM_METHODS list of regex's" do
1129
+ class WithSelfIgnored
1130
+ def self.__self_foo__; end
1131
+ end
1132
+ actual = Aquarium::Finders::MethodFinder.new.find :class => WithSelfIgnored, :methods => :all, :method_options => [:include_system_methods, :class, :exclude_ancestor_methods]
1133
+ actual.matched[WithSelfIgnored].should include(:__self_foo__)
1134
+ end
1135
+ end
1136
+
1081
1137
  describe "Aquarium::Finders::MethodFinder#find (looking for singleton methods)" do
1082
1138
  before(:each) do
1083
1139
  class Empty
File without changes
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_classes'
2
+ require 'aquarium/utils/type_utils_sample_classes'
3
3
  require 'aquarium/finders/type_finder'
4
4
 
5
5
  include Aquarium::Utils
@@ -1,11 +1,11 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_classes'
3
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_nested_types'
2
+ require 'aquarium/utils/type_utils_sample_classes'
3
+ require 'aquarium/utils/type_utils_sample_nested_types'
4
4
  require 'aquarium/finders/type_finder'
5
5
 
6
6
  include Aquarium::Utils
7
7
 
8
- def purge_actuals actuals
8
+ def purge_uninteresting actuals
9
9
  # Remove extra stuff inserted by RSpec, Aquarium, and "pretty printer" (rake?), possibly in other specs!
10
10
  actuals.matched_keys.reject do |t2|
11
11
  t2.name.include?("Spec::") or t2.name =~ /Aquarium::(Utils|Extras|Examples|Aspects|PointcutFinderTestClasses)/ or t2.name =~ /^PP/
@@ -16,7 +16,7 @@ describe TypeUtils, "#find types and their nested types, using :types_and_nested
16
16
  it "should find the matching types and their nested types." do
17
17
  Aquarium::NestedTestTypes.nested_in_NestedTestTypes.keys.each do |t|
18
18
  actual = Aquarium::Finders::TypeFinder.new.find :types_and_nested_types => (t.name)
19
- actual_keys = purge_actuals actual
19
+ actual_keys = purge_uninteresting actual
20
20
  actual_keys.sort{|x,y| x.name <=> y.name}.should == Aquarium::NestedTestTypes.nested_in_NestedTestTypes[t].sort{|x,y| x.name <=> y.name}
21
21
  actual.not_matched_keys.should == []
22
22
  end
@@ -34,7 +34,7 @@ describe TypeUtils, "#find nested types subtracting out excluded types and desce
34
34
  actual = Aquarium::Finders::TypeFinder.new.find :types_and_nested_types => Aquarium::NestedTestTypes,
35
35
  :exclude_types_and_nested_types => Aquarium::NestedTestTypes::TopModule
36
36
  expected = [Aquarium::NestedTestTypes] + Aquarium::NestedTestTypes.nested_in_NestedTestTypes[Aquarium::NestedTestTypes::TopClass]
37
- actual_keys = purge_actuals actual
37
+ actual_keys = purge_uninteresting actual
38
38
  actual_keys.sort{|x,y| x.name <=> y.name}.should == expected.sort{|x,y| x.name <=> y.name}
39
39
  actual.not_matched_keys.should == []
40
40
  end
@@ -1,3 +1,4 @@
1
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../lib')
2
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/..')
2
3
  require 'rubygems'
3
4
  require 'spec'
File without changes
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils/hash_utils'
4
4
 
5
5
  describe Aquarium::Utils::HashUtils, "#make_hash" do
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils/logic_error'
4
4
 
5
5
  # This doesn't do much..., except make rcov happy, since this exception is essentially for catching bugs.
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils/name_utils'
4
4
 
5
5
  describe Aquarium::Utils::NameUtils, ".make_valid_attr_name_from_method_name" do
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils/nil_object'
4
4
 
5
5
  describe Aquarium::Utils::NilObject, "#eql?" do
@@ -1,9 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../spec_example_types'
2
+ require 'aquarium/spec_example_types'
3
3
  require 'aquarium/utils/set_utils'
4
4
 
5
5
  describe Aquarium::Utils::SetUtils, "make_set" do
6
-
6
+ include Aquarium::Utils::SetUtils
7
+
7
8
  before :each do
8
9
  @empty_set = Set.new
9
10
  end
@@ -60,6 +61,8 @@ describe Aquarium::Utils::SetUtils, "make_set" do
60
61
  end
61
62
 
62
63
  describe Aquarium::Utils::SetUtils, "strip_set_nils" do
64
+ include Aquarium::Utils::SetUtils
65
+
63
66
  it "should return an empty set if an empty set is specified" do
64
67
  strip_set_nils(Set.new([])).should == Set.new([])
65
68
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require 'aquarium/utils/type_utils'
3
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_classes'
4
- require File.dirname(__FILE__) + '/../utils/type_utils_sample_nested_types'
3
+ require 'aquarium/utils/type_utils_sample_classes'
4
+ require 'aquarium/utils/type_utils_sample_nested_types'
5
5
 
6
6
  include Aquarium::Utils
7
7
 
@@ -40,8 +40,8 @@ describe TypeUtils, ".descendents called with a class" do
40
40
  TypeUtils.descendents(Aquarium::ForDescendents::NestedD31ForDescendents).should eql([Aquarium::ForDescendents::NestedD31ForDescendents])
41
41
  end
42
42
 
43
- it "should return all classes and their descendents that derive from a class" do
44
- TypeUtils.sample_classes.each do |t|
43
+ TypeUtils.sample_classes.each do |t|
44
+ it "should return all classes and their descendents that derive from #{t}" do
45
45
  check_descendent_array t, TypeUtils.sample_classes_descendents[t]
46
46
  end
47
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aquarium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aquarium Development Team
@@ -9,7 +9,7 @@ autorequire: aquarium
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-25 00:00:00 -05:00
12
+ date: 2008-10-26 00:00:00 -05:00
13
13
  default_executable: ""
14
14
  dependencies: []
15
15
 
@@ -22,7 +22,7 @@ extensions: []
22
22
  extra_rdoc_files:
23
23
  - README
24
24
  - CHANGES
25
- - MIT-LICENSE
25
+ - MIT_LICENSE
26
26
  - UPGRADE
27
27
  files:
28
28
  - Aquarium-IDEA.ipr
@@ -31,7 +31,7 @@ files:
31
31
  - Aquarium.iws
32
32
  - CHANGES
33
33
  - EXAMPLES.rd
34
- - MIT-LICENSE
34
+ - MIT_LICENSE
35
35
  - ParseTreePlay.rb
36
36
  - Rakefile
37
37
  - README
@@ -104,7 +104,7 @@ files:
104
104
  - spec/aquarium/finders/pointcut_finder_spec_test_classes.rb
105
105
  - spec/aquarium/finders/type_finder_spec.rb
106
106
  - spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb
107
- - spec/aquarium/finders/type_finder_with_nested_types.rb
107
+ - spec/aquarium/finders/type_finder_with_nested_types_spec.rb
108
108
  - spec/aquarium/spec_example_types.rb
109
109
  - spec/aquarium/spec_helper.rb
110
110
  - spec/aquarium/utils/array_utils_spec.rb
@@ -165,9 +165,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
165
  requirements: []
166
166
 
167
167
  rubyforge_project: aquarium
168
- rubygems_version: 1.0.1
168
+ rubygems_version: 1.3.0
169
169
  signing_key:
170
170
  specification_version: 2
171
- summary: Aquarium-0.4.2 (r7) - Aspect-Oriented Programming toolkit for Ruby http://aquarium.rubyforge.org
171
+ summary: Aquarium-0.4.3 (r7) - Aspect-Oriented Programming toolkit for Ruby http://aquarium.rubyforge.org
172
172
  test_files: []
173
173