aquarium 0.5.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +240 -215
  3. data/README +61 -44
  4. data/RELEASE-PLAN +21 -23
  5. data/Rakefile +64 -94
  6. data/UPGRADE +45 -35
  7. data/aquarium.gemspec +50 -0
  8. data/examples/README.txt +6 -0
  9. data/examples/aspect_design_example_spec.rb +2 -2
  10. data/examples/design_by_contract_example_spec.rb +3 -3
  11. data/examples/exception_wrapping_example_spec.rb +2 -2
  12. data/examples/introductions_example_spec.rb +1 -1
  13. data/examples/method_tracing_example_spec.rb +17 -16
  14. data/examples/reusable_aspect_hack_example_spec.rb +5 -5
  15. data/jruby/Rakefile +61 -0
  16. data/jruby/java/example/Worker.java +9 -0
  17. data/jruby/java/example/sorter/StringListSorter.java +22 -0
  18. data/jruby/java/example/sorter/converter/StringListCaseConverterAndSorter.java +42 -0
  19. data/jruby/java/example/visibility/Visibility.java +13 -0
  20. data/jruby/spec/java_class_aspects_spec.rb +434 -0
  21. data/jruby/spec/java_visibility_spec.rb +122 -0
  22. data/jruby/spec/spec_helper.rb +5 -0
  23. data/lib/aquarium/aspects/aspect.rb +8 -4
  24. data/lib/aquarium/utils/type_utils.rb +4 -1
  25. data/lib/aquarium/version.rb +29 -28
  26. data/previous_failures.txt +0 -0
  27. data/rspec.watchr +60 -0
  28. data/spec/aquarium/aspects/advice_spec.rb +10 -10
  29. data/spec/aquarium/aspects/aspect_invocation_spec.rb +79 -79
  30. data/spec/aquarium/aspects/aspect_spec.rb +73 -73
  31. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +5 -5
  32. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
  33. data/spec/aquarium/aspects/default_objects_handler_spec.rb +5 -5
  34. data/spec/aquarium/aspects/join_point_spec.rb +40 -40
  35. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +8 -8
  36. data/spec/aquarium/aspects/pointcut_spec.rb +25 -25
  37. data/spec/aquarium/extensions/regex_spec.rb +6 -6
  38. data/spec/aquarium/extras/design_by_contract_spec.rb +6 -6
  39. data/spec/aquarium/finders/finder_result_spec.rb +2 -2
  40. data/spec/aquarium/finders/method_finder_spec.rb +24 -24
  41. data/spec/aquarium/finders/pointcut_finder_spec.rb +10 -10
  42. data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +4 -4
  43. data/spec/aquarium/finders/type_finder_spec.rb +5 -5
  44. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +6 -5
  45. data/spec/aquarium/finders/type_finder_with_nested_types_spec.rb +2 -2
  46. data/spec/aquarium/utils/logic_error_spec.rb +1 -1
  47. data/spec/aquarium/utils/method_utils_spec.rb +38 -38
  48. data/spec/aquarium/utils/nil_object_spec.rb +11 -11
  49. data/spec/aquarium/utils/options_utils_spec.rb +8 -8
  50. data/spec/aquarium/utils/type_utils_spec.rb +3 -3
  51. metadata +238 -57
data/UPGRADE CHANGED
@@ -1,29 +1,39 @@
1
+ == Updating to Aquarium-0.7.1
2
+
3
+ Version 0.7.1 supports only Ruby 2.6. It was tested with 2.6.3p62 (2019-04-16 revision 67580). Basic JRuby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 support is provided, but using JRuby currently does *not* pass all the custom Java specs in the `jruby/spec` directory, which specifically test working with Java classes. However, JRuby does pass all the Ruby specs in the `spec` directory. This is a long-standing issue with JRuby support in Aquarium. Patches are welcome!
4
+
5
+ > TODO: There are currently a _lot_ of deprecation warnings.
6
+
7
+ == Updating to Aquarium-0.6.X
8
+
9
+ Version 0.6.0 supports only Ruby 2.0.0p247. Basic JRuby 1.7.4 (1.9.3p392) support is provided, but using JRuby currently does *not* pass all the custom Java specs in the `jruby/spec` directory, which specifically test working with Java classes. However, JRuby does pass all the Ruby specs in the `spec` directory. I didn't want to release v0.6.0 with the Java-specific specs not working, but I didn't have time to resolve the issues. Patches are welcome.
10
+
1
11
  == Updating to Aquarium-0.5.X
