aquarium 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -414,15 +414,18 @@ Aquarium::Extras provides add-ons for Aquarium, such as a Design by Contract imp
414
414
 
415
415
  The simplest approach is to install the gem:
416
416
 
417
- gem install -y aquarium # sudo may be required on non-Windows systems
417
+ gem install -y aquarium # sudo may be required on non-Windows systems
418
418
 
419
419
  == Building the Aquarium gem
420
420
 
421
- If you prefer to build the gem locally, check out source from svn://rubyforge.org/var/svn/aquarium/trunk. Then
422
- do the following:
421
+ If you prefer to build the gem locally, clone from GitHub,
423
422
 
424
- rake gem
425
- gem install pkg/aquarium-x.y.z.gem # sudo may be required
423
+ git clone git://github.com/deanwampler/Aquarium.git
424
+
425
+ Then do the following:
426
+
427
+ rake gem
428
+ gem install pkg/aquarium-x.y.z.gem # sudo may be required
426
429
 
427
430
  == Running Aquarium's RSpec Specs
428
431
 
@@ -432,17 +435,16 @@ In order to run Aquarium's full suite of specs (rake pre_commit) you must instal
432
435
  * rspec # Used instead of Test::Unit for TDD
433
436
  * rcov # Verifies that the code is 100% covered by specs
434
437
  * webgen # Generates the static HTML website
435
- * RedCloth # Required by webgen
436
- * syntax # Required by RSpec's custom webgen extension to highlight ruby code
438
+ * coderay # Required by webgen
437
439
  * diff-lcs # Required if you use the --diff switch
438
440
  * win32console # Required by the --colour switch if you're on Windows
439
441
  * meta_project # Required in order to make releases at RubyForge
440
442
  * heckle # Required if you use the --heckle switch
441
- * jruby # Required if run the separate spec suite in the "jruby" directory
443
+ * jruby # Required if run the separate spec suite in the "jruby" directory (v1.3+)
442
444
 
443
445
  Once those are all installed, you should be able to run the suite with the following steps:
444
446
 
445
- * svn co svn://rubyforge.org/var/svn/aquarium/trunk aquarium
447
+ * git clone git://github.com/deanwampler/Aquarium.git
446
448
  * cd aquarium
447
449
  * rake spec
448
450
  or
data/Rakefile CHANGED
@@ -11,6 +11,8 @@ require 'aquarium/version'
11
11
  require 'spec/rake/spectask'
12
12
  require 'spec/rake/verify_rcov'
13
13
 
14
+ # TODO: add ../README.markdown to archives.
15
+
14
16
  # Some of the tasks are in separate files since they are also part of the website documentation
15
17
  load File.dirname(__FILE__) + '/rake_tasks/examples.rake'
16
18
  load File.dirname(__FILE__) + '/rake_tasks/verify_rcov.rake'
@@ -34,14 +36,14 @@ Spec::Rake::SpecTask.new do |t|
34
36
  t.spec_files = FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
35
37
  t.spec_opts = ['--options', 'spec.opts']
36
38
  t.rcov = true
37
- t.rcov_dir = '../doc/output/coverage'
39
+ t.rcov_dir = '../doc/aquarium/out/coverage'
38
40
  t.rcov_opts = ['--exclude', 'examples']
39
41
  end
40
42
 
41
- desc "Run all specs and store html output in doc/output/report.html"
43
+ desc "Run all specs and store html output in doc/aquarium/out/report.html"
42
44
  Spec::Rake::SpecTask.new('spec_html') do |t|
43
45
  t.spec_files = FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
44
- t.spec_opts = ['--format html:../doc/output/report.html','--backtrace']
46
+ t.spec_opts = ['--format html:../doc/aquarium/out/report.html','--backtrace']
45
47
  end
46
48
 
47
49
  desc "Run all specs without rcov"
@@ -52,7 +54,7 @@ end
52
54
 
53
55
  desc 'Generate HTML documentation for website'
54
56
  task :webgen do
55
- Dir.chdir '../doc' do
57
+ Dir.chdir '../doc/aquarium' do
56
58
  output = nil
57
59
  IO.popen('webgen 2>&1') do |io|
58
60
  output = io.read
@@ -63,7 +65,7 @@ end
63
65
 
64
66
  desc 'Generate RDoc'
65
67
  rd = Rake::RDocTask.new do |rdoc|
66
- rdoc.rdoc_dir = '../doc/output/rdoc'
68
+ rdoc.rdoc_dir = '../doc/aquarium/out/rdoc'
67
69
  rdoc.options << '--title' << 'Aquarium' << '--line-numbers' << '--inline-source' << '--main' << 'README'
68
70
  rdoc.rdoc_files.include('README', 'CHANGES', 'MIT_LICENSE', 'examples/**/*.rb', 'UPGRADE', 'lib/**/*.rb') # 'EXAMPLES.rd'
69
71
  end
@@ -124,23 +126,29 @@ task :todo do
124
126
  end
125
127
 
126
128
  task :clobber do
127
- rm_rf '../doc/output'
129
+ rm_rf '../doc/aquarium/out'
128
130
  rm_rf 'translated_specs'
129
131
  end
130
132
 
131
133
  task :release => [:clobber, :verify_committed, :verify_user, :spec, :publish_packages, :tag, :publish_website, :publish_news]
132
134
 
135
+ # TODO!
133
136
  desc "Verifies that there is no uncommitted code"
134
137
  task :verify_committed do
135
- IO.popen('svn stat') do |io|
138
+ IO.popen('git status') do |io|
136
139
  io.each_line do |line|
137
- raise "\n!!! Do a svn commit first !!!\n\n" if line =~ /^\s*M\s*/
140
+ raise "\n!!! Do a git commit first !!!\n\n" if line =~ /^\s*M\s*/
138
141
  end
139
142
  end
140
143
  end
141
144
 
142
- desc "Creates a tag in svn"
145
+ # TODO!
146
+ desc "Creates a tag in git"
143
147
  task :tag do
148
+ end
149
+
150
+ desc "Creates a tag in svn (obsolete)"
151
+ task :svntag do
144
152
  from = `svn info #{File.dirname(__FILE__)}`.match(/URL: (.*)\/aquarium/n)[1]
145
153
  to = from.gsub(/trunk/, "tags/#{Aquarium::VERSION::TAG}")
146
154
  tag_cmd = "svn cp #{from} #{to} -m \"Tag release #{Aquarium::VERSION::FULL_VERSION}\""
@@ -182,14 +190,16 @@ task :verify_user do
182
190
  end
183
191
 
184
192
  desc "Upload Website to RubyForge"
185
- task :publish_website => [:verify_user, :website] do
193
+ task :publish_website => [:verify_user, :website, :do_publish_website]
194
+
195
+ task :do_publish_website do
186
196
  unless Aquarium::VERSION::RELEASE_CANDIDATE
187
197
  # host = "aquarium-website@rubyforge.org"
188
198
  host = "#{ENV['RUBYFORGE_USER']}@rubyforge.org"
189
199
  publisher = Rake::SshDirPublisher.new(
190
200
  "#{host}",
191
201
  "/var/www/gforge-projects/#{PKG_NAME}",
192
- "../doc/output"
202
+ "../doc/aquarium/out"
193
203
  )
194
204
  publisher.upload
195
205
  else
@@ -204,7 +214,7 @@ task :archive_website => [:verify_user, :website] do
204
214
  publisher = Rake::SshDirPublisher.new(
205
215
  "#{host}",
206
216
  "/var/www/gforge-projects/#{PKG_NAME}/#{Spec::VERSION::TAG}",
207
- "../doc/output"
217
+ "../doc/aquarium/out"
208
218
  )
209
219
  publisher.upload
210
220
  end
data/UPGRADE CHANGED
@@ -1,82 +1,88 @@
1
1
  == Updating to Aquarium-0.4.0
2
2
 
3
- This release is fully backwards-compatible with previous releases. It expands the API slightly and adds
4
- internal improvements to better support JRuby. There should be no upgrade issues.
3
+ This release is fully backwards-compatible with previous releases. It expands
4
+ the API slightly and adds internal improvements to better support JRuby. There
5
+ should be no upgrade issues.
5
6
 
6
7
  == Updating to Aquarium-0.3.1
7
8
 
8
- There should be no upgrade issues with this release. However, the enhancement #17565 now ensures that a
9
- JoinPoint is only specified with one type and a type that actually exists, when a string, symbol, or
10
- regex is used to specify the type.
9
+ There should be no upgrade issues with this release. However, the enhancement
10
+ #17565 now ensures that a JoinPoint is only specified with one type and a type
11
+ that actually exists, when a string, symbol, or regex is used to specify the
12
+ type.
11
13
 
12
14
  == Updating to Aquarium-0.3.0
13
15
 
14
- There are no known upgrade issues with this release. Although many new synonyms were added for API method
15
- parameters, all changes are backwards compatible.
16
+ There are no known upgrade issues with this release. Although many new synonyms
17
+ were added for API method parameters, all changes are backwards compatible.
16
18
 
17
19
  == Updating to Aquarium-0.2.0
18
20
 
19
- This release changes the expected advice parameter list from |join_point, *method_args| to
20
- |join_point, object, *method_args|, where "object" is the current object receiving the message
21
- corresponding to the advised join point. Therefore, when you upgrade, you will need to modify your
22
- advices to take this extra argument, even if you don't use it. Since an advice of |jp, *args| would
23
- silently "absorb" the object into the beginning of "*args", thereby potentially causing confusion,
24
- Aquarium will raise an exception if the advice block or proc has this obsolete signature.
21
+ This release changes the expected advice parameter list from
22
+ |join_point, *method_args|
23
+ to
24
+ |join_point, object, *method_args|
25
+ where "object" is the current object receiving the message corresponding to
26
+ the advised join point. Therefore, when you upgrade, you will need to modify
27
+ your advices to take this extra argument, even if you don't use it. Since an
28
+ advice of |jp, *args| would silently "absorb" the object into the beginning of
29
+ "*args", thereby potentially causing confusion, Aquarium will raise an exception
30
+ if the advice block or proc has this obsolete signature.
25
31
 
26
- Note that "JoinPoint#Context.advised_object" is still supported, even if it is now less useful.
32
+ Note that "JoinPoint#Context.advised_object" is still supported, even if it is
33
+ now less useful.
27
34
 
28
35
  == Updating to Aquarium-0.1.8
29
36
 
30
- V0.1.7 did not successfully "register" at rubyforge. This releases fixes that problem and also adds
31
- several feature enhancements and refactorings. There are no known upgrade issues.
37
+ V0.1.7 did not successfully "register" at rubyforge. This releases fixes that
38
+ problem and also adds several feature enhancements and refactorings. There are
39
+ no known upgrade issues.
32
40
 
33
41
  == Updating to Aquarium-0.1.7
34
42
 
35
- This is primarily a bug-fix release, so there should be no upgrading or incompatibility issues.
43
+ This is primarily a bug-fix release, so there should be no upgrading or
44
+ incompatibility issues.
36
45
 
37
46
  == Updating to Aquarium-0.1.6
38
47
 
39
- As described in the CHANGES, the JoinPoint#type, JoinPoint#type=, JoinPoint#object, and JoinPoint#object=
40
- are now deprecated. Client code that uses these methods will still work, but warning messages will be
41
- written to STDOUT. See CHANGES for more details.
48
+ As described in the CHANGES, the JoinPoint#type, JoinPoint#type=,
49
+ JoinPoint#object, and JoinPoint#object= are now deprecated. Client code that
50
+ uses these methods will still work, but warning messages will be written to
51
+ STDOUT. See CHANGES for more details.
42
52
 
43
53
  == Updating to Aquarium-0.1.5
44
54
 
45
- This is mostly a bug-fix release, but it did have to introduce one API change, as described in the
46
- CHANGES. In particular, the aspect "DSL" methods are no longer automatically to Object, as some of
47
- their names overlap with methods added by Rails.
55
+ This is mostly a bug-fix release, but it did have to introduce one API change,
56
+ as described in the CHANGES. In particular, the aspect "DSL" methods are no
57
+ longer automatically to Object, as some of their names overlap with methods
58
+ added by Rails.
48
59
 
49
60
  Now, if you want these methods added to Object, you must require the new
50
61
  lib/aquarium/aspects/dsl/object_dsl.rb explicitly.
51
62
 
52
- As an alternative, if you just want these methods added selectively in certain types, then do the
53
- following:
63
+ As an alternative, if you just want these methods added selectively in certain
64
+ types, then do the following:
54
65
 
55
- <ruby>
56
- require 'aquarium/dsl/aspect_dsl'
66
+ require 'aquarium/dsl/aspect_dsl'
57
67
 
58
- class MyClass # reopen "MyClass"
59
- # Add the methods as _class_ methods
60
- include Aquarium::DSL
61
- end
62
- </ruby>
68
+ class MyClass # reopen "MyClass"
69
+ # Add the methods as _class_ methods
70
+ include Aquarium::DSL
71
+ end
63
72
 
64
73
  or, use (class|module)_eval:
65
- <ruby>
66
- require 'aquarium/dsl/aspect_dsl'
67
74
 
68
- MyClass.class_eval do
69
- # Add the methods as _class_ methods
70
- include Aquarium::DSL
71
- end
72
- </ruby>
75
+ require 'aquarium/dsl/aspect_dsl'
76
+
77
+ MyClass.class_eval do
78
+ # Add the methods as _class_ methods
79
+ include Aquarium::DSL
80
+ end
73
81
 
74
82
  To add the methods as _instance_ methods on individual objects:
75
83
 
76
- <ruby>
77
- object = MyClass.new
78
- object.extend(Aquarium::DSL)
79
- </ruby>
84
+ object = MyClass.new
85
+ object.extend(Aquarium::DSL)
80
86
 
81
87
  See the CHANGES for more details.
82
88
 
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
- # Example demonstrating emerging ideas about good aspect-oriented design. Specifically, this
3
- # example follows ideas of Jonathan Aldrich on "Open Modules", where a "module" (in the generic
4
- # sense of the word...) is responsible for defining and maintaining the pointcuts that it is
5
- # willing to expose to potential aspects. Aspects are only allowed to advise the module through
6
- # the pointcut. (Enforcing this constraint is TBD)
7
- # Griswold, Sullivan, and collaborators have expanded on these ideas. See their IEEE Software,
8
- # March 2006 paper.
2
+ # Example demonstrating emerging ideas about good aspect-oriented design.
3
+ # Specifically, this example follows ideas of Jonathan Aldrich on
4
+ # "Open Modules", where a "module" (in the generic sense of the word...) is
5
+ # responsible for defining and maintaining the pointcuts that it is willing
6
+ # to expose to potential aspects. Aspects are only allowed to advise the
7
+ # module through the pointcut. (Enforcing this constraint is TBD.) Griswold,
8
+ # Sullivan, and collaborators have expanded on these ideas. See their IEEE
9
+ # Software, March 2006 paper.
9
10
 
10
11
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
11
12
  require 'aquarium'
@@ -23,10 +24,11 @@ module Aquarium
23
24
  # STATE_CHANGE = pointcut :method => :state=
24
25
  # STATE_CHANGE = pointcut :attribute => :state, :attribute_options => [:writers]
25
26
  # Note that only matching on the attribute writers is important, especially
26
- # given the advice block below, because if the reader is allowed to be advised,
27
- # we get an infinite recursion of advice invocation! The correct solution is
28
- # the planned extension of the pointcut language to support condition tests for
29
- # context. I.e., we don't want the advice applied when it's already inside advice.
27
+ # given the advice block below, because if the reader is allowed to be
28
+ # advised, we get an infinite recursion of advice invocation! The correct
29
+ # solution is the planned extension of the pointcut language to support
30
+ # condition tests for context. I.e., we don't want the advice applied when
31
+ # it's already inside advice.
30
32
  STATE_CHANGE = pointcut :writing => :state
31
33
  end
32
34
  end
@@ -34,9 +36,10 @@ end
34
36
  include Aquarium::Aspects
35
37
 
36
38
  # Observe state changes in the class, using the class-defined pointcut.
37
- # Two ways of referencing the pointcut are shown. The first assumes you know the particular
38
- # pointcuts you care about. The second is more general; it uses the recently-introduced
39
- # :named_pointcut feature to search for all pointcuts matching a name in a set of types.
39
+ # Two ways of referencing the pointcut are shown. The first assumes you know
40
+ # the particular pointcuts you care about. The second is more general; it
41
+ # uses the recently-introduced :named_pointcut feature to search for all
42
+ # pointcuts matching a name in a set of types.
40
43
 
41
44
  observer1 = Aspect.new :after,
42
45
  :pointcut => Aquarium::ClassWithStateAndBehavior::STATE_CHANGE do |jp, obj, *args|
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
- # Example demonstrating "Design by Contract", Bertrand Meyer's idea for programmatically-
3
- # specifying the contract of use for a class or module and testing it at runtime (usually
4
- # during the testing process)
5
- # This example is adapted from spec/extras/design_by_contract_spec.rb.
6
- # Note: the DesignByContract module adds the #precondition, #postcondition, and #invariant
7
- # methods shown below to Object and they use "self" as the :object to advise.
2
+ # Example demonstrating "Design by Contract", Bertrand Meyer's idea for
3
+ # programmatically-specifying the contract of use for a class or module and
4
+ # testing it at runtime (usually during the testing process). This example
5
+ # is adapted from spec/extras/design_by_contract_spec.rb.
6
+ # Note: the DesignByContract module adds the #precondition, #postcondition,
7
+ # and #invariant methods shown below to Object and they use "self" as the
8
+ # :object to advise.
8
9
 
9
10
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
10
11
  require 'aquarium/extras/design_by_contract'
@@ -15,7 +16,8 @@ module Aquarium
15
16
  p "inside :action"
16
17
  end
17
18
 
18
- precondition :calls_to => :action, :message => "Must pass more than one argument." do |jp, obj, *args|
19
+ precondition :calls_to => :action,
20
+ :message => "Must pass more than one argument." do |jp, obj, *args|
19
21
  args.size > 0
20
22
  end
21
23
  end
@@ -37,8 +39,9 @@ module Aquarium
37
39
  end
38
40
 
39
41
  postcondition :calls_to => :action,
40
- :message => "Must return a copy of the input args with :a appended to it." do |jp, obj, *args|
41
- jp.context.returned_value.size == args.size + 1 && jp.context.returned_value[-1] == :a
42
+ :message => "Must return new array, [:a] + args." do |jp, obj, *args|
43
+ jp.context.returned_value.size == args.size + 1 &&
44
+ jp.context.returned_value[-1] == :a
42
45
  end
43
46
  end
44
47
  end
@@ -66,7 +69,8 @@ module Aquarium
66
69
  @invar = 1
67
70
  end
68
71
 
69
- invariant :calls_to => /action$/, :message => "Must not change the @invar value." do |jp, obj, *args|
72
+ invariant :calls_to => /action$/,
73
+ :message => "The @invar value must not change." do |jp, obj, *args|
70
74
  obj.invar == 0
71
75
  end
72
76
  end
@@ -25,11 +25,12 @@ module Aquarium
25
25
  end
26
26
 
27
27
  Aquarium::Aspects::Aspect.new :around,
28
- :calls_to => /^raise_exception/, :in_type => Aquarium::Raiser do |jp, obj, *args|
28
+ :calls_to => /^raise_exception/,
29
+ :in_type => Aquarium::Raiser do |jp, obj, *args|
29
30
  begin
30
31
  jp.proceed
31
32
  rescue Aquarium::Exception1 => e
32
- raise Aquarium::NewException.new("Old exception message was \"#{e.message}\"")
33
+ raise Aquarium::NewException.new("Exception message was \"#{e.message}\"")
33
34
  end
34
35
  end
35
36
 
@@ -40,7 +41,8 @@ rescue Aquarium::Exception2 => e
40
41
  p "Rescued exception: #{e.class} with message: #{e}"
41
42
  end
42
43
 
43
- p "The raised Aquarium::Exception1 raised here will be intercepted and Aquarium::NewException will be raised:"
44
+ p "The raised Aquarium::Exception1 raised here will be intercepted and"
45
+ p " Aquarium::NewException will be raised:"
44
46
  begin
45
47
  Aquarium::Raiser.new.raise_exception1
46
48
  rescue Aquarium::NewException => e
@@ -21,7 +21,8 @@ include Aquarium::Finders
21
21
 
22
22
  found = TypeFinder.new.find :types => /Aquarium::TypeFinderIntroductionExampleTarget/
23
23
 
24
- # Now, iterate through them and "extend" them with the module defining the new behavior.
24
+ # Now, iterate through them and "extend" them with the module defining
25
+ # the new behavior.
25
26
 
26
27
  found.each {|t| t.extend Aquarium::TypeFinderIntroductionExampleModule }
27
28
 
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
- # Example demonstrating "around" advice for method_missing. This is a technique for
3
- # avoiding collisions when different toolkits want to override method_missing in the
4
- # same classes, e.g., Object. Using around advice as shown allows a toolkit to add
5
- # custom behavior while invoking the "native" method_missing to handle unrecognized
6
- # method calls.
7
- # Note that it is essential to use around advice, not before or after advice, because
8
- # neither can prevent the call to the "wrapped" method_missing, which is presumably
9
- # not what you want.
10
- # In this (contrived) example, an Echo class uses method_missing to simply echo
11
- # the method name and arguments. An aspect is used to intercept any calls to a
12
- # fictitious "log" method and handle those in a different way.
2
+ # Example demonstrating "around" advice for method_missing. This is a
3
+ # technique for avoiding collisions when different toolkits want to override
4
+ # method_missing in the same classes, e.g., Object. Using around advice as
5
+ # shown allows a toolkit to add custom behavior while invoking the "native"
6
+ # method_missing to handle unrecognized method calls.
7
+ # Note that it is essential to use around advice, not before or after advice,
8
+ # because neither can prevent the call to the "wrapped" method_missing, which
9
+ # is presumably not what you want. In this (contrived) example, an Echo class
10
+ # uses method_missing to simply echo the method name and arguments. An aspect
11
+ # is used to intercept any calls to a fictitious "log" method and handle those
12
+ # in a different way.
13
13
 
14
14
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
15
15
  require 'aquarium'
@@ -32,11 +32,12 @@ echo1.log "something", "interesting..."
32
32
  echo1.shout "theater", "in", "a", "crowded", "firehouse!"
33
33
 
34
34
  Aquarium::Aspects::Aspect.new :around,
35
- :calls_to => :method_missing, :for_type => Aquarium::Echo, do |join_point, obj, sym, *args|
35
+ :calls_to => :method_missing,
36
+ :for_type => Aquarium::Echo do |jp, obj, sym, *args|
36
37
  if sym == :log
37
38
  p "--- Sending to log: #{args.join(" ")}"
38
39
  else
39
- join_point.proceed
40
+ jp.proceed
40
41
  end
41
42
  end
42
43