aquarium 0.5.1 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +240 -215
- data/README +61 -44
- data/RELEASE-PLAN +21 -23
- data/Rakefile +64 -94
- data/UPGRADE +45 -35
- data/aquarium.gemspec +50 -0
- data/examples/README.txt +6 -0
- data/examples/aspect_design_example_spec.rb +2 -2
- data/examples/design_by_contract_example_spec.rb +3 -3
- data/examples/exception_wrapping_example_spec.rb +2 -2
- data/examples/introductions_example_spec.rb +1 -1
- data/examples/method_tracing_example_spec.rb +17 -16
- data/examples/reusable_aspect_hack_example_spec.rb +5 -5
- data/jruby/Rakefile +61 -0
- data/jruby/java/example/Worker.java +9 -0
- data/jruby/java/example/sorter/StringListSorter.java +22 -0
- data/jruby/java/example/sorter/converter/StringListCaseConverterAndSorter.java +42 -0
- data/jruby/java/example/visibility/Visibility.java +13 -0
- data/jruby/spec/java_class_aspects_spec.rb +434 -0
- data/jruby/spec/java_visibility_spec.rb +122 -0
- data/jruby/spec/spec_helper.rb +5 -0
- data/lib/aquarium/aspects/aspect.rb +8 -4
- data/lib/aquarium/utils/type_utils.rb +4 -1
- data/lib/aquarium/version.rb +29 -28
- data/previous_failures.txt +0 -0
- data/rspec.watchr +60 -0
- data/spec/aquarium/aspects/advice_spec.rb +10 -10
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +79 -79
- data/spec/aquarium/aspects/aspect_spec.rb +73 -73
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +5 -5
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
- data/spec/aquarium/aspects/default_objects_handler_spec.rb +5 -5
- data/spec/aquarium/aspects/join_point_spec.rb +40 -40
- data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +8 -8
- data/spec/aquarium/aspects/pointcut_spec.rb +25 -25
- data/spec/aquarium/extensions/regex_spec.rb +6 -6
- data/spec/aquarium/extras/design_by_contract_spec.rb +6 -6
- data/spec/aquarium/finders/finder_result_spec.rb +2 -2
- data/spec/aquarium/finders/method_finder_spec.rb +24 -24
- data/spec/aquarium/finders/pointcut_finder_spec.rb +10 -10
- data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +4 -4
- data/spec/aquarium/finders/type_finder_spec.rb +5 -5
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +6 -5
- data/spec/aquarium/finders/type_finder_with_nested_types_spec.rb +2 -2
- data/spec/aquarium/utils/logic_error_spec.rb +1 -1
- data/spec/aquarium/utils/method_utils_spec.rb +38 -38
- data/spec/aquarium/utils/nil_object_spec.rb +11 -11
- data/spec/aquarium/utils/options_utils_spec.rb +8 -8
- data/spec/aquarium/utils/type_utils_spec.rb +3 -3
- 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'
|
data/aquarium.gemspec
ADDED
@@ -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
|
data/examples/README.txt
ADDED
@@ -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.
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
73
|
-
foo.logged_messages[
|
74
|
-
foo.logged_messages[
|
75
|
-
foo.logged_messages[
|
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].
|
118
|
-
bar.logged_messages[1].
|
119
|
-
bar.logged_messages[2].
|
120
|
-
bar.logged_messages[3].
|
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].
|
143
|
-
foo.logged_messages[1].
|
144
|
-
foo.logged_messages[2].
|
145
|
-
foo.logged_messages[3].
|
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].
|
151
|
-
bar.logged_messages[1].
|
152
|
-
bar.logged_messages[2].
|
153
|
-
bar.logged_messages[3].
|
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
|
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
|
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
|
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
|
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
|
78
|
+
Aquarium::Reusables::TraceMethods.advice_invoked?.should be_truthy
|
79
79
|
end
|
80
80
|
end
|
data/jruby/Rakefile
ADDED
@@ -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
|
+
}
|