2
12
 
3
- This release introduces a few small API changes that are described in
4
- CHANGES. The primary goal of the release is to add full support for
13
+ This release introduces a few small API changes that are described in
14
+ CHANGES. The primary goal of the release is to add full support for
5
15
  Ruby 1.9.3 and JRuby 1.6.7.
6
16
 
7
- It was not tested on early versions of Ruby 1.9 and JRuby 1.X, so users
8
- of earlier releases should use caution upgrading. Post any issues to the
17
+ It was not tested on early versions of Ruby 1.9 and JRuby 1.X, so users
18
+ of earlier releases should use caution upgrading. Post any issues to the
9
19
  GitHub project.
10
20
 
11
21
  == Updating to Aquarium-0.4.X
12
22
 
13
- This release is fully backwards-compatible with previous releases. It
14
- expands the API slightly and adds internal improvements to better support
15
- JRuby. There should be no upgrade issues.
23
+ This release is fully backwards-compatible with previous releases. It
24
+ expands the API slightly and adds internal improvements to better support
25
+ JRuby. There should be no upgrade issues.
16
26
 
17
27
  == Updating to Aquarium-0.3.1
18
28
 
19
- There should be no upgrade issues with this release. However, the enhancement
20
- #17565 now ensures that a JoinPoint is only specified with one type and a type
21
- that actually exists, when a string, symbol, or regex is used to specify the
22
- type.
29
+ There should be no upgrade issues with this release. However, the enhancement
30
+ #17565 now ensures that a JoinPoint is only specified with one type and a type
31
+ that actually exists, when a string, symbol, or regex is used to specify the
32
+ type.
23
33
 
24
34
  == Updating to Aquarium-0.3.0
25
35
 
26
- There are no known upgrade issues with this release. Although many new synonyms
36
+ There are no known upgrade issues with this release. Although many new synonyms
27
37
  were added for API method parameters, all changes are backwards compatible.
28
38
 
29
39
  == Updating to Aquarium-0.2.0
@@ -31,46 +41,46 @@ were added for API method parameters, all changes are backwards compatible.
31
41
  This release changes the expected advice parameter list from
32
42
  |join_point, *method_args|
33
43
  to
34
- |join_point, object, *method_args|
35
- where "object" is the current object receiving the message corresponding to
36
- the advised join point. Therefore, when you upgrade, you will need to modify
37
- your advices to take this extra argument, even if you don't use it. Since an
38
- advice of |jp, *args| would silently "absorb" the object into the beginning of
39
- "*args", thereby potentially causing confusion, Aquarium will raise an exception
40
- if the advice block or proc has this obsolete signature.
41
-
42
- Note that "JoinPoint#Context.advised_object" is still supported, even if it is
44
+ |join_point, object, *method_args|
45
+ where "object" is the current object receiving the message corresponding to
46
+ the advised join point. Therefore, when you upgrade, you will need to modify
47
+ your advices to take this extra argument, even if you don't use it. Since an
48
+ advice of |jp, *args| would silently "absorb" the object into the beginning of
49
+ "*args", thereby potentially causing confusion, Aquarium will raise an exception
50
+ if the advice block or proc has this obsolete signature.
51
+
52
+ Note that "JoinPoint#Context.advised_object" is still supported, even if it is
43
53
  now less useful.
44
54
 
45
55
  == Updating to Aquarium-0.1.8
46
56
 
47
- V0.1.7 did not successfully "register" at rubyforge. This releases fixes that
48
- problem and also adds several feature enhancements and refactorings. There are
57
+ V0.1.7 did not successfully "register" at rubyforge. This releases fixes that
58
+ problem and also adds several feature enhancements and refactorings. There are
49
59
  no known upgrade issues.
50
60
 
51
61
  == Updating to Aquarium-0.1.7
52
62
 
53
- This is primarily a bug-fix release, so there should be no upgrading or
63
+ This is primarily a bug-fix release, so there should be no upgrading or
54
64
  incompatibility issues.
55
65
 
56
66
  == Updating to Aquarium-0.1.6
57
67
 
58
- As described in the CHANGES, the JoinPoint#type, JoinPoint#type=,
59
- JoinPoint#object, and JoinPoint#object= are now deprecated. Client code that
60
- uses these methods will still work, but warning messages will be written to
61
- STDOUT. See CHANGES for more details.
68
+ As described in the CHANGES, the JoinPoint#type, JoinPoint#type=,
69
+ JoinPoint#object, and JoinPoint#object= are now deprecated. Client code that
70
+ uses these methods will still work, but warning messages will be written to
71
+ STDOUT. See CHANGES for more details.
62
72
 
63
73
  == Updating to Aquarium-0.1.5
64
74
 
65
- This is mostly a bug-fix release, but it did have to introduce one API change,
66
- as described in the CHANGES. In particular, the aspect "DSL" methods are no
67
- longer automatically to Object, as some of their names overlap with methods
68
- added by Rails.
75
+ This is mostly a bug-fix release, but it did have to introduce one API change,
76
+ as described in the CHANGES. In particular, the aspect "DSL" methods are no
77
+ longer automatically to Object, as some of their names overlap with methods
78
+ added by Rails.
69
79
 
70
- Now, if you want these methods added to Object, you must require the new
71
- lib/aquarium/aspects/dsl/object_dsl.rb explicitly.
80
+ Now, if you want these methods added to Object, you must require the new
81
+ lib/aquarium/aspects/dsl/object_dsl.rb explicitly.
72
82
 
73
- As an alternative, if you just want these methods added selectively in certain
83
+ As an alternative, if you just want these methods added selectively in certain
74
84
  types, then do the following:
75
85
 
76
86
  require 'aquarium/dsl/aspect_dsl'
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # This GemSpec adapted from http://rakeroutes.com/blog/lets-write-a-gem-part-one/
3
+
4
+ # -- this is magic line that ensures "../lib" is in the load path -------------
5
+ $:.push File.expand_path("../lib", __FILE__)
6
+ require 'aquarium/version'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "aquarium"
10
+ s.version = Aquarium::VERSION::STRING
11
+ s.summary = Aquarium::VERSION::DESCRIPTION
12
+ s.authors = ["Dean Wampler and other contributors"]
13
+ s.email = "deanwampler@gmail.com"
14
+ s.homepage = "https://deanwampler.github.io/open-source/aquarium/index.html"
15
+ s.rubyforge_project = "aquarium"
16
+ s.description = <<-EOF
17
+ Aquarium is a full-featured Aspect-Oriented Programming (AOP) framework for Ruby that is
18
+ designed to provide an intuitive syntax and support for large-scale, dynamic aspects.
19
+ EOF
20
+
21
+ # Use all files managed with Git.
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+
25
+ s.bindir = 'bin'
26
+
27
+ # Where any executable files included with the gem live.
28
+ # These go in bin by convention. In our case, we have none.
29
+ # s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+ s.executables = []
31
+ s.require_paths = ["lib"]
32
+
33
+ # Specify dependencies. Some of these are for building the documentation.
34
+ s.add_development_dependency('bundler', '>= 2.0.1')
35
+ s.add_development_dependency('coderay', '>= 1.1.2')
36
+ s.add_development_dependency('meta_project', '>= 0.4.15')
37
+ s.add_development_dependency('rake', '>= 12.3.2')
38
+ s.add_development_dependency('rdoc', '>= 6.1.1')
39
+ s.add_development_dependency('RedCloth', '>= 4.3.2')
40
+ s.add_development_dependency("rspec", '>= 2.14.1')
41
+ s.add_development_dependency("rspec-core", '>= 3.8.0')
42
+ s.add_development_dependency("rspec-expectations", '>= 3.8.3')
43
+ s.add_development_dependency('webgen', '>= 1.5.2')
44
+
45
+ # s.has_rdoc = true
46
+ # s.rdoc_options = rd.options
47
+ # s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$|^EXAMPLES.rd$/ }.to_a
48
+
49
+ s.autorequire = 'aquarium'
50
+ end
@@ -0,0 +1,6 @@
1
+ Aquarium Examples README
2
+
3
+ There are several examples here and four corresponding versions that are RSpec examples (so they are testable!).
4
+
5
+ I keep the non-RSpec versions primarily for the documentation pages, but it's a bit risky keeping them as they could break in the future, so buyer beware!
6
+
@@ -40,7 +40,7 @@ describe "An example of an aspect referencing a particular class-defined pointcu
40
40
  observer = Aspect.new :after,
