Move 2.0 changes collected in branches/pending back to trunk for further
[scons.git] / test / Java / Java-1.6.py
1 #!/usr/bin/env python
2 #
3 # __COPYRIGHT__
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #
24 from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
25
26 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
27
28 """
29 Test Java compilation with a live Java 1.6 "javac" compiler.
30 """
31
32 import os
33 import sys
34
35 import TestSCons
36
37 _python_ = TestSCons._python_
38
39 test = TestSCons.TestSCons()
40
41 where_javac, java_version = test.java_where_javac('1.6')
42
43
44
45 test.write('SConstruct', """
46 env = Environment(tools = ['javac'],
47                   JAVAVERSION = '1.6',
48                   JAVAC = r'%(where_javac)s')
49 env.Java(target = 'class1', source = 'com/sub/foo')
50 env.Java(target = 'class2', source = 'com/sub/bar')
51 env.Java(target = 'class3', source = ['src1', 'src2'])
52 env.Java(target = 'class4', source = ['src4'])
53 env.Java(target = 'class5', source = ['src5'])
54 env.Java(target = 'class6', source = ['src6'])
55 """ % locals())
56
57 test.subdir('com',
58             ['com', 'sub'],
59             ['com', 'sub', 'foo'],
60             ['com', 'sub', 'bar'],
61             'src1',
62             'src2',
63             'src4',
64             'src5',
65             'src6')
66
67 test.write(['com', 'sub', 'foo', 'Example1.java'], """\
68 package com.sub.foo;
69
70 public class Example1
71 {
72
73      public static void main(String[] args)
74      {
75
76      }
77
78 }
79 """)
80
81 test.write(['com', 'sub', 'foo', 'Example2.java'], """\
82 package com.other;
83
84 public class Example2
85 {
86
87      public static void main(String[] args)
88      {
89
90      }
91
92 }
93 """)
94
95 test.write(['com', 'sub', 'foo', 'Example3.java'], """\
96 package com.sub.foo;
97
98 public class Example3
99 {
100
101      public static void main(String[] args)
102      {
103
104      }
105
106 }
107 """)
108
109 test.write(['com', 'sub', 'bar', 'Example4.java'], """\
110 package com.sub.bar;
111
112 public class Example4
113 {
114
115      public static void main(String[] args)
116      {
117
118      }
119
120 }
121 """)
122
123 test.write(['com', 'sub', 'bar', 'Example5.java'], """\
124 package com.other;
125
126 public class Example5
127 {
128
129      public static void main(String[] args)
130      {
131
132      }
133
134 }
135 """)
136
137 test.write(['com', 'sub', 'bar', 'Example6.java'], """\
138 package com.sub.bar;
139
140 public class Example6
141 {
142
143      public static void main(String[] args)
144      {
145
146      }
147
148 }
149 """)
150
151 test.write(['src1', 'Example7.java'], """\
152 public class Example7
153 {
154
155      public static void main(String[] args)
156      {
157
158      }
159
160 }
161 """)
162
163 # Acid-test file for parsing inner Java classes, courtesy Chad Austin.
164 test.write(['src2', 'Test.java'], """\
165 class Empty {
166 }
167
168 interface Listener {
169   public void execute();
170 }
171
172 public
173 class
174 Test {
175   class Inner {
176     void go() {
177       use(new Listener() {
178         public void execute() {
179           System.out.println("In Inner");
180         }
181       });
182     }
183     String s1 = "class A";
184     String s2 = "new Listener() { }";
185     /* class B */
186     /* new Listener() { } */
187   }
188
189   public static void main(String[] args) {
190     new Test().run();
191   }
192
193   void run() {
194     use(new Listener() {
195       public void execute() {
196         use(new Listener( ) {
197           public void execute() {
198             System.out.println("Inside execute()");
199           }
200         });
201       }
202     });
203
204     new Inner().go();
205   }
206
207   void use(Listener l) {
208     l.execute();
209   }
210 }
211
212 class Private {
213   void run() {
214     new Listener() {
215       public void execute() {
216       }
217     };
218   }
219 }
220 """)
221
222 # Testing nested anonymous inner classes, courtesy Brandon Mansfield.
223 test.write(['src4', 'NestedExample.java'], """\
224 // import java.util.*;
225
226 public class NestedExample
227 {
228         public NestedExample()
229         {
230                 new Thread() {
231                         public void start()
232                         {
233                                 new Thread() {
234                                         public void start()
235                                         {
236                                                 try {Thread.sleep(200);}
237                                                 catch (Exception e) {}
238                                         }
239                                 };
240                                 while (true)
241                                 {
242                                         try {Thread.sleep(200);}
243                                         catch (Exception e) {}
244                                 }
245                         }
246                 };
247         }
248
249
250         public static void main(String argv[])
251         {
252                 new NestedExample();
253         }
254 }
255 """)
256
257 # Test not finding an anonymous class when the second token after a
258 # "new" is a closing brace.  This duplicates a test from the unit tests,
259 # but lets us make sure that we correctly determine that everything is
260 # up-to-date after the build.
261 test.write(['src5', 'TestSCons.java'], """\
262 class TestSCons {
263     public static void main(String[] args) {
264         Foo[] fooArray = new Foo[] { new Foo() };
265     }
266 }
267
268 class Foo { }
269 """)
270
271 # Test private inner class instantiation, courtesy Tilo Prutz:
272 #   http://scons.tigris.org/issues/show_bug.cgi?id=1594
273 test.write(['src6', 'TestSCons.java'], """\
274 class test
275 {
276     test()
277     {
278         super();
279         new inner();
280     }
281
282     static class inner
283     {
284         private inner() {}
285     }
286 }
287 """)
288
289
290
291 test.run(arguments = '.')
292
293 expect_1 = [
294     test.workpath('class1', 'com', 'other', 'Example2.class'),
295     test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
296     test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
297 ]
298
299 expect_2 = [
300     test.workpath('class2', 'com', 'other', 'Example5.class'),
301     test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
302     test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
303 ]
304
305 expect_3 = [
306     test.workpath('class3', 'Empty.class'),
307     test.workpath('class3', 'Example7.class'),
308     test.workpath('class3', 'Listener.class'),
309     test.workpath('class3', 'Private$1.class'),
310     test.workpath('class3', 'Private.class'),
311     test.workpath('class3', 'Test$1$1.class'),
312     test.workpath('class3', 'Test$1.class'),
313     test.workpath('class3', 'Test$Inner$1.class'),
314     test.workpath('class3', 'Test$Inner.class'),
315     test.workpath('class3', 'Test.class'),
316 ]
317
318 expect_4 = [
319     test.workpath('class4', 'NestedExample$1$1.class'),
320     test.workpath('class4', 'NestedExample$1.class'),
321     test.workpath('class4', 'NestedExample.class'),
322 ]
323
324 expect_5 = [
325     test.workpath('class5', 'Foo.class'),
326     test.workpath('class5', 'TestSCons.class'),
327 ]
328
329 expect_6 = [
330     test.workpath('class6', 'test$1.class'),
331     test.workpath('class6', 'test$inner.class'),
332     test.workpath('class6', 'test.class'),
333 ]
334
335 failed = None
336
337 def get_class_files(dir):
338     def find_class_files(arg, dirname, fnames):
339         for fname in fnames:
340             if fname[-6:] == '.class':
341                 arg.append(os.path.join(dirname, fname))
342     result = []
343     os.path.walk(dir, find_class_files, result)
344     result.sort()
345     return result
346
347 def classes_must_match(dir, expect):
348     global failed
349     got = get_class_files(test.workpath(dir))
350     if expect != got:
351         sys.stderr.write("Expected the following class files in '%s':\n" % dir)
352         for c in expect:
353             sys.stderr.write('    %s\n' % c)
354         sys.stderr.write("Got the following class files in '%s':\n" % dir)
355         for c in got:
356             sys.stderr.write('    %s\n' % c)
357         failed = 1
358
359 def classes_must_not_exist(dir, expect):
360     global failed
361     present = list(filter(os.path.exists, expect))
362     if present:
363         sys.stderr.write("Found the following unexpected class files in '%s' after cleaning:\n" % dir)
364         for c in present:
365             sys.stderr.write('    %s\n' % c)
366         failed = 1
367
368 classes_must_match('class1', expect_1)
369 classes_must_match('class2', expect_2)
370 classes_must_match('class3', expect_3)
371 classes_must_match('class4', expect_4)
372 classes_must_match('class5', expect_5)
373 classes_must_match('class6', expect_6)
374
375 test.fail_test(failed)
376
377 test.up_to_date(options='--debug=explain', arguments = '.')
378
379 test.run(arguments = '-c .')
380
381 classes_must_not_exist('class1', expect_1)
382 classes_must_not_exist('class2', expect_2)
383 classes_must_not_exist('class3', expect_3)
384 classes_must_not_exist('class4', expect_4)
385 classes_must_not_exist('class5', expect_5)
386 # This test case should pass, but doesn't.
387 # The expect_6 list contains the class files that the Java compiler
388 # actually creates, apparently because of the "private" instantiation
389 # of the "inner" class.  Our parser doesn't currently detect this, so
390 # it doesn't know to remove that generated class file.
391 #classes_must_not_exist('class6', expect_6)
392
393 test.fail_test(failed)
394
395 test.pass_test()
396
397 # Local Variables:
398 # tab-width:4
399 # indent-tabs-mode:nil
400 # End:
401 # vim: set expandtab tabstop=4 shiftwidth=4: