Ticket #673: dojo-anttest-patch.txt

File dojo-anttest-patch.txt, 31.2 kB (added by jkuhnert@…, 3 years ago)

The patch

Line 
1
2Property changes on: /home/jkuhnert/projects/dojo
3___________________________________________________________________
4Name: svn:ignore
5   - .project
6release
7testRunner.js
8
9   +
10.project
11release
12testRunner.js
13TestNG context suite.launch
14dojo_org.dojotoolkit.*
15bin
16.settings
17.classpath
18
19
20
21Property changes on: /home/jkuhnert/projects/dojo/buildscripts
22___________________________________________________________________
23Name: svn:ignore
24   - *.class
25test.txt
26test.bat
27
28   +
29*.class
30test.txt
31test.bat
32build
33output
34dist
35
36
37Index: /home/jkuhnert/projects/dojo/buildscripts/src/test/org/dojotoolkit/ant/TestDojoTestTask.java
38===================================================================
39--- /home/jkuhnert/projects/dojo/buildscripts/src/test/org/dojotoolkit/ant/TestDojoTestTask.java        (revision 0)
40+++ /home/jkuhnert/projects/dojo/buildscripts/src/test/org/dojotoolkit/ant/TestDojoTestTask.java        (revision 0)
41@@ -0,0 +1,106 @@
42+package org.dojotoolkit.ant;
43+
44+import static org.testng.AssertJUnit.assertEquals;
45+import static org.testng.AssertJUnit.assertNotNull;
46+
47+import java.io.IOException;
48+
49+import org.apache.tools.ant.BuildException;
50+import org.apache.tools.ant.Project;
51+import org.mozilla.javascript.Context;
52+import org.mozilla.javascript.tools.shell.Global;
53+import org.testng.annotations.ExpectedExceptions;
54+import org.testng.annotations.Test;
55+
56+/**
57+ * Tests functionality of {@link DojoTestTask}.
58+ *
59+ * @author jkuhnert
60+ */
61+public class TestDojoTestTask {
62+       
63+       @Test
64+       @ExpectedExceptions({BuildException.class})
65+       public void testNoConfig()
66+       {
67+               DojoTestTask task = newTask();
68+               task.execute();
69+       }
70+       
71+       @Test
72+       @ExpectedExceptions({BuildException.class})
73+       public void testBadConfig()
74+       {
75+               DojoTestTask task = newTask();
76+               task.setDojoSrc("../../thisaintdojo");
77+               
78+               task.execute();
79+       }
80+       
81+       @Test
82+       public void testDefault()
83+       throws IOException
84+       {
85+               DojoTestTask task = newTask();
86+               task.setDojoSrc(".");
87+               task.setTestSrc("buildscripts/src/test-data/tests");
88+               
89+               task.validate();
90+               
91+               String[] tests = task.getTestFiles();
92+               assertNotNull(tests);
93+               assertEquals(2, tests.length);
94+               
95+               String basePath = task.getProject().getBaseDir().getAbsolutePath();
96+               
97+               String scriptArg = "djConfig = { \n" +
98+                               "       baseRelativePath: \"" + basePath + "/\",\n" +
99+                               "       isDebug: true\n" +
100+                               "};\n" +
101+                               "\n" +
102+                               "load(\"" + basePath + "/dojo.js\");\n" +
103+                               "\n" +
104+                               "load(\"" + basePath + "/tests/prologue.js\", \n" +
105+                               "       \"" + basePath + "/testtools/JsFakeDom/BUFakeDom.js\", \n" +
106+                               "       \"" + basePath + "/testtools/JsTestManager/jsunit_wrap.js\");\n" +
107+                               "load(\"" + basePath + "/tests/test_date.js\");\n" +
108+                               "load(\"" + basePath + "/tests/test_dom.js\");" +
109+                               "load(\"" + basePath + "/tests/epilogue.js\");\n" +
110+                               "jum.init();\n" +
111+                               "jum.runAll();";
112+               
113+               Context cx = Context.enter();
114+               try {
115+                       Global lGlobal = new Global(cx);
116+                       
117+                       cx.compileString(
118+                                       scriptArg,
119+                                       "djconfig", 1 , null
120+                       ).exec(cx, lGlobal);
121+                       
122+               } finally {
123+                       Context.exit();
124+               }
125+       }
126+       
127+       @Test
128+       public void testRunTests()
129+       {
130+               DojoTestTask task = newTask();
131+               task.setDojoSrc(".");
132+               task.setTestSrc("buildscripts/src/test-data/tests");
133+               
134+               task.execute();
135+       }
136+       
137+       protected DojoTestTask newTask()
138+       {
139+               Project project = new Project();
140+               project.setBasedir(System.getProperty("basedir", "."));
141+               
142+               DojoTestTask task = new DojoTestTask();
143+               task.setProject(project);
144+               
145+               return task;
146+       }
147+}
148Index: /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/ant/DojoTestTask.java
149===================================================================
150--- /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/ant/DojoTestTask.java    (revision 0)
151+++ /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/ant/DojoTestTask.java    (revision 0)
152@@ -0,0 +1,267 @@
153+package org.dojotoolkit.ant;
154+
155+import java.io.BufferedInputStream;
156+import java.io.File;
157+import java.io.FileOutputStream;
158+import java.io.IOException;
159+import java.net.MalformedURLException;
160+import java.net.URL;
161+import java.text.CharacterIterator;
162+import java.text.StringCharacterIterator;
163+
164+import org.apache.tools.ant.BuildException;
165+import org.apache.tools.ant.DirectoryScanner;
166+import org.apache.tools.ant.Project;
167+import org.apache.tools.ant.Task;
168+import org.apache.tools.ant.taskdefs.Execute;
169+import org.apache.tools.ant.types.CommandlineJava;
170+import org.apache.tools.ant.types.FileSet;
171+import org.dojotoolkit.DojoTest;
172+
173+/**
174+ * Represents an ant task the simplifies the dependency / build
175+ * issues associated with trying to use the dojo test system
176+ * outside of dojo.
177+ *
178+ * @author jkuhnert
179+ */
180+public class DojoTestTask extends Task {
181+       
182+       // The directory containing dojo, compressed or in original form
183+       private String _dojoSrc;
184+       // The directory containg tests to be run
185+       private String _testSrc;
186+       // The directory any tempory output is written to, goes to java.io.tmpdir by default
187+       private String _outputTargetDir;
188+       
189+       private File _dojoDir;
190+       private File _testDir;
191+       private File _outputDir;
192+       
193+       public void setDojoSrc(String dojosrc) { _dojoSrc = dojosrc; }
194+       public void setTestSrc(String testsrc) { _testSrc = testsrc; }
195+       public void setOutputDir(String outputdir) { _outputTargetDir = outputdir; }
196+       
197+       /**
198+        * Validates that required parameters are set.
199+        * @throws BuildException on error
200+        */
201+       void validate()
202+       {
203+               if (_dojoSrc == null) throw new BuildException("dojosrc not set");
204+               if (_testSrc == null) throw new BuildException("testsrc not set");
205+               
206+               _dojoDir = getProject().resolveFile(_dojoSrc);
207+               _testDir = getProject().resolveFile(_testSrc);
208+               
209+               // output defaults to system tmp dir if not set
210+               if (_outputTargetDir != null) _outputDir = getProject().resolveFile(_outputTargetDir);
211+               else _outputDir = new File(System.getProperty("java.io.tmpdir"));
212+       }
213+       
214+       /**
215+        * Gets all files matching <code>test*.js</code> in the
216+        * specified <code>testsrc</code> directory.
217+        * @return The set of files found, if any.
218+        */
219+       String[] getTestFiles()
220+       {
221+               FileSet fs = new FileSet();
222+               fs.setIncludes("**/test*.js");
223+               fs.setFollowSymlinks(true);
224+               fs.setDir(_testDir);
225+               
226+               DirectoryScanner ds = fs.getDirectoryScanner(getProject());
227+               return ds.getIncludedFiles();
228+       }
229+       
230+       /**
231+        * Ensures that all needed test.js files are
232+        * present in the temporary output directory.
233+        *
234+        * Files would be things like prologue.js,jsunit_wrap.js,etc..
235+        */
236+       void prepareOutput()
237+       throws IOException
238+       {
239+               log("Preparing output directory.");
240+               
241+               checkFile("prologue.js", "tests");
242+               checkFile("BUFakeDom.js", "testtools/JsFakeDom");
243+               checkFile("jsunit_wrap.js", "testtools/JsTestManager");
244+               checkFile("epilogue.js", "tests");
245+       }
246+       
247+       /**
248+        * Checks for the existance of the specified
249+        * file in the output directory, if not present
250+        * attempts to grab it from the current ClassLoader (if in a jar),
251+        * or from the filesystem if dojo src is pointed at
252+        * the dojo project folder.
253+        *
254+        * @param fileName
255+        *                      The file to check for existance of.
256+        * @param localPath
257+        *                      Optional locally resolvable path if task being executed
258+        *                      against dojo project sources.
259+        */
260+       void checkFile(String fileName, String localPath)
261+       throws IOException
262+       {
263+               File file = new File(_outputDir.getAbsolutePath() + "/" + fileName);
264+               if (file.exists()) return;
265+               
266+               if (localPath != null) {
267+                       File local = getProject().resolveFile(localPath + "/" + fileName);
268+                       if (local.exists()) {
269+                               getProject().copyFile(local, file);
270+                               return;
271+                       }
272+               }
273+               
274+               byte[] data = new byte[3000];
275+               BufferedInputStream bi =
276+                       new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(fileName));
277+               int read = 0;
278+               
279+               FileOutputStream out =
280+                       new FileOutputStream(_outputDir.getAbsolutePath() + "/" + fileName);
281+               
282+               while ((read = bi.read(data)) > -1 ) {
283+                       out.write(data, 0, read);
284+               }
285+               
286+               bi.close();
287+               out.close();
288+       }
289+       
290+       /**
291+        * The main method executed by ant tasks.
292+        */
293+       public void execute()
294+       {
295+               validate();
296+               
297+               try {
298+                       prepareOutput();
299+               } catch (Throwable t) { throw new BuildException(t); }
300+               
301+               String[] tests = getTestFiles();
302+               if (tests == null || tests.length < 1) {
303+                       log("No tests found.");
304+                       return;
305+               }
306+               
307+               Execute execute = new Execute();
308+               execute.setAntRun(getProject());
309+               
310+               CommandlineJava cmd = new CommandlineJava();
311+               cmd.createClasspath(getProject()).createPath().setLocation(findJar());
312+               cmd.setClassname("org.dojotoolkit.DojoTest");
313+               
314+               cmd.createArgument().setValue(DojoTest.ARG_DOJO_DIR);
315+               cmd.createArgument().setFile(_dojoDir);
316+               cmd.createArgument().setValue(DojoTest.ARG_OUTPUT_DIR);
317+               cmd.createArgument().setFile(_outputDir);
318+               cmd.createArgument().setValue(DojoTest.ARG_TEST_DIR);
319+               cmd.createArgument().setFile(_testDir);
320+               
321+               cmd.createArgument().setValue(DojoTest.ARG_TEST_FILES);
322+               for (int i=0; i < tests.length; i++)
323+                       cmd.createArgument().setValue(tests[i]);
324+               
325+               execute.setCommandline(cmd.getCommandline());
326+               
327+               log(cmd.describeCommand(), Project.MSG_VERBOSE);
328+               
329+               log("Executing dojo tests.");
330+               
331+               try {
332+                       execute.execute();
333+               }
334+               catch (IOException e) {
335+                       throw new BuildException("Process fork failed.", e, getLocation());
336+               }
337+       }
338+       
339+       /**
340+        * Stolen from TestNG. Resolves the jar file that this class is running in.
341+        *
342+        * @return The file if found, null otherwise.
343+        */
344+       private File findJar() {
345+               Class  thisClass = getClass();
346+               String resource = thisClass.getName().replace('.', '/') + ".class";
347+               URL url = thisClass.getClassLoader().getResource(resource);
348+               
349+               if(null != url) {
350+                       String u = url.toString();
351+                       if(u.startsWith("jar:file:")) {
352+                               int    pling = u.indexOf("!");
353+                               String jarName = u.substring(4, pling);
354+                               return new File(fromURI(jarName));
355+                       }
356+                       else if(u.startsWith("file:")) {
357+                               int    tail = u.indexOf(resource);
358+                               String dirName = u.substring(0, tail);
359+                               return new File(fromURI(dirName));
360+                       }
361+               }
362+
363+               return null;
364+       }
365+       
366+       /**
367+        * Stolen from TestNG, resolves uris.
368+        * @param uri
369+        * @return
370+        */
371+       private String fromURI(String uri) {
372+               URL url = null;
373+               try {
374+                       url = new URL(uri);
375+               }
376+               catch(MalformedURLException murle) {
377+               }
378+               if((null == url) || !("file".equals(url.getProtocol()))) {
379+                       throw new IllegalArgumentException("Can only handle valid file: URIs");
380+               }
381+
382+               StringBuffer buf = new StringBuffer(url.getHost());
383+               if(buf.length() > 0) {
384+                       buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
385+               }
386+
387+               String file = url.getFile();
388+               int    queryPos = file.indexOf('?');
389+               buf.append((queryPos < 0) ? file : file.substring(0, queryPos));
390+
391+               uri = buf.toString().replace('/', File.separatorChar);
392+
393+               if((File.pathSeparatorChar == ';') && uri.startsWith("\\") && (uri.length() > 2)
394+                               && Character.isLetter(uri.charAt(1)) && (uri.lastIndexOf(':') > -1)) {
395+                       uri = uri.substring(1);
396+               }
397+               
398+               StringBuffer      sb = new StringBuffer();
399+               CharacterIterator iter = new StringCharacterIterator(uri);
400+               for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
401+                       if(c == '%') {
402+                               char c1 = iter.next();
403+                               if(c1 != CharacterIterator.DONE) {
404+                                       int  i1 = Character.digit(c1, 16);
405+                                       char c2 = iter.next();
406+                                       if(c2 != CharacterIterator.DONE) {
407+                                               int i2 = Character.digit(c2, 16);
408+                                               sb.append((char) ((i1 << 4) + i2));
409+                                       }
410+                               }
411+                       }
412+                       else {
413+                               sb.append(c);
414+                       }
415+               }
416+
417+               return sb.toString();
418+       }
419+}
420Index: /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/DojoTest.java
421===================================================================
422--- /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/DojoTest.java    (revision 0)
423+++ /home/jkuhnert/projects/dojo/buildscripts/src/java/org/dojotoolkit/DojoTest.java    (revision 0)
424@@ -0,0 +1,210 @@
425+package org.dojotoolkit;
426+
427+import java.io.File;
428+
429+import org.mozilla.javascript.Context;
430+import org.mozilla.javascript.tools.shell.Global;
431+
432+/**
433+ * Core class for running dojo based tests within
434+ * a Rhino execution environment.
435+ *
436+ * @author jkuhnert
437+ */
438+public class DojoTest {
439+
440+       public static final String ARG_OUTPUT_DIR = "outputdir";
441+       public static final String ARG_DOJO_DIR = "dojodir";
442+       public static final String ARG_TEST_DIR = "testdir";
443+       public static final String ARG_TEST_FILES = "testfiles";
444+       
445+       private String[] _testFiles;
446+       private File _dojoDir;
447+       private File _outputDir;
448+       private File _testDir;
449+       
450+       /**
451+        * Default constructor.
452+        */
453+       public DojoTest()
454+       {
455+       }
456+       
457+       /**
458+        * Sets the set of javascript file paths to be run in this
459+        * test.
460+        * @param testFiles
461+        */
462+       public void setTestFiles(String[] testFiles)
463+       {
464+               _testFiles = testFiles;
465+       }
466+       
467+       /**
468+        * Sets the root dojo source directory. This
469+        * can be either the path to a checked out dojo
470+        * source project or a built dojo release.
471+        * @param dojoDir
472+        */
473+       public void setDojoDir(File dojoDir)
474+       {
475+               _dojoDir = dojoDir;
476+       }
477+       
478+       /**
479+        * The output directory where the required helper
480+        * javascript files are expected to be found. (epilogue.js/BUFakeDom.js/etc..)
481+        * @param outputDir
482+        */
483+       public void setOutputDir(File outputDir)
484+       {
485+               _outputDir = outputDir;
486+       }
487+       
488+       /**
489+        * Sets the absolute path to the root test directory.
490+        * @param testDir
491+        */
492+       public void setTestDir(File testDir)
493+       {
494+               _testDir = testDir;
495+       }
496+       
497+       /**
498+        * Causes the tests to be run.
499+        */
500+       public void execute()
501+       {
502+               Context cx = Context.enter();
503+               try {
504+                       Global global = new Global(cx);
505+                       
506+                       execString(cx, global,
507+                                       "djConfig = { \n" +
508+                                       "       baseRelativePath: \"" + _dojoDir.getAbsolutePath() + "/\",\n" +
509+                                       "       isDebug: true\n" +
510+                                       "};\n",
511+                                       "djConfig"
512+                       );
513+                       
514+                       String path = _outputDir.getAbsolutePath() + "/";
515+                       
516+                       execString(cx, global,
517+                                       "load('" + _dojoDir.getAbsolutePath() + "/dojo.js');",
518+                                       "dojo.js"
519+                       );
520+                       
521+                       execString(cx, global,
522+                                       "load('" + path + "prologue.js');",
523+                                       "prologue.js"
524+                       );
525+                       
526+                       execString(cx, global,
527+                                       "load('" + path + "BUFakeDom.js');",
528+                                       "BUFakeDom.js"
529+                       );
530+                       
531+                       execString(cx, global,
532+                                       "load('" + path + "jsunit_wrap.js');",
533+                                       "jsunit_wrap.js"
534+                       );
535+                       
536+                       for (int i=0; i < _testFiles.length; i++) {
537+                               execString(cx, global,
538+                                               "load('" + _testDir.getAbsolutePath() + "/" + _testFiles[i] + "');",
539+                                               _testFiles[i]
540+                               );
541+                       }
542+                       
543+                       execString(cx, global,
544+                                       "load('" + path + "epilogue.js');",
545+                                       "epilogue.js"
546+                       );
547+                       
548+                       execString(cx, global,
549+                                       "jum.init();jum.runAll();",
550+                                       "jum"
551+                       );
552+               } finally {
553+                       Context.exit();
554+               }
555+       }
556+       
557+       /**
558+        * Executes a javascript string. This method wraps the execution
559+        * of the specified string to catch and output any exceptions, this
560+        * is so that any test failures don't prevent the whole build from
561+        * running.
562+        *
563+        * @param cx
564+        * @param global
565+        * @param str
566+        * @param file
567+        */
568+       void execString(Context cx, Global global, String str, String file)
569+       {
570+               try {
571+                       cx.compileString(
572+                                       str,
573+                                       file, 1 , null
574+                       ).exec(cx, global);
575+               } catch (Throwable t) {
576+                       System.out.println(t.getMessage());
577+               }
578+       }
579+       
580+       /**
581+        * Prints a usage message when invoked with incorrect arguments
582+        * from the command line.
583+        */
584+       void printUsage()
585+       {
586+               System.out.println("Usage: DojoTest "
587+                               + DojoTest.ARG_DOJO_DIR + " <dojo path> "
588+                               + DojoTest.ARG_OUTPUT_DIR + " <output path> "
589+                               + DojoTest.ARG_TEST_DIR + " <test dir path> "
590+                               + DojoTest.ARG_TEST_FILES + " <list of space seperated test file paths> ");
591+       }
592+       
593+       /**
594+        * Main entry point when invoked from command line.
595+        * @param args
596+        */
597+       public static void main(String[] args)
598+       {
599+               DojoTest test = new DojoTest();
600+               
601+               // validate arguments
602+               if (args == null || args.length < 8) {
603+                       test.printUsage();
604+                       System.exit(-1);
605+               }
606+               
607+               // grab initial configuration
608+               for (int i=0; i < 6; i++) {
609+                       if (DojoTest.ARG_DOJO_DIR.equals(args[i])) {
610+                               test.setDojoDir(new File(args[i + 1]));
611+                               i++;
612+                               continue;
613+                       }
614+                       
615+                       if (DojoTest.ARG_OUTPUT_DIR.equals(args[i])) {
616+                               test.setOutputDir(new File(args[i + 1]));
617+                               i++;
618+                               continue;
619+                       }
620+                       
621+                       if (DojoTest.ARG_TEST_DIR.equals(args[i])) {
622+                               test.setTestDir(new File(args[i + 1]));
623+                               i++;
624+                               continue;
625+                       }
626+               }
627+               
628+               String[] testFiles = new String[args.length - 7];
629+               System.arraycopy(args, 7, testFiles, 0, testFiles.length);
630+               test.setTestFiles(testFiles);
631+               
632+               test.execute();
633+       }
634+}
635Index: /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/widget/test_Widget.js
636===================================================================
637--- /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/widget/test_Widget.js (revision 0)
638+++ /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/widget/test_Widget.js (revision 0)
639@@ -0,0 +1,8 @@
640+dojo.require("dojo.widget.Widget");
641+
642+function test_widget_ctor(){
643+       jum.debug("in widget.ctor");
644+       var obj1 = new dojo.widget.Widget();
645+       
646+       jum.assertTrue("test1", typeof obj1 == "object");
647+}
648Index: /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/test_dom.js
649===================================================================
650--- /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/test_dom.js   (revision 0)
651+++ /home/jkuhnert/projects/dojo/buildscripts/src/test-data/tests/test_dom.js   (revision 0)
652@@ -0,0 +1,202 @@
653+dojo.require("dojo.dom");
654+
655+function test_dom_sanityCheck(){
656+       var td = document.createElement("div");
657+       td.appendChild(document.createTextNode("foo"));
658+       td.appendChild(document.createCDATASection("bar"));
659+       var td2 = document.createElement("div");
660+       td.appendChild(td2);
661+       jum.assertEquals("test1", 3, td.childNodes.length);
662+}
663+
664+function test_dom_getTagName(){
665+       var td = document.createElement("div");
666+       td.setAttribute("dojoType", "foo");
667+       jum.assertEquals("test10", "dojo:foo", dojo.dom.getTagName(td));
668+
669+       var td2 = document.createElement("div");
670+       jum.assertEquals("test20", "div", dojo.dom.getTagName(td2));
671+
672+       var td3 = document.createElement("div");
673+       td3.setAttribute("class", "dojo-foo");
674+       jum.assertEquals("test30", "dojo:foo", dojo.dom.getTagName(td3));
675+}
676+
677+function test_dom_getUniqueId(){
678+       var td = document.createElement("div");
679+       td.setAttribute("id", "dj_unique_1");
680+       document.body.appendChild(td);
681+       jum.assertEquals("test40", "dj_unique_2", dojo.dom.getUniqueId());
682+}
683+
684+function test_dom_getFirstChildElement(){
685+       var td = document.createElement("div");
686+       td.appendChild(document.createTextNode("foo"));
687+       td.appendChild(document.createCDATASection("bar"));
688+       var td2 = document.createElement("div");
689+       td.appendChild(td2);
690+       jum.assertTrue("test50", dojo.dom.getFirstChildElement(td) === td2);
691+}
692+
693+function test_dom_getLastChildElement(){
694+       var td = document.createElement("div");
695+       var td2 = document.createElement("div");
696+       td.appendChild(td2);
697+       td.appendChild(document.createTextNode("foo"));
698+       td.appendChild(document.createCDATASection("bar"));
699+       jum.assertTrue("test60", dojo.dom.getLastChildElement(td) === td2);
700+}
701+
702+function test_dom_getNextSiblingElement(){
703+       var td = document.createElement("div");
704+       var td2 = document.createElement("div");
705+       td.appendChild(td2);
706+       td.appendChild(document.createTextNode("foo"));
707+       var td3 = document.createElement("div");
708+       td.appendChild(td3);
709+       td.appendChild(document.createCDATASection("bar"));
710+       jum.assertTrue("test70", dojo.dom.getNextSiblingElement(td2) === td3);
711+       jum.assertTrue("test71", dojo.dom.nextElement(td2) === td3);
712+       jum.assertTrue("test80", dojo.dom.getNextSiblingElement(td3) === null);
713+       jum.assertTrue("test81", dojo.dom.nextElement(td3) === null);
714+}
715+
716+function test_dom_getPreviousSiblingElement(){
717+       var td = document.createElement("div");
718+       var td2 = document.createElement("div");
719+       td.appendChild(td2);
720+       td.appendChild(document.createTextNode("foo"));
721+       var td3 = document.createElement("div");
722+       td.appendChild(td3);
723+       td.appendChild(document.createCDATASection("bar"));
724+       jum.assertTrue("test90", dojo.dom.getPreviousSiblingElement(td3) === td2);
725+       jum.assertTrue("test91", dojo.dom.prevElement(td3) === td2);
726+       jum.assertTrue("test100", dojo.dom.getPreviousSiblingElement(td2) === null);
727+       jum.assertTrue("test101", dojo.dom.prevElement(td2) === null);
728+}
729+
730+function test_dom_moveChildrenNoTrim(){
731+       var td = document.createElement("div");
732+       var td2 = document.createElement("div");
733+       var td3 = document.createElement("div");
734+       td.appendChild(td2);
735+       td.appendChild(document.createTextNode("foo"));
736+       td.appendChild(td3);
737+       td.appendChild(document.createCDATASection("bar"));
738+       var ts = document.createElement("span");
739+       var moved = dojo.dom.moveChildren(td, ts, false);
740+       jum.assertEquals("test110", 4, moved);
741+       jum.assertEquals("test120", 4, ts.childNodes.length);
742+       jum.assertEquals("test130", 0, td.childNodes.length);
743+       jum.assertFalse("test140", td.hasChildNodes());
744+}
745+
746+function test_dom_moveChildrenWithTrim(){
747+       // FIXME: this method is very weird. It only seems to trim text nodes and
748+       // not CDATA sections or other non-printing node types, but I'm not sure if
749+       // it's a bug in the method or my understanding of it
750+       var td = document.createElement("div");
751+       var td2 = document.createElement("div");
752+       var td3 = document.createElement("div");
753+       td.appendChild(td2);
754+       td.appendChild(document.createTextNode("foo"));
755+       td.appendChild(td3);
756+       td.appendChild(document.createCDATASection("bar"));
757+       td.appendChild(document.createTextNode("baz"));
758+       var ts = document.createElement("span");
759+       var moved = dojo.dom.moveChildren(td, ts, true);
760+       jum.assertEquals("test150", 4, moved);
761+       jum.assertEquals("test160", 4, ts.childNodes.length);
762+       jum.assertEquals("test170", 0, td.childNodes.length);
763+       jum.assertFalse("test180", td.hasChildNodes());
764+}
765+
766+function test_dom_copyChildren(){
767+       // FIXME: we can't test this now since JsFakeDom doesn't have an
768+       // implementation of cloneNode()
769+}
770+
771+function test_dom_removeChildren(){
772+       var td = document.createElement("div");
773+       var td2 = document.createElement("div");
774+       var td3 = document.createElement("div");
775+       td.appendChild(td2);
776+       td.appendChild(document.createTextNode("foo"));
777+       td.appendChild(td3);
778+       td.appendChild(document.createCDATASection("bar"));
779+       td.appendChild(document.createTextNode("baz"));
780+       var count = dojo.dom.removeChildren(td);
781+       jum.assertEquals("test190", 5, count);
782+       jum.assertEquals("test200", 0, td.childNodes.length);
783+       jum.assertFalse("test210", td.hasChildNodes());
784+}
785+
786+function test_dom_replaceChildren(){
787+       var td = document.createElement("div");
788+       var td2 = document.createElement("div");
789+       td.appendChild(td2);
790+       var nc = document.createTextNode("foo")
791+       dojo.dom.replaceChildren(td, nc);
792+       jum.assertEquals("test220", 1, td.childNodes.length);
793+       jum.assertTrue("test230", td.hasChildNodes());
794+       jum.assertTrue("test240", td.firstChild === nc);
795+}
796+
797+function test_dom_removeNode(){
798+       var td = document.createElement("div");
799+       var td2 = document.createElement("div");
800+       dojo.dom.removeChildren(document.body);
801+       jum.assertFalse("test250", document.body.hasChildNodes());
802+       document.body.appendChild(td2);
803+       jum.assertTrue("test260", document.body.hasChildNodes());
804+       var r1 = dojo.dom.removeNode(td);
805+       jum.assertTrue("test270", r1 == null);
806+       var r2 = dojo.dom.removeNode(td2);
807+       jum.assertTrue("test280", r2 === td2);
808+       jum.assertFalse("test290", document.body.hasChildNodes());
809+}
810+
811+function test_dom_getAncestors(){
812+       var td = document.createElement("div");
813+       var td2 = document.createElement("div");
814+       document.body.appendChild(td);
815+       td.appendChild(td2);
816+       var t2a = dojo.dom.getAncestors(td2);
817+       jum.assertTrue("test300", t2a[0] === td2);
818+       jum.assertTrue("test310", t2a[1] === td);
819+       jum.assertTrue("test320", t2a[2] === document.body);
820+       document.body.appendChild(td2);
821+       t2a = dojo.dom.getAncestors(td2);
822+       jum.assertTrue("test330", t2a[0] === td2);
823+       jum.assertTrue("test340", t2a[1] === document.body);
824+}
825+
826+function test_dom_isDescendantOf(){
827+       var td = document.createElement("div");
828+       var td2 = document.createElement("div");
829+       document.body.appendChild(td);
830+       td.appendChild(td2);
831+       jum.assertTrue("test350", dojo.dom.isDescendantOf(td2, td));
832+       jum.assertTrue("test360", dojo.dom.isDescendantOf(td2, document.body));
833+       jum.assertTrue("test370", dojo.dom.isDescendantOf(td2, td2));
834+       jum.assertFalse("test380", dojo.dom.isDescendantOf(td2, td2, true));
835+}
836+
837+function test_dom_innerXML(){
838+       // FIXME: we can't test this since there's no XMLSerializer instance in
839+       // JsFakeDom...
840+}
841+
842+function test_dom_createDocumentFromText(){
843+       // FIXME: ...same goes for DOMParser
844+}
845+
846+
847+// FIXME:
848+//     still need to add tests for:
849+//             * insertBefore
850+//             * insertAfter
851+//             * insertAtPosition
852+//             * insertAtIndex
853+//             * textContent
854+//             * collectionToArray
855Index: /home/jkuhnert/projects/dojo/buildscripts/build.xml
856===================================================================
857--- /home/jkuhnert/projects/dojo/buildscripts/build.xml (revision 3785)
858+++ /home/jkuhnert/projects/dojo/buildscripts/build.xml (working copy)
859@@ -166,7 +166,7 @@
860 ]]></script>
861        </target>
862        <!-- end testScripting task -->
863-
864+       
865        <!-- -check-config task -->
866        <target name="-check-config"
867                description="checks to make sure than we're sane before doing anything else">
868@@ -174,7 +174,7 @@
869                <available property="ant_bsf_ok" file="${user.home}/.ant/lib/ant-apache-bsf.jar" />
870                <available property="jython_ok" file="${user.home}/.ant/lib/jython.jar" />
871                <available property="jython_libs_ok" file="${user.home}/.ant/lib/pyLib.zip" />
872-
873+       
874                <condition property="config_ok">
875                        <and>
876                                <isset property="bsf_ok" />
877@@ -183,7 +183,7 @@
878                                <isset property="jython_libs_ok" />
879                        </and>
880                </condition>
881-
882+       
883        </target>
884        <!-- end -check-config task -->
885 
886@@ -198,11 +198,11 @@
887                                <include name="bsf.jar"/>
888                                <include name="jython.jar"/>
889                                <include name="pyLib.zip"/>
890-                               <include name="js.jar"/>
891+                               <include name="js.jar" />
892                                <include name="ant-apache-bsf.jar"/>
893                        </fileset>
894                </copy>
895-
896+       
897                <echo message=""/>
898                <echo message="+--------------------------------------------------------+" />
899                <echo message="| Due to some horrendous design decisions by the authors |" />
900@@ -602,7 +602,7 @@
901                        entire release task to fail if mtasc is not
902                        available - make mtasc optional.
903                -->
904-               <script language="javascript"><![CDATA[
905+               <script language="javascript" ><![CDATA[
906                        function echo(msg){
907                                var echo = dojo.createTask("echo");
908                                echo.setMessage(msg);
909@@ -768,4 +768,131 @@
910                </exec>
911        </target>
912        <!-- end buildFlash task -->
913+       
914+       
915+       <!-- ====================================================================== -->
916+       <!-- Dojo ant task build sections. These create the custom ant tasks for        -->
917+       <!-- dojo.                                                                      -->
918+       <!-- ====================================================================== -->
919+       
920+       <property name="build.target" value="build/main" />
921+       <property name="lib.dir" value="lib" />
922+       <property name="src.dir" value="src/java" />
923+       <property name="dist.dir" value="dist" />
924+       
925+       <property name="js.test" value="../tests" />
926+       <property name="js.tools" value="../testtools" />
927+       
928+       <property name="prologue" value="${js.test}/prologue.js" />
929+       <property name="BUFakeDom" value="${js.tools}/JsFakeDom/BUFakeDom.js" />
930+       <property name="jsunit_wrap" value="${js.tools}/JsTestManager/jsunit_wrap.js" />
931+       <property name="epilogue" value="${js.test}/epilogue.js" />
932+       
933+       <taskdef name="dojo-test" classname="org.dojotoolkit.ant.DojoTestTask"
934+               classpath="${dist.dir}/ant-dojotest.jar" />
935+       
936+       <target name="ant-tasks" depends="compile-tasks,copy-resources,extract-rhino-jar"
937+               description="Creates the ant-dojotest.jar task.">
938+               <mkdir dir="${dist.dir}" />
939+               <jar destfile="${dist.dir}/ant-dojotest.jar" update="true">
940+                       <fileset dir="${build.target}" excludes="test/**"/>
941+               </jar>
942+       </target>
943+       
944+       <target name="compile-tasks"
945+               description="Compiles classes/code needed to create ant tasks." >
946+               <mkdir dir="${build.target}" />
947+               <path id="compile.cp">
948+                       <fileset dir="${lib.dir}">
949+                               <include name="custom_rhino.jar" />
950+                               <include name="xbean.jar" />
951+                       </fileset>
952+               </path>
953+               
954+               <javac classpathref="compile.cp"
955+                      debug="true"
956+                      optimize="true"
957+                      destdir="${build.target}">
958+                       <src path="${src.dir}" />
959+               </javac>
960+       </target>
961+       
962+       <target name="copy-resources"
963+                       description="Compiles classes/code needed to create ant tasks." >
964+               <copy verbose="false"
965+                                     file="${prologue}"
966+                                     todir="${build.target}" />
967+               <copy verbose="false"
968+                                     file="${BUFakeDom}"
969+                                     todir="${build.target}" />
970+               <copy verbose="false"
971+                                     file="${jsunit_wrap}"
972+                                     todir="${build.target}" />
973+               <copy verbose="false"
974+                                     file="${epilogue}"
975+                                     todir="${build.target}" />
976+       </target>
977+       
978+       <target name="extract-rhino-jar">
979+               <unjar src="${lib.dir}/custom_rhino.jar"
980+                      dest="${build.target}"
981+                      overwrite="true" />
982+       </target>
983+       
984+       <target name="run-tests" depends="ant-tasks" >
985+               <dojo-test dojosrc="${root}" testsrc="${root}/tests"/>
986+       </target>
987+       
988+       <!-- ====================================================================== -->
989+       <!-- Test dojo tasks                                                                                                            -->
990+       <!-- ====================================================================== -->
991+       
992+       <property name="test.src.dir" value="src/test" />
993+       <property name="test.js.dir" value="src/test-data" />
994+       <property name="test.build.target" value="build/test" />
995+       
996+       <taskdef name="testng" classname="org.testng.TestNGAntTask"
997+                       classpath="${lib.dir}/testng-4.7-jdk15.jar" />
998+       
999+       <target name="test-tasks" depends="ant-tasks,compile-test"
1000+               description="Tests the dojo ant tasks.">
1001+               <path id="test.run.cp">
1002+                       <fileset dir="${dist.dir}">
1003+                               <include name="ant-dojotest.jar" />
1004+                       </fileset>
1005+                       <pathelement location="${test.build.target}" />
1006+                       <fileset dir="${lib.dir}">
1007+                               <include name="ant.jar" />
1008+                       </fileset>
1009+               </path>
1010+               <testng classpathref="test.run.cp"
1011+                       outputDir="output"
1012+                       sourceDir="${test.src.dir}"
1013+                       haltOnFailure="true" verbose="2"
1014+                       >
1015+                       <sysproperty key="basedir" value="${root}" />
1016+                       <classfileset dir="${test.build.target}" />
1017+               </testng>
1018+       </target>
1019+       
1020+       <target name="compile-test"
1021+               description="Compiles classes/code needed to test dojo tasks." >
1022+               <mkdir dir="${test.build.target}" />
1023+               <path id="compile.test.cp">
1024+                       <fileset dir="${dist.dir}">
1025+                               <include name="ant-dojotest.jar" />
1026+                       </fileset>
1027+                       <fileset dir="${lib.dir}">
1028+                               <include name="testng-4.7-jdk15.jar" />
1029+                       </fileset>
1030+               </path>
1031+               
1032+               <javac classpathref="compile.test.cp"
1033+                      debug="true"
1034+                      optimize="true"
1035+                      destdir="${test.build.target}">
1036+                       <src path="${test.src.dir}" />
1037+               </javac>
1038+       </target>
1039+       
1040 </project>
1041Index: /home/jkuhnert/projects/dojo/buildscripts/lib/testng-4.7-jdk15.jar
1042===================================================================
1043Cannot display: file marked as a binary type.
1044svn:mime-type = application/octet-stream
1045
1046Property changes on: /home/jkuhnert/projects/dojo/buildscripts/lib/testng-4.7-jdk15.jar
1047___________________________________________________________________
1048Name: svn:mime-type
1049   + application/octet-stream
1050
1051Index: /home/jkuhnert/projects/dojo/buildscripts/lib/ant.jar
1052===================================================================
1053Cannot display: file marked as a binary type.
1054svn:mime-type = application/octet-stream
1055
1056Property changes on: /home/jkuhnert/projects/dojo/buildscripts/lib/ant.jar
1057___________________________________________________________________
1058Name: svn:mime-type
1059   + application/octet-stream
1060