41
41
  :pointcut => Aquarium::ClassWithStateAndBehavior::STATE_CHANGE do |jp, obj, *args|
42
42
  @new_state = obj.state
43
- @new_state.should be_eql(*args)
43
+ expect(@new_state).to eq(*args)
44
44
  end
45
45
  object = Aquarium::ClassWithStateAndBehavior.new(:a1, :a2, :a3)
46
46
  object.state = [:b1, :b2]
@@ -54,7 +54,7 @@ describe "An example of an aspect searching for class-defined pointcuts." do
54
54
  observer = Aspect.new :after,
55
55
  :named_pointcuts => {:matching => /CHANGE/, :within_types => Aquarium::ClassWithStateAndBehavior} do |jp, obj, *args|
56
56
  @new_state = obj.state
57
- @new_state.should be_eql(*args)
57
+ expect(@new_state).to eq(*args)
58
58
  end
59
59
  object = Aquarium::ClassWithStateAndBehavior.new(:a1, :a2, :a3)
60
60
  object.state = [:b1, :b2]
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  describe "An example using a precondition" do
26
26
  it "should fail at the call entry point if the precondition is not satisfied." do
27
- lambda { Aquarium::PreCondExample.new.action }.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
27
+ expect { Aquarium::PreCondExample.new.action }.to raise_error(Aquarium::Extras::DesignByContract::ContractError)
28
28
  end
29
29
  end
30
30
 
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  describe "An example using a postcondition" do
51
51
  it "should fail at the call exit point if the postcondition is not satisfied." do
52
- lambda { Aquarium::PostCondExample.new.action }.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
52
+ expect { Aquarium::PostCondExample.new.action }.to raise_error(Aquarium::Extras::DesignByContract::ContractError)
53
53
  end
54
54
  end
55
55
 
@@ -79,7 +79,7 @@ end
79
79
 
80
80
  describe "An example using an invariant" do
81
81
  it "should fail at the call entry or exit point if the invariant is not satisfied." do
82
- lambda { Aquarium::InvarCondExample.new.bad_action }.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
82
+ expect { Aquarium::InvarCondExample.new.bad_action }.to raise_error(Aquarium::Extras::DesignByContract::ContractError)
83
83
  end
84
84
  end
85
85
 
@@ -41,9 +41,9 @@ describe "Rescuing one exception type and raising a second type" do
41
41
  end
42
42
 
43
43
  it "should intercept the specified type of exception" do
44
- lambda { @raiser.raise_exception1 }.should raise_error(Aquarium::NewException)
44
+ expect { @raiser.raise_exception1 }.to raise_error(Aquarium::NewException)
45
45
  end
46
46
  it "should not intercept other types of exceptions" do
47
- lambda { @raiser.raise_exception2 }.should raise_error(Aquarium::Exception2)
47
+ expect { @raiser.raise_exception2 }.to raise_error(Aquarium::Exception2)
48
48
  end
