52f03ebcf932f6b5e07acefab2fc5d89bf697e3e
[ruby_koans.git] / src / about_java_interop.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 include Java
4
5 # Concepts
6 # * Pull in a java class
7 # * calling a method, Camel vs snake
8 # * Resovling module/class name conflicts
9 # * Showing what gets returned
10 # * Ruby Strings  VS Java Strings
11 # * Calling custom java class
12 # * Calling Ruby from java???
13
14 class AboutJavaInterop < EdgeCase::Koan
15   def test_using_a_java_library_class
16     java_array = java.util.ArrayList.new
17     assert_equal __(Java::JavaUtil::ArrayList), java_array.class
18   end
19
20   def test_java_class_can_be_referenced_using_both_ruby_and_java_like_syntax
21     assert_equal __(true), Java::JavaUtil::ArrayList == java.util.ArrayList
22   end
23
24   def test_include_class_includes_class_in_module_scope
25     assert_nil defined?(TreeSet) # __
26     include_class "java.util.TreeSet"
27     assert_equal __("constant"), defined?(TreeSet)
28   end
29
30   # THINK ABOUT IT:
31   #
32   # What if we use:
33   #
34   #   include_class "java.lang.String"
35   #
36   # What would be the value of the String constant after this
37   # include_class is run?  Would it be useful to provide a way of
38   # aliasing java classes to different names?
39
40   JString = java.lang.String
41   def test_also_java_class_can_be_given_ruby_aliases
42     java_string = JString.new("A Java String")
43     assert_equal __(java.lang.String), java_string.class
44     assert_equal __(java.lang.String), JString
45   end
46
47   def test_can_directly_call_java_methods_on_java_objects
48     java_string = JString.new("A Java String")
49     assert_equal __("a java string"), java_string.toLowerCase
50   end
51
52   def test_jruby_provides_snake_case_versions_of_java_methods
53     java_string = JString.new("A Java String")
54     assert_equal __("a java string"), java_string.to_lower_case
55   end
56
57   def test_jruby_provides_question_mark_versions_of_boolean_methods
58     java_string = JString.new("A Java String")
59     assert_equal __(true), java_string.endsWith("String")
60     assert_equal __(true), java_string.ends_with("String")
61     assert_equal __(true), java_string.ends_with?("String")
62   end
63
64   def test_java_string_are_not_ruby_strings
65     ruby_string = "A Java String"
66     java_string = java.lang.String.new(ruby_string)
67     assert_equal __(true), java_string.is_a?(java.lang.String)
68     assert_equal __(false), java_string.is_a?(String)
69   end
70
71   def test_java_strings_can_be_compared_to_ruby_strings_maybe
72     ruby_string = "A Java String"
73     java_string = java.lang.String.new(ruby_string)
74     assert_equal __(false), ruby_string == java_string
75     assert_equal __(true), java_string == ruby_string
76
77     # THINK ABOUT IT:
78     #
79     # Is there any possible way for this to be more wrong?
80     #
81     # SERIOUSLY, THINK ABOUT IT:
82     #
83     # Why do you suppose that Ruby and Java strings compare like that?
84     #
85     # ADVANCED THINK ABOUT IT:
86     #
87     # Is there a way to make Ruby/Java string comparisons commutative?
88     # How would you do it?
89   end
90
91   def test_however_most_methods_returning_strings_return_ruby_strings
92     java_array = java.util.ArrayList.new
93     assert_equal __("[]"), java_array.toString
94     assert_equal __(true), java_array.toString.is_a?(String)
95     assert_equal __(false), java_array.toString.is_a?(java.lang.String)
96   end
97
98   def test_some_ruby_objects_can_be_coerced_to_java
99     assert_equal __(Java::JavaLang::String), "ruby string".to_java.class
100     assert_equal __(Java::JavaLang::Long), 1.to_java.class
101     assert_equal __(Java::JavaLang::Double), 9.32.to_java.class
102     assert_equal __(Java::JavaLang::Boolean), false.to_java.class
103   end
104
105   def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect
106     assert_equal __(false), [].to_java.class == Java::JavaUtil::ArrayList
107     assert_equal __(false), {}.to_java.class == Java::JavaUtil::HashMap
108     assert_equal __(false), Object.new.to_java.class == Java::JavaLang::Object
109   end
110
111   def test_java_collections_are_enumerable
112     java_array = java.util.ArrayList.new
113     java_array << "one" << "two" << "three"
114     assert_equal __(["ONE", "TWO", "THREE"]), java_array.map { |item| item.upcase }
115   end
116
117   # ------------------------------------------------------------------
118
119   # Open the Java ArrayList class and add a new method.
120   class Java::JavaUtil::ArrayList
121     def multiply_all
122       result = 1
123       each do |item|
124         result *= item
125       end
126       result
127     end
128   end
129
130   def test_java_class_are_open_from_ruby
131     java_array = java.util.ArrayList.new
132     java_array.add_all([1,2,3,4,5])
133
134     assert_equal __(120), java_array.multiply_all
135   end
136
137 end