You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/15 21:32:38 UTC

svn commit: r997472 [5/41] - in /subversion/branches/py-tests-as-modules: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/server-side/ notes/ notes/tree-conflicts/ notes/wc-ng/ subversion/bindings/javahl/native/ subversio...

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java Wed Sep 15 19:32:26 2010
@@ -27,8 +27,9 @@ import org.apache.subversion.javahl.call
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.OutputStream;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.HashMap;
@@ -47,7 +48,7 @@ class SVNTests extends TestCase
      * our admin object, mostly used for creating,dumping and loading
      * repositories
      */
-    protected ISVNAdmin admin;
+    protected ISVNRepos admin;
 
     /**
      * the subversion client, what we want to test.
@@ -201,11 +202,11 @@ class SVNTests extends TestCase
         if (this.fsType == null)
         {
             this.fsType =
-                System.getProperty("test.fstype", ISVNAdmin.FSFS).toLowerCase();
-            if (!(ISVNAdmin.FSFS.equals(this.fsType) ||
-                  ISVNAdmin.BDB.equals(this.fsType)))
+                System.getProperty("test.fstype", ISVNRepos.FSFS).toLowerCase();
+            if (!(ISVNRepos.FSFS.equals(this.fsType) ||
+                  ISVNRepos.BDB.equals(this.fsType)))
             {
-                this.fsType = ISVNAdmin.FSFS;
+                this.fsType = ISVNRepos.FSFS;
             }
         }
 
@@ -226,7 +227,7 @@ class SVNTests extends TestCase
         createDirectories();
 
         // create and configure the needed subversion objects
-        admin = new SVNAdmin();
+        admin = new SVNRepos();
         initClient();
 
         // build and dump the sample repository
@@ -236,8 +237,10 @@ class SVNTests extends TestCase
         admin.create(greekRepos, true,false, null, this.fsType);
         addExpectedCommitItem(greekFiles.getAbsolutePath(), null, null,
                               NodeKind.none, CommitItemStateFlags.Add);
-        client.doImport(greekFiles.getAbsolutePath(), makeReposUrl(greekRepos),
-                        null, Depth.infinity, false, false, null);
+        client.doImport(greekFiles.getAbsolutePath(),
+                       makeReposUrl(greekRepos).toString(),
+                        Depth.infinity, false, false, null, 
+                        new MyCommitMessage(), null);
         admin.dump(greekRepos, new FileOutputStream(greekDump),
                    null, null, false, false, null);
     }
@@ -271,13 +274,74 @@ class SVNTests extends TestCase
     {
         this.client = new SVNClient();
         this.client.notification2(new MyNotifier());
-        this.client.commitMessageHandler(new MyCommitMessage());
+        this.client.setPrompt(new DefaultPromptUserPassword());
         this.client.username("jrandom");
-        this.client.password("rayjandom");
+        this.client.setProgressCallback(new DefaultProgressListener());
         this.client.setConfigDirectory(this.conf.getAbsolutePath());
         this.expectedCommitItems = new HashMap<String, MyCommitItem>();
     }
+    /**
+     * the default prompt : never prompts the user, provides defaults answers
+     */
+    private static class DefaultPromptUserPassword implements UserPasswordCallback
+    {
+
+        public int askTrustSSLServer(String info, boolean allowPermanently) 
+        {
+            return UserPasswordCallback.AcceptTemporary;
+        }
+
+        public String askQuestion(String realm, String question, boolean showAnswer)
+        {
+            return "";
+        }
+
+        public boolean askYesNo(String realm, String question, boolean yesIsDefault)
+        {
+            return yesIsDefault;
+        }
+
+        public String getPassword()
+        {
+            return "rayjandom";
+        }
+
+        public String getUsername()
+        {
+            return "jrandom";
+        }
 
+        public boolean prompt(String realm, String username)
+        {
+            return false;
+        }
+
+        public boolean prompt(String realm, String username, boolean maySave)
+        {
+            return false;
+        }
+
+        public String askQuestion(String realm, String question,
+                boolean showAnswer, boolean maySave) 
+        {
+            return "";
+        }
+
+        public boolean userAllowedSave() 
+        {
+            return false;
+        }
+    }
+
+    private static class DefaultProgressListener implements ProgressCallback 
+    {
+
+        public void onProgress(ProgressEvent event) 
+        {
+            // Do nothing, just receive the event
+        }
+        
+    }
     /**
      * build a sample directory with test files to be used as import for
      * the sample repository. Create also the master working copy test set.
@@ -356,14 +420,22 @@ class SVNTests extends TestCase
      * Create the url for the repository to be used for the tests.
      * @param file  the directory of the repository
      * @return the URL for the repository
+     * @throws SubversionException 
      */
-    protected String makeReposUrl(File file)
+    protected URI makeReposUrl(File file) throws SubversionException
     {
-        // split the common part of the root directory
-        String path = file.getAbsolutePath()
-            .substring(this.rootDir.getAbsolutePath().length() + 1);
-        // append to the root url
-        return rootUrl + path.replace(File.separatorChar, '/');
+       try
+       {
+            // split the common part of the root directory
+            String path = file.getAbsolutePath()
+                 .substring(this.rootDir.getAbsolutePath().length() + 1);
+            // append to the root url
+            return new URI(rootUrl + path.replace(File.separatorChar, '/'));
+       }
+       catch (URISyntaxException ex)
+       {
+           throw new SubversionException(ex.getMessage());
+       }
     }
 
     /**
@@ -445,7 +517,7 @@ class SVNTests extends TestCase
         /**
          * the url of the repository (used by SVNClient)
          */
-        protected String url;
+        protected URI url;
 
         /**
          * the expected layout of the working copy after the next subversion
@@ -598,7 +670,7 @@ class SVNTests extends TestCase
          * Returns the url of repository
          * @return  the url
          */
-        public String getUrl()
+        public URI getUrl()
         {
             return url;
         }