49
49
  end
@@ -30,7 +30,7 @@ describe "Using TypeFinder to introduce modules in a set of other types" do
30
30
  Aquarium::TypeFinderIntroductionExampleTargetModule2,
31
31
  Aquarium::TypeFinderIntroductionExampleTargetClass1,
32
32
  Aquarium::TypeFinderIntroductionExampleTargetClass2].each do |t|
33
- t.methods.should include('introduced_method')
33
+ expect(t.methods).to include(:introduced_method)
34
34
  end
35
35
  end
36
36
  end
@@ -69,10 +69,11 @@ describe "An example with advice on the public instance methods (excluding ances
69
69
  foo = Aquarium::Foo.new :a5, :a6
70
70
  foo.do_it :b5, :b6
71
71
  foo.logged_messages.size.should == 4
72
- foo.logged_messages[0].should include("Inside: Aquarium::Foo#initialize")
73
- foo.logged_messages[1].should include("Entering")
74
- foo.logged_messages[2].should include("Inside: Aquarium::Foo#do_it")
75
- foo.logged_messages[3].should include("Leaving")
72
+
73
+ expect(foo.logged_messages[0]).to include("Inside: Aquarium::Foo#initialize")
74
+ expect(foo.logged_messages[1]).to include("Entering")
75
+ expect(foo.logged_messages[2]).to include("Inside: Aquarium::Foo#do_it")
76
+ expect(foo.logged_messages[3]).to include("Leaving")
76
77
  aspect.unadvise
77
78
  end
78
79
  end
@@ -114,10 +115,10 @@ describe "An example with advice on the public instance methods (including ances
114
115
  bar = Aquarium::Bar.new :a9, :a10
115
116
  bar.do_something_else :b9, :b10
116
117
  bar.logged_messages.size.should == 4
117
- bar.logged_messages[0].should include("Inside: Aquarium::BarModule#initialize")
118
- bar.logged_messages[1].should include("Entering: Aquarium::Bar#do_something_else")
119
- bar.logged_messages[2].should include("Inside: Aquarium::BarModule#do_something_else")
120
- bar.logged_messages[3].should include("Leaving: Aquarium::Bar#do_something_else")
118
+ expect(bar.logged_messages[0]).to include("Inside: Aquarium::BarModule#initialize")
119
+ expect(bar.logged_messages[1]).to include("Entering: Aquarium::Bar#do_something_else")
120
+ expect(bar.logged_messages[2]).to include("Inside: Aquarium::BarModule#do_something_else")
121
+ expect(bar.logged_messages[3]).to include("Leaving: Aquarium::Bar#do_something_else")
121
122
  aspect.unadvise
122
123
  end
123
124
  end
@@ -139,18 +140,18 @@ describe "An example with advice on the private initialize method of Foo and Bar
139
140
  foo = Aquarium::Foo.new :a11, :a12
140
141
  foo.do_it :b11, :b12
141
142
  foo.logged_messages.size.should == 4
142
- foo.logged_messages[0].should include("Entering: Aquarium::Foo#initialize")
143
- foo.logged_messages[1].should include("Inside: Aquarium::Foo#initialize")
144
- foo.logged_messages[2].should include("Leaving: Aquarium::Foo#initialize")
145
- foo.logged_messages[3].should include("Inside: Aquarium::Foo#do_it")
143
+ expect(foo.logged_messages[0]).to include("Entering: Aquarium::Foo#initialize")
144
+ expect(foo.logged_messages[1]).to include("Inside: Aquarium::Foo#initialize")
145
+ expect(foo.logged_messages[2]).to include("Leaving: Aquarium::Foo#initialize")
146
+ expect(foo.logged_messages[3]).to include("Inside: Aquarium::Foo#do_it")
146
147
 
147
148
  bar = Aquarium::Bar.new :a13, :a14
148
149
  bar.do_something_else :b13, :b14
149
150
  bar.logged_messages.size.should == 4
150
- bar.logged_messages[0].should include("Entering: Aquarium::Bar#initialize")
151
- bar.logged_messages[1].should include("Inside: Aquarium::BarModule#initialize")
152
- bar.logged_messages[2].should include("Leaving: Aquarium::Bar#initialize")
153
- bar.logged_messages[3].should include("Inside: Aquarium::BarModule#do_something_else")
151
+ expect(bar.logged_messages[0]).to include("Entering: Aquarium::Bar#initialize")
152
+ expect(bar.logged_messages[1]).to include("Inside: Aquarium::BarModule#initialize")
153
+ expect(bar.logged_messages[2]).to include("Leaving: Aquarium::Bar#initialize")
154
+ expect(bar.logged_messages[3]).to include("Inside: Aquarium::BarModule#do_something_else")
154
155
  aspect.unadvise
155
156
  after_methods = Aquarium::Foo.private_instance_methods.sort #- Object.private_methods.sort
156
157
  (before_methods - after_methods).should == []
@@ -55,26 +55,26 @@ describe "Reusable aspect defined in a module can be evaluated at 'include' time
55
55
 
56
56
  it "should not advise types that don't include the module with the aspect" do
57
57
  NotTraced1.new.doit
58
- Aquarium::Reusables::TraceMethods.advice_invoked?.should be_false
58
+ Aquarium::Reusables::TraceMethods.advice_invoked?.should be_falsey
59
59
  end
60
60
 
61
61
  it "should not advise any methods if the module with the aspect is included before any methods are defined!" do
62
62
  NotTraced2.new.doit
63
- Aquarium::Reusables::TraceMethods.advice_invoked?.should be_false
63
+ Aquarium::Reusables::TraceMethods.advice_invoked?.should be_falsey
64
64
  end
65
65
 
66
66
  it "should advise methods if the module with the aspect is included after the methods are defined" do
67
67
  Traced1.new.doit
68
- Aquarium::Reusables::TraceMethods.advice_invoked?.should be_true
68
+ Aquarium::Reusables::TraceMethods.advice_invoked?.should be_truthy
69
69
  end
70
70
 
71
71
  it "should advise methods after the module with the aspect is included" do
72
72
  Traced2.new.doit
73
- Aquarium::Reusables::TraceMethods.advice_invoked?.should be_false
73
+ Aquarium::Reusables::TraceMethods.advice_invoked?.should be_falsey
74
74
  class Traced2
75
75
  include Aquarium::Reusables::TraceMethods
76
76
  end
77
77
  Traced2.new.doit
78
- Aquarium::Reusables::TraceMethods.advice_invoked?.should be_true
78
+ Aquarium::Reusables::TraceMethods.advice_invoked?.should be_truthy
79
79
  end
80
80
  end