@@ -657,12 +729,12 @@ class SVNTests extends TestCase
             throws SubversionException, IOException
         {
             // build a clean working directory
-            String uri = makeReposUrl(repos);
+            URI uri = makeReposUrl(repos);
             workingCopy = new File(workingCopies, this.testName);
             removeDirOrFile(workingCopy);
             // checkout the repository
-            client.checkout(uri, workingCopy.getAbsolutePath(), null, null,
-                    Depth.infinity, false, false);
+            client.checkout(uri.toString(), workingCopy.getAbsolutePath(),
+                   null, null, Depth.infinity, false, false);
             // sanity check the working with its expected status
             checkStatus();
             return workingCopy;
@@ -717,7 +789,7 @@ class SVNTests extends TestCase
      * internal class to receive the request for the log messages to check if
      * the expected commit items are presented
      */
-    class MyCommitMessage implements CommitMessage
+    class MyCommitMessage implements CommitMessageCallback
     {
         /**
          * Retrieve a commit message from the user based on the items

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/WC.java
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/WC.java?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/WC.java (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/apache/subversion/javahl/WC.java Wed Sep 15 19:32:26 2010
@@ -526,7 +526,8 @@ public class WC
         // result array
         for (Item item : items.values())
         {
-            Assert.assertTrue("item in working copy not found in status",
+            Assert.assertTrue("item '" + item.myPath + 
+                              "' in working copy not found in status",
                     item.touched);
         }
     }

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java Wed Sep 15 19:32:26 2010
@@ -1352,14 +1352,17 @@ public class BasicTests extends SVNTests
         client.remove(new String[] {thisTest.getWCPath()+"/A/B/E"}, null, true);
         removeDirOrFile(new File(thisTest.getWorkingCopy(), "A/B/E"));
         thisTest.getWc().setItemTextStatus("A/B/E", Status.Kind.deleted);
-        thisTest.getWc().removeItem("A/B/E/alpha");
-        thisTest.getWc().removeItem("A/B/E/beta");
+        thisTest.getWc().setItemTextStatus("A/B/E/alpha", Status.Kind.deleted);
+        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.deleted);
 
         // test the status of the working copy
         thisTest.checkStatus();
 
-        // revert A/B/E -> this will not resurect it
+        // revert A/B/E -> this will resurect it
         client.revert(thisTest.getWCPath()+"/A/B/E", true);
+        thisTest.getWc().setItemTextStatus("A/B/E", Status.Kind.normal);
+        thisTest.getWc().setItemTextStatus("A/B/E/alpha", Status.Kind.normal);
+        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.normal);
 
         // test the status of the working copy
         thisTest.checkStatus();
@@ -1637,8 +1640,7 @@ public class BasicTests extends SVNTests
         assertFalse("failed to remove unmodified file",
                 new File(thisTest.getWorkingCopy(), "A/B/E/alpha").exists());
         file = new File(thisTest.getWorkingCopy(),"A/B/F");
-        assertTrue("removed versioned dir", file.exists()
-                && file.isDirectory());
+        assertFalse("failed to remove versioned dir", file.exists());
         assertFalse("failed to remove unversioned dir",
                 new File(thisTest.getWorkingCopy(), "A/C/Q").exists());
         assertFalse("failed to remove added dir",
@@ -1717,83 +1719,6 @@ public class BasicTests extends SVNTests
     }
 
     /**
-     * Test if Subversion will detect the change of a file to a
-     * direcory.
-     * @throws Throwable
-     */
-    public void testBasicNodeKindChange() throws Throwable
-    {
-        // create working copy
-        OneTest thisTest = new OneTest();
-
-        //  remove A/D/gamma
-        client.remove(new String[] {thisTest.getWCPath()+"/A/D/gamma"}, null,
-                false);
-        thisTest.getWc().setItemTextStatus("A/D/gamma", Status.Kind.deleted);
-
-        // check the working copy status
-        thisTest.checkStatus();
-
-        try
-        {
-            // creating a directory in the place of the deleted file should
-            // fail
-            client.mkdir(new String[] {thisTest.getWCPath()+"/A/D/gamma"},
-                    null);
-            fail("can change node kind");
-        }
-        catch(ClientException e)
-        {
-
-        }
-
-        // check the working copy status
-        thisTest.checkStatus();
-
-        // commit the deletion
-        addExpectedCommitItem(thisTest.getWCPath(),
-                thisTest.getUrl(), "A/D/gamma", NodeKind.file,
-                CommitItemStateFlags.Delete);
-        assertEquals("wrong revision number from commit",
-                client.commit(new String[]{thisTest.getWCPath()},"log message",
-                        true), 2);
-        thisTest.getWc().removeItem("A/D/gamma");
-
-        // check the working copy status
-        thisTest.checkStatus();
-
-        try
-        {
-            // creating a directory in the place of the deleted file should
-            // still fail
-            client.mkdir(
-                    new String[] {thisTest.getWCPath()+"/A/D/gamma"}, null);
-            fail("can change node kind");
-        }
-        catch(ClientException e)
-        {
-
-        }
-
-        // check the working copy status
-        thisTest.checkStatus();
-
-        // update the working copy
-        client.update(thisTest.getWCPath(), null, true);
-
-        // check the working copy status
-        thisTest.checkStatus();
-
-        // now creating the directory should succeed
-        client.mkdir(new String[] {thisTest.getWCPath()+"/A/D/gamma"}, null);
-        thisTest.getWc().addItem("A/D/gamma", null);
-        thisTest.getWc().setItemTextStatus("A/D/gamma", Status.Kind.added);
-
-        // check the working copy status
-        thisTest.checkStatus();
-    }
-
-    /**
      * Test the basic SVNClient.import functionality.
      * @throws Throwable
      */
@@ -2738,7 +2663,10 @@ public class BasicTests extends SVNTests
         String aPath = fileToSVNPath(new File(thisTest.getWCPath() + "/A"),
                                      false);
 
-        expectedDiffOutput = NL + "Property changes on: A" + NL +
+        expectedDiffOutput = "Index: A" + NL + sepLine +
+            "--- A\t(revision 1)" + NL +
+            "+++ A\t(working copy)" + NL +
+            NL + "Property changes on: A" + NL +
             underSepLine +
             "Added: testprop" + NL +
             "## -0,0 +1 ##" + NL +
@@ -2753,7 +2681,10 @@ public class BasicTests extends SVNTests
                                  expectedDiffOutput, diffOutput);
 
         // Test diff where relativeToDir and path are the same.
-        expectedDiffOutput = NL + "Property changes on: ." + NL +
+        expectedDiffOutput = "Index: ." + NL + sepLine +
+            "--- .\t(revision 1)" + NL +
+            "+++ .\t(working copy)" + NL +
+            NL + "Property changes on: ." + NL +
             underSepLine +
             "Added: testprop" + NL +
             "## -0,0 +1 ##" + NL +
@@ -3114,6 +3045,10 @@ public class BasicTests extends SVNTests
      * @throws IOException
      * @throws SubversionException
      */
+    /*
+      This is currently commented out, because we don't have an XFail method
+      for JavaHL.  The resolution is pending the result of issue #3680:
+      http://subversion.tigris.org/issues/show_bug.cgi?id=3680
     public void testObstructionTolerance()
             throws SubversionException, IOException
     {
@@ -3262,7 +3197,7 @@ public class BasicTests extends SVNTests
                                    backupTest.getWc().getItemContent("A/D/H/omega"));
 
         backupTest.checkStatus();
-    }
+    }*/
 
     /**
      * Test basic blame functionality.  This test marginally tests blame

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNTests.java Wed Sep 15 19:32:26 2010
@@ -29,6 +29,9 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import org.tigris.subversion.javahl.ProgressListener;
+import org.tigris.subversion.javahl.PromptUserPassword;
+import org.tigris.subversion.javahl.PromptUserPassword3;
 
 import junit.framework.TestCase;
 
@@ -267,11 +270,74 @@ class SVNTests extends TestCase
         this.client = new SVNClientSynchronized();
         this.client.notification2(new MyNotifier());
         this.client.commitMessageHandler(new MyCommitMessage());
+        this.client.setPrompt(new DefaultPromptUserPassword());
         this.client.username("jrandom");
-        this.client.password("rayjandom");
+        this.client.setProgressListener(new DefaultProgressListener());
         this.client.setConfigDirectory(this.conf.getAbsolutePath());
         this.expectedCommitItems = new HashMap();
     }
+    /**
+     * the default prompt : never prompts the user, provides defaults answers
+     */
+    private static class DefaultPromptUserPassword implements PromptUserPassword3
+    {
+
+        public int askTrustSSLServer(String info, boolean allowPermanently) 
+        {
+            return PromptUserPassword3.AcceptTemporary;
+        }
+
+        public String askQuestion(String realm, String question, boolean showAnswer)
+        {
+            return "";
+        }
+
+        public boolean askYesNo(String realm, String question, boolean yesIsDefault)
+        {
+            return yesIsDefault;
+        }
+
+        public String getPassword()
+        {
+            return "rayjandom";
+        }
+
+        public String getUsername()
+        {
+            return "jrandom";
+        }
+
+        public boolean prompt(String realm, String username)
+        {
+            return false;
+        }
+
+        public boolean prompt(String realm, String username, boolean maySave)
+        {
+            return false;
+        }
+
+        public String askQuestion(String realm, String question,
+                boolean showAnswer, boolean maySave) 
+        {
+            return "";
+        }
+
+        public boolean userAllowedSave() 
+        {
+            return false;
+        }
+    }
+
+    private static class DefaultProgressListener implements ProgressListener 
+    {
+
+        public void onProgress(ProgressEvent event) 
+        {
+            // Do nothing, just receive the event
+        }
+        
+    }
 
     /**
      * build a sample directory with test files to be used as import for

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/include/svn_containers.swg
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/include/svn_containers.swg?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/include/svn_containers.swg (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/include/svn_containers.swg Wed Sep 15 19:32:26 2010
@@ -205,6 +205,27 @@
   %append_output(svn_swig_py_changed_path_hash_to_dict($1));
 }
 
+%typemap(in) apr_hash_t *changed_paths2
+  (apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL)
+{
+  if (_global_pool == NULL)
+  {
+    if (svn_swig_py_get_parent_pool(args, $descriptor(apr_pool_t *),
+                                    &_global_py_pool, &_global_pool))
+      SWIG_fail;
+  }
+
+  $1 = svn_swig_py_struct_ptr_hash_from_dict($input,
+    $descriptor(svn_log_changed_path2_t *), _global_pool);
+  if (PyErr_Occurred()) {
+    SWIG_fail;
+  }
+}
+%typemap(out) apr_hash_t *changed_paths2
+{
+  %append_output(svn_swig_py_changed_path2_hash_to_dict($1));
+}
+
 /* apr_hash_t * <const char *, svn_config_t *> */
 %typemap(in) apr_hash_t *config
   (apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL)

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/README
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/README?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/README (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/README Wed Sep 15 19:32:26 2010
@@ -37,3 +37,14 @@ TRANSLATING PARAMETER LISTS
               foo(function)
           except:
               # handle it
+
+
+RUNNING THE TESTS
+
+   $ cd subversion/bindings/swig/python
+   $ python ./tests/run_all.py --help
+   $ python ./tests/run_all.py [TEST...]
+
+   where TEST can be the name of a test suite ('core', 'mergeinfo',
+   'client', etc.), or see '--help' for other options.  The default is to
+   run the tests in all modules.

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Wed Sep 15 19:32:26 2010
@@ -805,6 +805,7 @@ static PyObject *make_ob_##type(void *va
 
 DECLARE_SWIG_CONSTRUCTOR(txdelta_window, svn_txdelta_window_dup)
 DECLARE_SWIG_CONSTRUCTOR(log_changed_path, svn_log_changed_path_dup)
+DECLARE_SWIG_CONSTRUCTOR(log_changed_path2, svn_log_changed_path2_dup)
 DECLARE_SWIG_CONSTRUCTOR(wc_status, svn_wc_dup_status)
 DECLARE_SWIG_CONSTRUCTOR(lock, svn_lock_dup)
 DECLARE_SWIG_CONSTRUCTOR(auth_ssl_server_cert_info,
@@ -878,6 +879,42 @@ PyObject *svn_swig_py_changed_path_hash_
   return dict;
 }
 
+PyObject *svn_swig_py_changed_path2_hash_to_dict(apr_hash_t *hash)
+{
+  apr_hash_index_t *hi;
+  PyObject *dict;
+
+  if (hash == NULL)
+    Py_RETURN_NONE;
+
+  if ((dict = PyDict_New()) == NULL)
+    return NULL;
+
+  for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi))
+    {
+      const void *key;
+      void *val;
+      PyObject *value;
+
+      apr_hash_this(hi, &key, NULL, &val);
+      value = make_ob_log_changed_path2(val);
+      if (value == NULL)
+        {
+            Py_DECREF(dict);
+            return NULL;
+        }
+      if (PyDict_SetItemString(dict, (char *)key, value) == -1)
+        {
+          Py_DECREF(value);
+          Py_DECREF(dict);
+          return NULL;
+        }
+      Py_DECREF(value);
+    }
+
+  return dict;
+}
+
 apr_hash_t *svn_swig_py_stringhash_from_dict(PyObject *dict,
                                              apr_pool_t *pool)
 {
@@ -1320,6 +1357,61 @@ commit_item_array_to_list(const apr_arra
 
 /*** Errors ***/
 
+/* Convert a given SubversionException to an svn_error_t. On failure returns
+   NULL and sets a Python exception. */
+static svn_error_t *exception_to_error(PyObject * exc)
+{
+	const char *message, *file = NULL;
+	apr_status_t apr_err;
+	long line = 0;
+	PyObject *apr_err_ob = NULL, *child_ob = NULL, *message_ob = NULL;
+	PyObject *file_ob = NULL, *line_ob = NULL;
+    svn_error_t *rv = NULL, *child = NULL;
+
+	if ((apr_err_ob = PyObject_GetAttrString(exc, "apr_err")) == NULL)
+	    goto finished;
+	apr_err = (apr_status_t) PyInt_AsLong(apr_err_ob);
+	if (PyErr_Occurred()) goto finished;
+
+	if ((message_ob = PyObject_GetAttrString(exc, "message")) == NULL)
+	    goto finished;
+	message = PyString_AsString(message_ob);
+	if (PyErr_Occurred()) goto finished;
+
+	if ((file_ob = PyObject_GetAttrString(exc, "file")) == NULL)
+	    goto finished;
+	if (file_ob != Py_None)
+	    file = PyString_AsString(file_ob);
+	if (PyErr_Occurred()) goto finished;
+
+	if ((line_ob = PyObject_GetAttrString(exc, "line")) == NULL)
+	    goto finished;
+	if (line_ob != Py_None)
+	    line = PyInt_AsLong(line_ob);
+	if (PyErr_Occurred()) goto finished;
+
+	if ((child_ob = PyObject_GetAttrString(exc, "child")) == NULL)
+	    goto finished;
+	/* We could check if the child is a Subversion exception too,
+	   but let's just apply duck typing. */
+	if (child_ob != Py_None)
+	    child = exception_to_error(child_ob);
+	if (PyErr_Occurred()) goto finished;
+
+	rv = svn_error_create(apr_err, child, message);
+	/* Somewhat hacky, but we need to preserve original file/line info. */
+	rv->file = file ? apr_pstrdup(rv->pool, file) : NULL;
+	rv->line = line;
+
+finished:
+	Py_XDECREF(child_ob);
+	Py_XDECREF(line_ob);
+	Py_XDECREF(file_ob);
+	Py_XDECREF(message_ob);
+	Py_XDECREF(apr_err_ob);
+	return rv;
+}
+
 /* If the currently set Python exception is a valid SubversionException,
    clear exception state and transform it into a Subversion error.
    Otherwise, return a Subversion error about an exception in a callback. */
@@ -1327,48 +1419,36 @@ static svn_error_t *callback_exception_e
 {
   PyObject *svn_module = NULL, *svn_exc = NULL;
   PyObject *exc, *exc_type, *exc_traceback;
-  PyObject *message_ob = NULL, *apr_err_ob = NULL;
-  const char *message;
-  int apr_err;
   svn_error_t *rv = NULL;
 
   PyErr_Fetch(&exc_type, &exc, &exc_traceback);
 
   if ((svn_module = PyImport_ImportModule("svn.core")) == NULL)
-    goto finished;
-  if ((svn_exc = PyObject_GetAttrString(svn_module, "SubversionException"))
-      == NULL)
-    goto finished;
-
-  if (!PyErr_GivenExceptionMatches(exc_type, svn_exc))
-    {
-      PyErr_Restore(exc_type, exc, exc_traceback);
-      exc = exc_type = exc_traceback = NULL;
       goto finished;
-    }
 
-  if ((apr_err_ob = PyObject_GetAttrString(exc, "apr_err")) == NULL)
-    goto finished;
-  apr_err = PyInt_AsLong(apr_err_ob);
-  if (PyErr_Occurred()) goto finished;
+  svn_exc = PyObject_GetAttrString(svn_module, "SubversionException");
+  Py_DECREF(svn_module);
 
-  if ((message_ob = PyObject_GetAttrString(exc, "message")) == NULL)
-    goto finished;
-  message = PyString_AsString(message_ob);
-  if (PyErr_Occurred()) goto finished;
+  if (svn_exc == NULL)
+      goto finished;
 
-  /* A possible improvement here would be to convert the whole
-     SubversionException chain. */
-  rv = svn_error_create(apr_err, NULL, message);
+  if (PyErr_GivenExceptionMatches(exc_type, svn_exc))
+    {
+      rv = exception_to_error(exc);
+    }
+  else
+    {
+      PyErr_Restore(exc_type, exc, exc_traceback);
+      exc_type = exc = exc_traceback = NULL;
+    }
 
 finished:
-  Py_XDECREF(exc);
+  Py_XDECREF(svn_exc);
   Py_XDECREF(exc_type);
+  Py_XDECREF(exc);
   Py_XDECREF(exc_traceback);
-  Py_XDECREF(svn_module);
-  Py_XDECREF(svn_exc);
-  Py_XDECREF(apr_err_ob);
-  Py_XDECREF(message_ob);
+  /* By now, either rv is set and the exception is cleared, or rv is NULL
+     and an exception is pending (possibly a new one). */
   return rv ? rv : svn_error_create(SVN_ERR_SWIG_PY_EXCEPTION_SET, NULL,
                                     "Python callback raised an exception");
 }
@@ -4027,3 +4107,19 @@ svn_swig_py_setup_wc_diff_callbacks2(voi
   callbacks->dir_props_changed  = wc_diff_callbacks2_dir_props_changed;
   return callbacks;
 }
+
+PyObject *
+svn_swig_py_txdelta_window_t_ops_get(svn_txdelta_window_t *window,
+                                     swig_type_info * op_type_info,
+                                     PyObject *window_pool)
+{
+  PyObject *result = PyList_New(window->num_ops);
+  int i;
+  
+  for (i = 0; i < window->num_ops; ++i)
+      PyList_SET_ITEM(result, i,
+                      svn_swig_NewPointerObj(window->ops + i, op_type_info,
+                                             window_pool, NULL));
+
+  return result;
+}

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h Wed Sep 15 19:32:26 2010
@@ -174,11 +174,16 @@ PyObject *svn_swig_py_c_strings_to_list(
 SVN_SWIG_SWIGUTIL_EXPORT
 PyObject *svn_swig_py_array_to_list(const apr_array_header_t *strings);
 
-/* helper function to convert a hash mapping char * to svn_string_t * to a
- * Python dict mapping str to str. */
+/* helper function to convert a hash mapping char * to
+ * svn_log_changed_path_t * to a Python dict mapping str to str. */
 SVN_SWIG_SWIGUTIL_EXPORT
 PyObject *svn_swig_py_changed_path_hash_to_dict(apr_hash_t *hash);
 
+/* helper function to convert a hash mapping char * to
+ * svn_log_changed_path2_t * to a Python dict mapping str to str. */
+SVN_SWIG_SWIGUTIL_EXPORT
+PyObject *svn_swig_py_changed_path2_hash_to_dict(apr_hash_t *hash);
+
 /* helper function to convert an array of 'svn_revnum_t' to a Python list
    of int objects */
 SVN_SWIG_SWIGUTIL_EXPORT
@@ -508,6 +513,17 @@ svn_error_t *svn_swig_py_ra_lock_callbac
 SVN_SWIG_SWIGUTIL_EXPORT
 extern const svn_ra_reporter2_t swig_py_ra_reporter2;
 
+/* Get a list of ops from a window. Used to replace the naive
+   svn_txdelta_window_t.ops accessor. op_type_info is supposed to be
+   the SWIG descriptor of "svn_txdelta_op_t *". window_pool is supposed
+   to be the pool associated with the window proxy and used for wrapping
+   the op objects. */
+SVN_SWIG_SWIGUTIL_EXPORT
+PyObject *
+svn_swig_py_txdelta_window_t_ops_get(svn_txdelta_window_t *window,
+                                     swig_type_info * op_type_info,
+                                     PyObject *window_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/svn/delta.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/svn/delta.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/svn/delta.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/svn/delta.py Wed Sep 15 19:32:26 2010
@@ -29,6 +29,9 @@ _unprefix_names(locals(), 'svn_delta_')
 _unprefix_names(locals(), 'svn_txdelta_', 'tx_')
 del _unprefix_names
 
+# Force our accessor since it appears that there isn't a more civilized way
+# to make SWIG use it.
+svn_txdelta_window_t.ops = property(svn_txdelta_window_t_ops_get)
 
 class Editor:
 

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/auth.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/auth.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/auth.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/auth.py Wed Sep 15 19:32:26 2010
@@ -110,7 +110,8 @@ class SubversionAuthTestCase(unittest.Te
     self.assert_(creds is not None)
 
 def suite():
-    return unittest.makeSuite(SubversionAuthTestCase, 'test')
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionAuthTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/client.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/client.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/client.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/client.py Wed Sep 15 19:32:26 2010
@@ -22,8 +22,6 @@ import unittest, os, weakref, setup_path
 
 from svn import core, client, wc
 
-from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
-  REPOS_PATH, REPOS_URL
 try:
   # Python >=3.0
   from urllib.parse import urljoin
@@ -71,6 +69,8 @@ class SubversionClientTestCase(unittest.
     self.client_ctx.auth_baton = core.svn_auth_open(providers)
 
     self.temper = utils.Temper()
+    (_, self.repos_path, self.repos_uri) = self.temper.alloc_known_repo(
+      'trac/versioncontrol/tests/svnrepos.dump', suffix='-client')
 
   def tearDown(self):
     # We have to free client_ctx first, since it may be holding handles
@@ -162,10 +162,10 @@ class SubversionClientTestCase(unittest.
     path = self.temper.alloc_empty_dir('-checkout')
 
     self.assertRaises(ValueError, client.checkout2,
-                      REPOS_URL, path, None, None, True, True,
+                      self.repos_uri, path, None, None, True, True,
                       self.client_ctx)
 
-    client.checkout2(REPOS_URL, path, rev, rev, True, True,
+    client.checkout2(self.repos_uri, path, rev, rev, True, True,
             self.client_ctx)
 
   def test_info(self):
@@ -174,19 +174,19 @@ class SubversionClientTestCase(unittest.
     # Run info
     revt = core.svn_opt_revision_t()
     revt.kind = core.svn_opt_revision_head
-    client.info(REPOS_URL, revt, revt, self.info_receiver,
+    client.info(self.repos_uri, revt, revt, self.info_receiver,
                 False, self.client_ctx)
 
     # Check output from running info. This also serves to verify that
     # the internal 'info' object is still valid
-    self.assertEqual(self.path, os.path.basename(REPOS_PATH))
+    self.assertEqual(self.path, os.path.basename(self.repos_path))
     self.info.assert_valid()
-    self.assertEqual(self.info.URL, REPOS_URL)
-    self.assertEqual(self.info.repos_root_URL, REPOS_URL)
+    self.assertEqual(self.info.URL, self.repos_uri)
+    self.assertEqual(self.info.repos_root_URL, self.repos_uri)
 
   def test_mkdir_url(self):
     """Test svn_client_mkdir2 on a file:// URL"""
-    directory = urljoin(REPOS_URL+"/", "dir1")
+    directory = urljoin(self.repos_uri+"/", "dir1")
 
     commit_info = client.mkdir2((directory,), self.client_ctx)
     self.assertEqual(commit_info.revision, 13)
@@ -194,16 +194,16 @@ class SubversionClientTestCase(unittest.
 
   def test_mkdir_url_with_revprops(self):
     """Test svn_client_mkdir3 on a file:// URL, with added revprops"""
-    directory = urljoin(REPOS_URL+"/", "some/deep/subdir")
+    directory = urljoin(self.repos_uri+"/", "some/deep/subdir")
 
     commit_info = client.mkdir3((directory,), 1, {'customprop':'value'},
                                 self.client_ctx)
-    self.assertEqual(commit_info.revision, 14)
+    self.assertEqual(commit_info.revision, 13)
     self.assertEqual(self.log_message_func_calls, 1)
 
   def test_log3_url(self):
     """Test svn_client_log3 on a file:// URL"""
-    directory = urljoin(REPOS_URL+"/", "trunk/dir1")
+    directory = urljoin(self.repos_uri+"/", "trunk/dir1")
 
     start = core.svn_opt_revision_t()
     end = core.svn_opt_revision_t()
@@ -233,7 +233,7 @@ class SubversionClientTestCase(unittest.
 
     self.received_revisions = []
 
-    client.log5((REPOS_URL,), end, (rev_range,), 0, False, True, False, (),
+    client.log5((self.repos_uri,), end, (rev_range,), 0, False, True, False, (),
         self.log_entry_receiver, self.client_ctx)
 
     self.assertEqual(self.received_revisions, range(0, 5))
@@ -241,22 +241,22 @@ class SubversionClientTestCase(unittest.
   def test_uuid_from_url(self):
     """Test svn_client_uuid_from_url on a file:// URL"""
     self.assert_(isinstance(
-                 client.uuid_from_url(REPOS_URL, self.client_ctx),
+                 client.uuid_from_url(self.repos_uri, self.client_ctx),
                  basestring))
 
   def test_url_from_path(self):
     """Test svn_client_url_from_path for a file:// URL"""
-    self.assertEquals(client.url_from_path(REPOS_URL), REPOS_URL)
+    self.assertEquals(client.url_from_path(self.repos_uri), self.repos_uri)
 
     rev = core.svn_opt_revision_t()
     rev.kind = core.svn_opt_revision_head
 
     path = self.temper.alloc_empty_dir('-url_from_path')
 
-    client.checkout2(REPOS_URL, path, rev, rev, True, True,
+    client.checkout2(self.repos_uri, path, rev, rev, True, True,
                      self.client_ctx)
 
-    self.assertEquals(client.url_from_path(path), REPOS_URL)
+    self.assertEquals(client.url_from_path(path), self.repos_uri)
 
   def test_uuid_from_path(self):
     """Test svn_client_uuid_from_path."""
@@ -265,20 +265,20 @@ class SubversionClientTestCase(unittest.
 
     path = self.temper.alloc_empty_dir('-uuid_from_path')
 
-    client.checkout2(REPOS_URL, path, rev, rev, True, True,
+    client.checkout2(self.repos_uri, path, rev, rev, True, True,
                      self.client_ctx)
 
     wc_adm = wc.adm_open3(None, path, False, 0, None)
 
     self.assertEquals(client.uuid_from_path(path, wc_adm, self.client_ctx),
-                      client.uuid_from_url(REPOS_URL, self.client_ctx))
+                      client.uuid_from_url(self.repos_uri, self.client_ctx))
 
     self.assert_(isinstance(client.uuid_from_path(path, wc_adm,
                             self.client_ctx), basestring))
 
   def test_open_ra_session(self):
       """Test svn_client_open_ra_session()."""
-      client.open_ra_session(REPOS_URL, self.client_ctx)
+      client.open_ra_session(self.repos_uri, self.client_ctx)
 
 
   def test_info_file(self):
@@ -290,7 +290,7 @@ class SubversionClientTestCase(unittest.
     rev.kind = core.svn_opt_revision_head
     wc_path = self.temper.alloc_empty_dir('-info_file')
 
-    client.checkout2(REPOS_URL, wc_path, rev, rev, True, True,
+    client.checkout2(self.repos_uri, wc_path, rev, rev, True, True,
                      self.client_ctx)
     adm_access = wc.adm_open3(None, wc_path, True, -1, None)
 
@@ -298,7 +298,7 @@ class SubversionClientTestCase(unittest.
       # Test 1: Run info -r BASE. We expect the size value to be filled in.
       rev.kind = core.svn_opt_revision_base
       readme_path = '%s/trunk/README.txt' % wc_path
-      readme_url = '%s/trunk/README.txt' % REPOS_URL
+      readme_url = '%s/trunk/README.txt' % self.repos_uri
       client.info(readme_path, rev, rev, self.info_receiver,
                   False, self.client_ctx)
 
@@ -340,7 +340,7 @@ class SubversionClientTestCase(unittest.
     head.kind = core.svn_opt_revision_head
     wc_path = self.temper.alloc_empty_dir('-merge_peg3')
 
-    client.checkout3(REPOS_URL, wc_path, head, head, core.svn_depth_infinity,
+    client.checkout3(self.repos_uri, wc_path, head, head, core.svn_depth_infinity,
                      True, False, self.client_ctx)
 
     # Let's try to backport a change from the v1x branch
@@ -375,8 +375,8 @@ class SubversionClientTestCase(unittest.
     self.assertEqual(readme_text, 'This is a test.\n')
 
 def suite():
-    return unittest.makeSuite(SubversionClientTestCase, 'test',
-                              suiteClass=SubversionRepositoryTestSetup)
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionClientTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/core.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/core.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/core.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/core.py Wed Sep 15 19:32:26 2010
@@ -20,7 +20,8 @@
 #
 import unittest
 
-import svn.core
+import svn.core, svn.client
+import utils
 
 class SubversionCoreTestCase(unittest.TestCase):
   """Test cases for the basic SWIG Subversion core"""
@@ -46,8 +47,67 @@ class SubversionCoreTestCase(unittest.Te
             svn.core.svn_mime_type_validate, "this\nis\ninvalid\n")
     svn.core.svn_mime_type_validate("unknown/but-valid; charset=utf8")
 
+  def test_exception_interoperability(self):
+    """Test if SubversionException is correctly converted into svn_error_t
+    and vice versa."""
+    t = utils.Temper()
+    (_, _, repos_uri) = t.alloc_empty_repo(suffix='-core')
+    rev = svn.core.svn_opt_revision_t()
+    rev.kind = svn.core.svn_opt_revision_head
+    ctx = svn.client.create_context()
+    
+    class Receiver:
+      def __call__(self, path, info, pool):
+        raise self.e
+    
+    rec = Receiver()
+    args = (repos_uri, rev, rev, rec, svn.core.svn_depth_empty, None, ctx)
+
+    try:
+      # ordinary Python exceptions must be passed through
+      rec.e = TypeError()
+      self.assertRaises(TypeError, svn.client.info2, *args)
+      
+      # SubversionException will be translated into an svn_error_t, propagated
+      # through the call chain and translated back to SubversionException.
+      rec.e = svn.core.SubversionException("Bla bla bla.",
+                                           svn.core.SVN_ERR_INCORRECT_PARAMS,
+                                           file=__file__, line=866)
+      rec.e.child = svn.core.SubversionException("Yada yada.",
+                                             svn.core.SVN_ERR_INCOMPLETE_DATA)
+      self.assertRaises(svn.core.SubversionException, svn.client.info2, *args)
+      
+      # It must remain unchanged through the process.
+      try:
+        svn.client.info2(*args)
+      except svn.core.SubversionException, exc:
+        # find the original exception
+        while exc.file != rec.e.file: exc = exc.child
+        
+        self.assertEqual(exc.message, rec.e.message)
+        self.assertEqual(exc.apr_err, rec.e.apr_err)
+        self.assertEqual(exc.line, rec.e.line)
+        self.assertEqual(exc.child.message, rec.e.child.message)
+        self.assertEqual(exc.child.apr_err, rec.e.child.apr_err)
+        self.assertEqual(exc.child.child, None)
+        self.assertEqual(exc.child.file, None)
+        self.assertEqual(exc.child.line, 0)
+        
+      # Incomplete SubversionExceptions must trigger Python exceptions, which
+      # will be passed through.
+      rec.e = svn.core.SubversionException("No fields except message.")
+      # e.apr_err is None but should be an int
+      self.assertRaises(TypeError, svn.client.info2, args)
+    finally:
+      # This would happen without the finally block as well, but we expliticly
+      # order the operations so that the cleanup is not hindered by any open
+      # handles.
+      del ctx
+      t.cleanup()
+
 def suite():
-    return unittest.makeSuite(SubversionCoreTestCase, 'test')
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionCoreTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/delta.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/delta.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/delta.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/delta.py Wed Sep 15 19:32:26 2010
@@ -46,9 +46,27 @@ class DeltaTestCase(unittest.TestCase):
     window_handler, baton = \
        svn.delta.tx_apply(src_stream, target_stream, None)
     window_handler(None, baton)
+    
+  def testTxdeltaWindowT(self):
+    """Test the svn_txdelta_window_t wrapper."""
+    a = StringIO("abc\ndef\n")
+    b = StringIO("def\nghi\n")
+    
+    delta_stream = svn.delta.svn_txdelta(a, b)
+    window = svn.delta.svn_txdelta_next_window(delta_stream)
+    
+    self.assert_(window.sview_offset + window.sview_len <= len(a.getvalue()))
+    self.assert_(window.tview_len <= len(b.getvalue()))
+    self.assert_(len(window.new_data) > 0)
+    self.assertEqual(window.num_ops, len(window.ops))
+    self.assertEqual(window.src_ops, len([op for op in window.ops
+      if op.action_code == svn.delta.svn_txdelta_source]))
+
+    # Check that the ops inherit the window's pool
+    self.assertEqual(window.ops[0]._parent_pool, window._parent_pool)
 
 def suite():
-  return unittest.makeSuite(DeltaTestCase, 'test')
+  return unittest.defaultTestLoader.loadTestsFromTestCase(DeltaTestCase)
 
 if __name__ == '__main__':
   runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/mergeinfo.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/mergeinfo.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/mergeinfo.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/mergeinfo.py Wed Sep 15 19:32:26 2010
@@ -19,21 +19,8 @@
 #
 #
 import unittest, os
-
-from sys import version_info # For Python version check
-if version_info[0] >= 3:
-  # Python >=3.0
-  from io import StringIO
-else:
-  # Python <3.0
-  try:
-    from cStringIO import StringIO
-  except ImportError:
-    from StringIO import StringIO
-
 from svn import core, repos, fs
-
-from trac.versioncontrol.tests.svn_fs import REPOS_PATH
+import utils
 
 class RevRange:
   """ Proxy object for a revision range, used for comparison. """
@@ -58,22 +45,16 @@ class SubversionMergeinfoTestCase(unitte
        created by dumping the repository generated for command line log
        tests 16.  If it needs to be updated (mergeinfo format changes, for
        example), we can go there to get a new version."""
-    dumpfile = open(os.path.join(os.path.split(__file__)[0],
-                                 'data', 'mergeinfo.dump'), 'rb')
-    # Remove any existing repository to ensure a fresh start
-    self.tearDown()
-    self.repos = repos.svn_repos_create(REPOS_PATH, '', '', None, None)
-    repos.svn_repos_load_fs2(self.repos, dumpfile, StringIO(),
-                             repos.svn_repos_load_uuid_ignore, '',
-                             0, 0, None)
+    self.temper = utils.Temper()
+    (self.repos, _, _) = self.temper.alloc_known_repo('data/mergeinfo.dump',
+                                                      suffix='-mergeinfo')
     self.fs = repos.fs(self.repos)
     self.rev = fs.youngest_rev(self.fs)
 
   def tearDown(self):
-    self.fs = None
-    self.repos = None
-    if os.path.exists(REPOS_PATH):
-      repos.delete(REPOS_PATH)
+    del self.fs
+    del self.repos
+    self.temper.cleanup()
 
   def test_mergeinfo_parse(self):
     """Test svn_mergeinfo_parse()"""
@@ -176,7 +157,8 @@ class SubversionMergeinfoTestCase(unitte
 
 
 def suite():
-    return unittest.makeSuite(SubversionMergeinfoTestCase, 'test')
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionMergeinfoTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/pool.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/pool.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/pool.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/pool.py Wed Sep 15 19:32:26 2010
@@ -219,7 +219,7 @@ class PoolTestCase(unittest.TestCase):
     svn_pool_destroy(svn_pool_create())
 
 def suite():
-  return unittest.makeSuite(PoolTestCase, 'test')
+  return unittest.defaultTestLoader.loadTestsFromTestCase(PoolTestCase)
 
 if __name__ == '__main__':
   runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/ra.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/ra.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/ra.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/ra.py Wed Sep 15 19:32:26 2010
@@ -28,9 +28,8 @@ if version_info[0] >= 3:
 else:
   # Python <3.0
   from StringIO import StringIO
-
-from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
-  REPOS_PATH, REPOS_URL
+  
+import utils
 
 class SubversionRepositoryAccessTestCase(unittest.TestCase):
   """Test cases for the Subversion repository layer"""
@@ -38,24 +37,23 @@ class SubversionRepositoryAccessTestCase
   def setUp(self):
     """Load a Subversion repository"""
 
-    # Isolate each test from the others with a fresh repository.
-    # Eventually, we should move this into a shared TestCase base
-    # class that all test cases in this directory can use.
-    SubversionRepositoryTestSetup().setUp()
-
     ra.initialize()
-
+    self.temper = utils.Temper()
+    # Isolate each test from the others with a fresh repository.
+    
     # Open repository directly for cross-checking
-    self.repos = repos.open(REPOS_PATH)
+    (self.repos, _, self.repos_uri) = self.temper.alloc_known_repo(
+      'trac/versioncontrol/tests/svnrepos.dump', suffix='-ra')
     self.fs = repos.fs(self.repos)
 
     self.callbacks = ra.Callbacks()
-    self.ra_ctx = ra.open2(REPOS_URL, self.callbacks, {})
+    self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {})
 
   def tearDown(self):
     self.ra_ctx = None
     self.fs = None
     self.repos = None
+    self.temper.cleanup()
 
   def test_get_file(self):
     # Test getting the properties of a file
@@ -73,7 +71,7 @@ class SubversionRepositoryAccessTestCase
 
   def test_get_repos_root(self):
     root = ra.get_repos_root(self.ra_ctx)
-    self.assertEqual(root,REPOS_URL)
+    self.assertEqual(root,self.repos_uri)
 
   def test_get_uuid(self):
     ra_uuid = ra.get_uuid(self.ra_ctx)
@@ -100,7 +98,8 @@ class SubversionRepositoryAccessTestCase
 
     self.assertEqual(dirents, {})
 
-    (dirents, _, _) = ra.get_dir2(self.ra_ctx, 'trunk', 10, core.SVN_DIRENT_KIND)
+    (dirents, _, _) = ra.get_dir2(self.ra_ctx, 'trunk', 10,
+                                  core.SVN_DIRENT_KIND)
 
     self.assert_('README2.txt' in dirents)
     self.assertEqual(dirents['README2.txt'].kind, core.svn_node_file)
@@ -252,10 +251,11 @@ class SubversionRepositoryAccessTestCase
 
     sess_url = ra.get_session_url(self.ra_ctx)
     try:
-        ra.reparent(self.ra_ctx, REPOS_URL+"/trunk")
+        ra.reparent(self.ra_ctx, self.repos_uri+"/trunk")
         reporter, reporter_baton = ra.do_diff2(self.ra_ctx, fs_revnum,
                                                "README.txt", 0, 0, 1,
-                                               REPOS_URL+"/trunk/README.txt",
+                                               self.repos_uri
+                                                 +"/trunk/README.txt",
                                                e_ptr, e_baton)
         reporter.set_path(reporter_baton, "", 0, True, None)
         reporter.finish_report(reporter_baton)
@@ -376,7 +376,7 @@ class SubversionRepositoryAccessTestCase
 
   def test_namestring(self):
     # Only ra-{neon,serf} support this right now.
-    if REPOS_URL.startswith('http'):
+    if self.repos_uri.startswith('http'):
       called = [False]
       def cb(pool):
         called[0] = True
@@ -386,7 +386,8 @@ class SubversionRepositoryAccessTestCase
       self.assert_(called[0])
 
 def suite():
-    return unittest.makeSuite(SubversionRepositoryAccessTestCase, 'test')
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionRepositoryAccessTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/repository.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/repository.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/repository.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/repository.py Wed Sep 15 19:32:26 2010
@@ -18,7 +18,7 @@
 # under the License.
 #
 #
-import unittest, setup_path, tempfile
+import unittest, setup_path
 from sys import version_info # For Python version check
 if version_info[0] >= 3:
   # Python >=3.0
@@ -28,9 +28,7 @@ else:
   from StringIO import StringIO
 from svn import core, repos, fs, delta
 from svn.core import SubversionException
-
-from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
-  REPOS_PATH
+import utils
 
 class ChangeReceiver(delta.Editor):
   """A delta editor which saves textdeltas for later use"""
@@ -55,13 +53,16 @@ class SubversionRepositoryTestCase(unitt
 
   def setUp(self):
     """Load a Subversion repository"""
-    self.repos = repos.open(REPOS_PATH)
+    self.temper = utils.Temper()
+    (self.repos, _, _) = self.temper.alloc_known_repo(
+      'trac/versioncontrol/tests/svnrepos.dump', suffix='-repository')
     self.fs = repos.fs(self.repos)
     self.rev = fs.youngest_rev(self.fs)
 
   def tearDown(self):
     self.fs = None
     self.repos = None
+    self.temper.cleanup()
 
   def test_cease_invocation(self):
     """Test returning SVN_ERR_CEASE_INVOCATION from a callback"""
@@ -81,9 +82,8 @@ class SubversionRepositoryTestCase(unitt
        using a config hash"""
     fs_config = { "fs-type": "fsfs" }
     for i in range(5):
-      path = core.svn_dirent_internal_style(tempfile.mkdtemp("-test" + str(i)))
+      path = self.temper.alloc_empty_dir(suffix='-repository-create%d' % i)
       repos.create(path, "", "", None, fs_config)
-      repos.delete(path)
 
   def test_dump_fs2(self):
     """Test the dump_fs2 function"""
@@ -197,8 +197,8 @@ class SubversionRepositoryTestCase(unitt
                      "Youngest revision")
 
 def suite():
-    return unittest.makeSuite(SubversionRepositoryTestCase, 'test',
-                              suiteClass=SubversionRepositoryTestSetup)
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionRepositoryTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py Wed Sep 15 19:32:26 2010
@@ -361,8 +361,9 @@ class SubversionRepositoryTestCase(unitt
 
 
 def suite():
-    return unittest.makeSuite(SubversionRepositoryTestCase, 'test',
-                              suiteClass=SubversionRepositoryTestSetup)
+    loader = unittest.TestLoader()
+    loader.suiteClass = SubversionRepositoryTestSetup
+    return loader.loadTestsFromTestCase(SubversionRepositoryTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/utils.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/utils.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/utils.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/utils.py Wed Sep 15 19:32:26 2010
@@ -18,13 +18,9 @@
 # under the License.
 #
 #
-import tempfile, urllib
+import os.path, sys, tempfile, urllib
 from svn import core, repos
-
-try:
-  from io import StringIO
-except ImportError:
-  from StringIO import StringIO
+from StringIO import StringIO
 
 class Temper(object):
   """Class to simplify allocation and cleanup of dummy Subversion
@@ -49,21 +45,31 @@ class Temper(object):
     self._cleanup_list.append((temp_dir_name, core.svn_io_remove_dir))
     return temp_dir_name
 
-  def alloc_repo(self, suffix = ""):
-    """Creates an empty repository. Returns a tuple of its handle, path and
+  def alloc_empty_repo(self, suffix = ""):
+    """Create an empty repository. Returns a tuple of its handle, path and
        file: URI in canonical internal form."""
     temp_path = tempfile.mkdtemp(suffix)
     repo_path = core.svn_dirent_internal_style(temp_path)
-    repo_uri = core.svn_uri_canonicalize(Temper._file_uri_for_path(temp_path))
+    repo_uri = core.svn_uri_canonicalize(file_uri_for_path(temp_path))
     handle = repos.create(repo_path, None, None, None, None)
     self._cleanup_list.append((repo_path, repos.svn_repos_delete))
     return (handle, repo_path, repo_uri)
+
+  def alloc_known_repo(self, repo_id, suffix = ""):
+    """Create a temporary repository and fill it with the contents of the
+       specified dump. repo_id is the path to the dump, relative to the script's
+       location. Returns the same as alloc_empty_repo."""
+    dump_path = os.path.join(os.path.dirname(sys.argv[0]), repo_id)
+    (handle, repo_path, repo_uri) = self.alloc_empty_repo(suffix=suffix)
+    repos.svn_repos_load_fs2(handle, open(dump_path, 'rb'), StringIO(),
+                             repos.load_uuid_default, None, False, False, None)
+    return (handle, repo_path, repo_uri)
     
-  @classmethod
-  def _file_uri_for_path(cls, path):
-    uri_path = urllib.pathname2url(path)
-
-    # pathname2url claims to return the path part of the URI, but on Windows
-    # it returns both the authority and path parts for no reason, which
-    # means we have to trim the leading slashes to "normalize" the result.
-    return 'file:///' + uri_path.lstrip('/')
+def file_uri_for_path(path):
+  """Return the file: URI corresponding to the given path."""
+  uri_path = urllib.pathname2url(path)
+
+  # pathname2url claims to return the path part of the URI, but on Windows
+  # it returns both the authority and path parts for no reason, which
+  # means we have to trim the leading slashes to "normalize" the result.
+  return 'file:///' + uri_path.lstrip('/')

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/wc.py?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/wc.py (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/python/tests/wc.py Wed Sep 15 19:32:26 2010
@@ -30,9 +30,7 @@ import svn.diff
 from svn import core, repos, wc, client
 from svn import delta, ra
 from svn.core import SubversionException, SVN_INVALID_REVNUM
-
-from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
-  REPOS_PATH, REPOS_URL
+import utils
 
 class SubversionWorkingCopyTestCase(unittest.TestCase):
   """Test cases for the Subversion working copy layer"""
@@ -40,23 +38,21 @@ class SubversionWorkingCopyTestCase(unit
   def setUp(self):
     """Load a Subversion repository"""
 
-    # Isolate each test from the others with a fresh repository.
-    # Eventually, we should move this into a shared TestCase base
-    # class that all test cases in this directory can use.
-    SubversionRepositoryTestSetup().setUp()
+    self.temper = utils.Temper()
 
-    # Open repository directly for cross-checking
-    self.repos = repos.open(REPOS_PATH)
+    # Isolate each test from the others with a fresh repository.
+    (self.repos, _, self.repos_uri) = self.temper.alloc_known_repo(
+      'trac/versioncontrol/tests/svnrepos.dump', suffix='-wc-repo')
     self.fs = repos.fs(self.repos)
 
-    self.path = core.svn_dirent_internal_style(tempfile.mktemp())
+    self.path = self.temper.alloc_empty_dir(suffix='-wc-wc')
 
     client_ctx = client.create_context()
 
     rev = core.svn_opt_revision_t()
     rev.kind = core.svn_opt_revision_head
 
-    client.checkout2(REPOS_URL, self.path, rev, rev, True, True,
+    client.checkout2(self.repos_uri, self.path, rev, rev, True, True,
             client_ctx)
 
     self.wc = wc.adm_open3(None, self.path, True, -1, None)
@@ -159,7 +155,7 @@ class SubversionWorkingCopyTestCase(unit
       self.assert_(wc.check_wc(self.path) > 0)
 
   def test_get_ancestry(self):
-      self.assertEqual([REPOS_URL, 12],
+      self.assertEqual([self.repos_uri, 12],
                        wc.get_ancestry(self.path, self.wc))
 
   def test_status(self):
@@ -212,9 +208,11 @@ class SubversionWorkingCopyTestCase(unit
 
   def test_get_pristine_copy_path(self):
       path_to_file = '%s/trunk/README.txt' % self.path
-      path_to_text_base = '%s/trunk/%s/text-base/README.txt.svn-base' % (self.path,
-        wc.get_adm_dir())
-      self.assertEqual(path_to_text_base, wc.get_pristine_copy_path(path_to_file))
+      path_to_text_base = wc.get_pristine_copy_path(path_to_file)
+      text_base = open(path_to_text_base).read()
+      # TODO: This test should modify the working file first, to ensure the
+      # path isn't just the path to the working file.
+      self.assertEqual(text_base, 'A test.\n')
 
   def test_entries_read(self):
       entries = wc.entries_read(self.wc, True)
@@ -235,7 +233,7 @@ class SubversionWorkingCopyTestCase(unit
     # Setup ra_ctx.
     ra.initialize()
     callbacks = ra.Callbacks()
-    ra_ctx = ra.open2(REPOS_URL, callbacks, None, None)
+    ra_ctx = ra.open2(self.repos_uri, callbacks, None, None)
 
     # Get commit editor.
     commit_info = [None]
@@ -292,7 +290,7 @@ class SubversionWorkingCopyTestCase(unit
   def test_diff_editor4(self):
     pool = None
     depth = core.svn_depth_infinity
-    url = REPOS_URL
+    url = self.repos_uri
 
     # cause file_changed: Replace README.txt's contents.
     readme_path = '%s/trunk/README.txt' % self.path
@@ -439,13 +437,14 @@ class SubversionWorkingCopyTestCase(unit
     self.assertEqual(got_diffs, expected_diffs)
 
   def tearDown(self):
-      #wc.adm_close(self.wc)
-      #core.svn_io_remove_dir(self.path)
+      wc.adm_close(self.wc)
       self.fs = None
       self.repos = None
+      self.temper.cleanup()
 
 def suite():
-    return unittest.makeSuite(SubversionWorkingCopyTestCase, 'test')
+    return unittest.defaultTestLoader.loadTestsFromTestCase(
+      SubversionWorkingCopyTestCase)
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/svn/core.rb
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/svn/core.rb?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/svn/core.rb (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/svn/core.rb Wed Sep 15 19:32:26 2010
@@ -669,16 +669,16 @@ module Svn
 
       def infinity_or_empty_from_recurse(depth_or_recurse)
         case depth_or_recurse
-          when true  : DEPTH_INFINITY
-          when false : DEPTH_EMPTY
+          when true  then DEPTH_INFINITY
+          when false then DEPTH_EMPTY
           else depth_or_recurse
         end
       end
 
       def infinity_or_immediates_from_recurse(depth_or_recurse)
         case depth_or_recurse
-          when true  : DEPTH_INFINITY
-          when false : DEPTH_IMMEDIATES
+          when true  then DEPTH_INFINITY
+          when false then DEPTH_IMMEDIATES
           else depth_or_recurse
         end
       end

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_client.rb
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_client.rb?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_client.rb (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_client.rb Wed Sep 15 19:32:26 2010
@@ -1079,6 +1079,12 @@ class SvnClientTest < Test::Unit::TestCa
     end
   end
 
+=begin
+  We haven't yet figured out what to expect in the case of an obstruction,
+  but it is no longer an error.  Commenting out this test until that
+  decision is made (see issue #3680:
+  http://subversion.tigris.org/issues/show_bug.cgi?id=3680)
+
   def test_cleanup
     log = "sample log"
     file = "sample.txt"
@@ -1124,6 +1130,7 @@ class SvnClientTest < Test::Unit::TestCa
       end
     end
   end
+=end
 
   def test_relocate
     log = "sample log"

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_info.rb
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_info.rb?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_info.rb (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_info.rb Wed Sep 15 19:32:26 2010
@@ -133,14 +133,13 @@ class SvnInfoTest < Test::Unit::TestCase
       assert_equal([].sort, info.deleted_dirs)
       assert_equal(["#{dir_svn_path}/", "#{tmp_dir_svn_path}/"].sort,
                    info.added_dirs)
-
-      File.open(file1_path, "w") {|f| f.puts "changed"}
-      File.open(file2_path, "w") {|f| f.puts "changed"}
-      File.open(file3_path, "w") {|f| f.puts "changed"}
     end
 
     log = "changed 3 files\ndeleted 2 files\nadded 3 files"
     make_context(log) do |ctx|
+      File.open(file1_path, "w") {|f| f.puts "changed"}
+      File.open(file2_path, "w") {|f| f.puts "changed"}
+      File.open(file3_path, "w") {|f| f.puts "changed"}
       ctx.rm_f([file4_path, file5_path])
       FileUtils.touch(file6_path)
       FileUtils.touch(file7_path)

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_wc.rb
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_wc.rb?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_wc.rb (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/ruby/test/test_wc.rb Wed Sep 15 19:32:26 2010
@@ -1052,9 +1052,9 @@ EOE
     Svn::Wc::AdmAccess.open(nil, @wc_path) do |access|
       access.set_changelist(path, "456", nil, notify_collector)
     end
-    assert_equal([[File.expand_path(path), Svn::Error::WcChangelistMove],
-                  [File.expand_path(path), NilClass]],
-                 notifies.collect {|notify| [notify.path, notify.err.class]})
+    assert_equal([[File.expand_path(path), Svn::Wc::NOTIFY_CHANGELIST_CLEAR],
+                  [File.expand_path(path), Svn::Wc::NOTIFY_CHANGELIST_SET]],
+                 notifies.collect {|notify| [notify.path, notify.action]})
 
     notifies = []
 

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_delta.i
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_delta.i?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_delta.i (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_delta.i Wed Sep 15 19:32:26 2010
@@ -172,6 +172,60 @@ svn_txdelta_window_t_ops_get(svn_txdelta
 %}
 #endif
 
+#ifdef SWIGPYTHON
+%ignore svn_txdelta_window_t::ops;
+%inline %{
+static PyObject *
+svn_txdelta_window_t_ops_get(PyObject *window_ob)
+{
+  void *window;
+  PyObject *ops_list, *window_pool;
+  int status;
+  
+  /* Kludge alert!
+     Normally, these kinds of conversions would belong in a typemap.
+     However, typemaps won't allow us to change the result type to an array,
+     so we have to make this custom accessor function.
+     A cleaner approach would be to use something like: 
+     
+     %extend svn_txdelta_window_t { void get_ops(apr_array_header_t ** ops); }
+     
+     But that means unnecessary copying, plus more hacks to get the pool for the
+     array and for wrapping the individual op objects. So we just don't bother.
+  */
+  
+  /* Note: the standard svn-python typemap releases the GIL while calling the
+     wrapped function, but this function does Python stuff, so we have to
+     reacquire it again. */
+  svn_swig_py_acquire_py_lock();
+  status = svn_swig_ConvertPtr(window_ob, &window,
+    SWIG_TypeQuery("svn_txdelta_window_t *"));
+    
+  if (status != 0)
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "expected an svn_txdelta_window_t* proxy");
+      svn_swig_py_release_py_lock();
+      return NULL;
+    }
+    
+  window_pool = PyObject_GetAttrString(window_ob, "_parent_pool");
+
+  if (window_pool == NULL)
+    {
+      svn_swig_py_release_py_lock();
+      return NULL;
+    }
+    
+  ops_list = svn_swig_py_txdelta_window_t_ops_get(window,
+    SWIG_TypeQuery("svn_txdelta_op_t *"), window_pool);
+    
+  svn_swig_py_release_py_lock();
+  
+  return ops_list;
+}
+%}
+#endif
 
 %include svn_delta_h.swg
 

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_diff.i
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_diff.i?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_diff.i (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_diff.i Wed Sep 15 19:32:26 2010
@@ -48,9 +48,9 @@
 
 /* The WRAPPED_STREAM typemap can't cope with struct members, and there
    isn't really a reason to change these. */
-%immutable svn_hunk_t::diff_text;
-%immutable svn_hunk_t::original_text;
-%immutable svn_hunk_t::modified_text;
+%immutable svn_diff_hunk_t::diff_text;
+%immutable svn_diff_hunk_t::original_text;
+%immutable svn_diff_hunk_t::modified_text;
 
 /* Ditto. */
 %immutable svn_patch_t::patch_file;

Modified: subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_fs.i
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_fs.i?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_fs.i (original)
+++ subversion/branches/py-tests-as-modules/subversion/bindings/swig/svn_fs.i Wed Sep 15 19:32:26 2010
@@ -62,6 +62,7 @@
 
 %hash_argout_typemap(entries_p, svn_fs_dirent_t *)
 %hash_argout_typemap(changed_paths_p, svn_fs_path_change_t *)
+%hash_argout_typemap(changed_paths2_p, svn_fs_path_change2_t *)
 
 #ifndef SWIGPERL
 %callback_typemap(svn_fs_get_locks_callback_t get_locks_func,

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_dep_compat.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_dep_compat.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_dep_compat.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_dep_compat.h Wed Sep 15 19:32:26 2010
@@ -62,6 +62,19 @@ extern "C" {
 #define apr_array_clear(arr)         (arr)->nelts = 0
 #endif
 
+#if !APR_VERSION_AT_LEAST(1,3,0)
+#define APR_UINT16_MAX  0xFFFFU
+#define APR_INT16_MAX   0x7FFF
+#define APR_INT16_MIN   (-APR_INT16_MAX-1)
+#define APR_UINT32_MAX 0xFFFFFFFFU
+#define APR_INT32_MAX  0x7FFFFFFF
+#define APR_INT32_MIN (-APR_INT32_MAX-1)
+#define APR_UINT64_MAX APR_UINT64_C(0xFFFFFFFFFFFFFFFF)
+#define APR_INT64_MAX   APR_INT64_C(0x7FFFFFFFFFFFFFFF)
+#define APR_INT64_MIN (-APR_INT64_MAX-1)
+#define APR_SIZE_MAX (~(apr_size_t)0)
+#endif
+
 /**
  * Check at compile time if the Serf version is at least a certain
  * level.

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_eol_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_eol_private.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_eol_private.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_eol_private.h Wed Sep 15 19:32:26 2010
@@ -58,23 +58,37 @@ svn_eol__find_eol_start(char *buf, apr_s
  * no more likely to be incorrect than correct for any caller that
  * doesn't.
  *
+ * The returned string is statically allocated.
+ *
+ * ### [JAF] Does it make sense for this to use "[buf, end)" while
+ *     svn_eol__find_eol_start() uses "buf, len"?
+ *
  * @since New in 1.7
  */
 const char *
 svn_eol__detect_eol(char *buf, char *endp);
 
-/* Detect the EOL marker used in @a file and return it in @a *eol.
+/* Set @a *eol to the EOL marker used in @a file.
  * If it cannot be detected, set @a *eol to NULL.
  *
  * The file is searched starting at the current file cursor position.
- * The first EOL marker found will be returnd. So if the file has
+ * The first EOL marker found will be returned. So if the file has
  * inconsistent EOL markers, this won't be detected.
  *
  * Upon return, the original file cursor position is always preserved,
  * even if an error is thrown.
  *
+ * The string @a *eol is statically allocated.
  * Do temporary allocations in @a pool.
  *
+ * ### [JAF] Apparent bug: implementation suffers from the "one byte of a
+ *     two-byte sequence" issue noted for svn_eol__detect_eol().
+ *
+ * ### [JAF] Apparent bug: if file pointer is at EOF, returns "success"
+ *     without initializing @a *eol.
+ *
+ * ### [JAF] Wouldn't it make more sense to accept a stream than a file?
+ *
  * @since New in 1.7 */
 svn_error_t *
 svn_eol__detect_file_eol(const char **eol, apr_file_t *file, apr_pool_t *pool);

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_fs_util.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_fs_util.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_fs_util.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_fs_util.h Wed Sep 15 19:32:26 2010
@@ -98,63 +98,64 @@ svn_fs__check_fs(svn_fs_t *fs, svn_boole
 
 /* SVN_FS__ERR_NOT_MUTABLE: the caller attempted to change a node
    outside of a transaction. FS is of type "svn_fs_t *". */
-#define SVN_FS__ERR_NOT_MUTABLE(fs, rev, path_in_repo)                   \
-  svn_error_createf                                                      \
-    (SVN_ERR_FS_NOT_MUTABLE, 0,                                          \
+#define SVN_FS__ERR_NOT_MUTABLE(fs, rev, path_in_repo, scratch_pool)     \
+  svn_error_createf(                                                     \
+     SVN_ERR_FS_NOT_MUTABLE, 0,                                          \
      _("File is not mutable: filesystem '%s', revision %ld, path '%s'"), \
-     fs->path, rev, path_in_repo)
+     svn_dirent_local_style(fs->path, scratch_pool), rev, path_in_repo)
 
 /* FS is of type "svn fs_t *".*/
-#define SVN_FS__ERR_NOT_DIRECTORY(fs, path_in_repo)    \
-  svn_error_createf                                    \
-    (SVN_ERR_FS_NOT_DIRECTORY, 0,                      \
-     _("'%s' is not a directory in filesystem '%s'"),  \
-     path_in_repo, fs->path)
+#define SVN_FS__ERR_NOT_DIRECTORY(fs, path_in_repo, scratch_pool) \
+  svn_error_createf(                                              \
+     SVN_ERR_FS_NOT_DIRECTORY, 0,                                 \
+     _("'%s' is not a directory in filesystem '%s'"),             \
+     path_in_repo, svn_dirent_local_style(fs->path, scratch_pool))
 
 /* FS is of type "svn fs_t *".   */
-#define SVN_FS__ERR_NOT_FILE(fs, path_in_repo)         \
-  svn_error_createf                                    \
-    (SVN_ERR_FS_NOT_FILE, 0,                           \
-     _("'%s' is not a file in filesystem '%s'"),       \
-     path_in_repo, fs->path)
+#define SVN_FS__ERR_NOT_FILE(fs, path_in_repo, scratch_pool)      \
+  svn_error_createf(                                              \
+     SVN_ERR_FS_NOT_FILE, 0,                                      \
+     _("'%s' is not a file in filesystem '%s'"),                  \
+     path_in_repo, svn_dirent_local_style(fs->path, scratch_pool))
+
 
 /* FS is of type "svn fs_t *", LOCK is of type "svn_lock_t *".   */
-#define SVN_FS__ERR_PATH_ALREADY_LOCKED(fs, lock)                      \
-  svn_error_createf                                                    \
-    (SVN_ERR_FS_PATH_ALREADY_LOCKED, 0,                                \
-     _("Path '%s' is already locked by user '%s' in filesystem '%s'"), \
-     lock->path, lock->owner, fs->path)
+#define SVN_FS__ERR_PATH_ALREADY_LOCKED(fs, lock, scratch_pool)             \
+  svn_error_createf(                                                        \
+     SVN_ERR_FS_PATH_ALREADY_LOCKED, 0,                                     \
+     _("Path '%s' is already locked by user '%s' in filesystem '%s'"),      \
+     lock->path, lock->owner, svn_dirent_local_style(fs->path, scratch_pool))
 
 /* FS is of type "svn fs_t *". */
-#define SVN_FS__ERR_NO_SUCH_LOCK(fs, path_in_repo)     \
-  svn_error_createf                                    \
-    (SVN_ERR_FS_NO_SUCH_LOCK, 0,                       \
-     _("No lock on path '%s' in filesystem '%s'"),     \
-     path_in_repo, fs->path)
+#define SVN_FS__ERR_NO_SUCH_LOCK(fs, path_in_repo, scratch_pool)  \
+  svn_error_createf(                                              \
+     SVN_ERR_FS_NO_SUCH_LOCK, 0,                                  \
+     _("No lock on path '%s' in filesystem '%s'"),                \
+     path_in_repo, svn_dirent_local_style(fs->path, scratch_pool))
 
 /* FS is of type "svn fs_t *". */
-#define SVN_FS__ERR_LOCK_EXPIRED(fs, token)                      \
-  svn_error_createf                                              \
-    (SVN_ERR_FS_LOCK_EXPIRED, 0,                                 \
-     _("Lock has expired: lock-token '%s' in filesystem '%s'"), \
-     token, fs->path)
+#define SVN_FS__ERR_LOCK_EXPIRED(fs, token, scratch_pool)        \
+  svn_error_createf(                                             \
+     SVN_ERR_FS_LOCK_EXPIRED, 0,                                 \
+     _("Lock has expired: lock-token '%s' in filesystem '%s'"),  \
+     token, svn_dirent_local_style(fs->path, scratch_pool))
 
 /* FS is of type "svn fs_t *". */
-#define SVN_FS__ERR_NO_USER(fs)                                     \
-  svn_error_createf                                                 \
-    (SVN_ERR_FS_NO_USER, 0,                                         \
+#define SVN_FS__ERR_NO_USER(fs, scratch_pool)                       \
+  svn_error_createf(                                                \
+     SVN_ERR_FS_NO_USER, 0,                                         \
      _("No username is currently associated with filesystem '%s'"), \
-     fs->path)
+     svn_dirent_local_style(fs->path, scratch_pool))
 
 /* SVN_FS__ERR_LOCK_OWNER_MISMATCH: trying to use a lock whose
    LOCK_OWNER doesn't match the USERNAME associated with FS.
    FS is of type "svn fs_t *". */
-#define SVN_FS__ERR_LOCK_OWNER_MISMATCH(fs, username, lock_owner)  \
-  svn_error_createf                                                \
-    (SVN_ERR_FS_LOCK_OWNER_MISMATCH, 0,                            \
-     _("User '%s' is trying to use a lock owned by '%s' in "       \
-       "filesystem '%s'"),                                         \
-     username, lock_owner, fs->path)
+#define SVN_FS__ERR_LOCK_OWNER_MISMATCH(fs, username, lock_owner, pool) \
+  svn_error_createf(                                                    \
+     SVN_ERR_FS_LOCK_OWNER_MISMATCH, 0,                                 \
+     _("User '%s' is trying to use a lock owned by '%s' in "            \
+       "filesystem '%s'"),                                              \
+     username, lock_owner, svn_dirent_local_style(fs->path, pool))
 
 /* Return a NULL-terminated copy of the first component of PATH,
    allocated in POOL.  If path is empty, or consists entirely of

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_mergeinfo_private.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_mergeinfo_private.h Wed Sep 15 19:32:26 2010
@@ -225,6 +225,21 @@ svn_rangelist__initialize(svn_revnum_t s
                           svn_boolean_t inheritable,
                           apr_pool_t *result_pool);
 
+/* Adjust in-place MERGEINFO's rangelists by OFFSET.  If OFFSET is negative 
+   and would adjust any part of MERGEINFO's source revisions to 0 or less,
+   then those revisions are dropped.  If all the source revisions for a merge
+   source path are dropped, then the path itself is dropped.  If all merge
+   source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty
+   hash.  *ADJUSTED_MERGEINFO is allocated in RESULT_POOL.  SCRATCH_POOL is
+   used for any temporary allocations. */
+svn_error_t *
+svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo,
+                                           svn_mergeinfo_t mergeinfo,
+                                           svn_revnum_t offset,
+                                           apr_pool_t *result_pool,
+                                           apr_pool_t *scratch_pool);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_opt_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_opt_private.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_opt_private.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_opt_private.h Wed Sep 15 19:32:26 2010
@@ -66,7 +66,6 @@ svn_opt__split_arg_at_peg_revision(const
 /* Attempt to transform URL_IN, which is a URL-like user input, into a
  * valid URL:
  *   - escape IRI characters and some other non-URI characters
- *   - check that only valid URI characters remain
  *   - check that no back-path ("..") components are present
  *   - canonicalize the separator ("/") characters
  * URL_IN is in UTF-8 encoding and has no peg revision specifier.

Modified: subversion/branches/py-tests-as-modules/subversion/include/private/svn_skel.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/include/private/svn_skel.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/include/private/svn_skel.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/include/private/svn_skel.h Wed Sep 15 19:32:26 2010
@@ -163,11 +163,11 @@ void svn_skel__prepend_str(const char *v
                            apr_pool_t *result_pool);
 
 
-/* Parse SKEL as an integer. SCRATCH_POOL is used for temporary memory.
-   NOTE: this function assumes the input is valid -- there is no way to
-   return an error.  */
-apr_int64_t svn_skel__parse_int(const svn_skel_t *skel,
-                                apr_pool_t *scratch_pool);
+/* Parse SKEL as an integer and return the result in *N.
+ * SCRATCH_POOL is used for temporary memory.  */
+svn_error_t *
+svn_skel__parse_int(apr_int64_t *n, const svn_skel_t *skel,
+                    apr_pool_t *scratch_pool);
 
 
 /* Return a string whose contents are a concrete representation of