@@ -0,0 +1,61 @@
1
+ # Rakefile for the separate testing of JRuby support
2
+ # (Separate because we need to run JRuby, not MRI...)
3
+
4
+ require 'rubygems'
5
+ require 'rake'
6
+ require 'rake/clean'
7
+
8
+ # Use RSpec's files.
9
+ require 'rspec/core/rake_task'
10
+
11
+ task :default => [:jruby]
12
+
13
+ task :jruby => [:aquarium_spec, :jruby_spec]
14
+
15
+ desc "Run all specs"
16
+ RSpec::Core::RakeTask.new do |t|
17
+ # t.spec_files = FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
18
+ t.rspec_opts = ['--colour'] + FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
19
+ end
20
+ task :spec => :verify_jruby
21
+
22
+ desc "Run all specs in reverse"
23
+ RSpec::Core::RakeTask.new(:spec_in_reverse) do |t|
24
+ #t.spec_files = FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
25
+ t.rspec_opts = ['--reverse', '--colour'] + FileList['spec/**/*_spec.rb', 'examples/**/*_spec.rb']
26
+ end
27
+ task :spec => :verify_jruby
28
+
29
+ desc "Run all of aquarium's specs using JRuby"
30
+ task :aquarium_spec => :verify_jruby do
31
+ output = nil
32
+ Dir.chdir '..' do
33
+ sh "rake spec"
34
+ end
35
+ end
36
+
37
+ task :verify_jruby do
38
+ unless self.class.const_defined? "JRUBY_VERSION"
39
+ raise "ERROR: You must run these rake tasks with jruby."
40
+ else
41
+ #raise "WARNING: JRuby support is not provided in this release. See ../CHANGES for details."
42
+ end
43
+ end
44
+
45
+ CLEAN.include('java/example.jar')
46
+ CLEAN.include('java/**/*.class')
47
+ SRC = FileList['java/**/*.java']
48
+ OBJ = SRC.ext('class')
49
+
50
+ rule '.class' => '.java' do |t|
51
+ sh "javac -cp java #{t.source}"
52
+ end
53
+
54
+ file 'java/example.jar' => OBJ do
55
+ classes = OBJ.map {|c| c.gsub(/^java\//, '')}
56
+ Dir.chdir 'java' do
57
+ sh "jar -cf example.jar #{classes}"
58
+ end
59
+ end
60
+
61
+ task :jruby_spec => ['java/example.jar', :spec, :spec_in_reverse]
@@ -0,0 +1,9 @@
1
+ package example;
2
+
3
+ /**
4
+ * An ad-hoc interface that demonstrates advising Java classes with Aquarium.
5
+ * See the specs that use this interface for examples of what you can and can't do with them!
6
+ */
7
+ public interface Worker<Input, Output> {
8
+ Output doWork(Input input);
9
+ }
@@ -0,0 +1,22 @@
1
+ package example.sorter;
2
+
3
+ import example.*;
4
+ import java.util.*;
5
+
6
+ /**
7
+ * An ad-hoc class that demonstrates advising Java classes with Aquarium.
8
+ * See the specs that use this class for examples of what you can and can't do with them!
9
+ */
10
+ public class StringListSorter implements Worker<List<String>, List<String>> {
11
+ protected Comparator<String> comparator;
12
+
13
+ public StringListSorter(Comparator<String> comparator) {
14
+ this.comparator = comparator;
15
+ }
16
+
17
+ public List<String> doWork(List<String> input) {
18
+ List<String> newList = new ArrayList<String>(input);
19
+ Collections.sort(newList, comparator);
20
+ return newList;
21
+ }
22
+ }
@@ -0,0 +1,42 @@
1
+ package example.sorter.converter;
2
+
3
+ import example.sorter.*;
4
+ import java.util.*;
5
+
6
+ /**
7
+ * A really ad-hoc, strange class that demonstrates advising Java classes with Aquarium.
8
+ * Disclaimer:
9
+ * Normally, the "and" in the class name would be a sign of a bad design and it's usually
10
+ * a bad idea to extend concreate classes and override concrete methods! So, don't take this
11
+ * class as an example of good Java design, please! ;)
12
+ */
13
+ public class StringListCaseConverterAndSorter extends StringListSorter {
14
+ private boolean convertToLowerCase = true;
15
+
16
+ public StringListCaseConverterAndSorter(boolean convertToLowerCase, Comparator<String> comparator) {
17
+ super(comparator);
18
+ this.convertToLowerCase = convertToLowerCase;
19
+ }
20
+
21
+ public StringListCaseConverterAndSorter(Comparator<String> comparator) {
22
+ super(comparator);
23
+ }
24
+
25
+ public List<String> doWork(List<String> input) {
26
+ List<String> newList = convertCase(input);
27
+ /* return super.doWork(newList); */
28
+ Collections.sort(newList, comparator);
29
+ return newList;
30
+ }
31
+
32
+ public List<String> convertCase(List<String> input) {
33
+ List<String> newList = new ArrayList<String>(input.size());
34
+ for (String s: input) {
35
+ if (convertToLowerCase)
36
+ newList.add(s.toLowerCase());
37
+ else
38
+ newList.add(s.toUpperCase());
39
+ }
40
+ return newList;
41
+ }
42
+ }