]> granicus.if.org Git - php/commitdiff
new unit tests
authorGreg Beaver <cellog@php.net>
Sat, 29 May 2004 08:51:59 +0000 (08:51 +0000)
committerGreg Beaver <cellog@php.net>
Sat, 29 May 2004 08:51:59 +0000 (08:51 +0000)
pearweb mock object is complete

pear/tests/PEAR_test_mock_pearweb.php.inc
pear/tests/download_test.config.inc [new file with mode: 0644]
pear/tests/download_test_classes.php.inc [new file with mode: 0644]
pear/tests/merge2.input [new file with mode: 0644]
pear/tests/pear_channelfile.phpt [new file with mode: 0644]
pear/tests/pear_installer_installFile_channels.phpt [new file with mode: 0644]
pear/tests/pear_installer_install_channels.phpt [new file with mode: 0644]
pear/tests/pear_registry_1.1.phpt [new file with mode: 0644]
pear/tests/user3.input [new file with mode: 0644]

index d042c947a240f16d65c0e6779d78a57029477939..9206a4d2900127f15af6ad5d085c30e2010a43a0 100644 (file)
@@ -3,17 +3,28 @@ require_once 'XML/RPC/Server.php';
 
 class PEAR_test_mock_pearweb {
     var $_config;
+    var $_remote;
     
-    function addHtmlConfig($address, $contents)
+    function setRemote(&$r)
     {
-        $this->_config['html'][$address] = $contents;
+        $this->_remote = &$r;
+    }
+
+    function addHtmlConfig($address, $filename)
+    {
+        $this->_config['html'][$address] = array(basename($filename), file_get_contents($filename));
     }
     
     function addXmlrpcConfig($method, $params, $return)
     {
-        $val = XML_RPC_encode($return);
+        $this->_config['xmlrpc'][$method][serialize($params)] = $return;
+    }
+    
+    function _encode($val)
+    {
+        $val = XML_RPC_encode($val);
         $ser = new XML_RPC_Response($val);
-        $this->_config['xmlrpc'][$method][serialize($params)] = $ser->serialize();
+        return $ser->serialize();
     }
     
     function receiveHttp($address)
@@ -21,11 +32,12 @@ class PEAR_test_mock_pearweb {
         if (!isset($this->_config) || !is_array($this->_config)) {
             return $this->do404($address);
         }
-        if (!isset($this->_config[$address])) {
+        if (!isset($this->_config['html'][$address])) {
             return $this->do404($address);
-        }
-        if (isset($this->_config['html'][$address])) {
-            return $this->do200() . $this->_config['html'][$address];
+        } else {
+            return $this->do200() .
+                'content-length: ' . strlen($this->_config['html'][$address][1]) . "\n\n" .
+                $this->_config['html'][$address][1];
         }
     }
     
@@ -39,7 +51,54 @@ class PEAR_test_mock_pearweb {
             var_dump($info['param']);
             die("Error - parameters not configured properly for $info[method]");
         }
-        return $this->do200() . $this->_config['xmlrpc'][$info['method']][serialize($info['params'])];
+        return $this->do200() .
+            $this->_encode($this->_config['xmlrpc'][$info['method']][serialize($info['params'])]);
+    }
+    
+    function call($method, $params)
+    {
+        if (!isset($this->_config['xmlrpc'][$method])) {
+            return false;
+        }
+        if (!isset($this->_config['xmlrpc'][$method][serialize($params)])) {
+            $args = $params;
+            switch (count($args)) {
+                case 0:
+                    $result = $this->_remote->parentcall($method);
+                break;
+                case 1:
+                    $result = $this->_remote->parentcall($method, $args[0]);
+                break;
+                case 2:
+                    $result = $this->_remote->parentcall($method, $args[0], $args[1]);
+                break;
+                case 3:
+                    $result = $this->_remote->parentcall_epi($method, $args[0], $args[1], $args[2]);
+                break;
+                case 4:
+                    $result = $this->_remote->parentcall($method, $args[0], $args[1], $args[2], $args[3]);
+                break;
+                case 5:
+                    $result = $this->_remote->parentcall($method, $args[0], $args[1], $args[2], $args[3], $args[4]);
+                break;
+                case 6:
+                    $result = $this->_remote->parentcall($method, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
+                break;
+            }
+            $dump = new PHP_Dump($result);
+            $args = new PHP_Dump($args);
+            if (!isset($this->_pearweb->_config['xmlrpc'][$method][serialize($args)]))
+            $GLOBALS['totalPHP'][$method . serialize($args)] = '$pearweb->addXmlrpcConfig("' .
+                $method . '", ' .
+                $args->toPHP() . ', ' .
+                $dump->toPHP() .");";
+            foreach($GLOBALS['totalPHP'] as $php) {
+                echo $php . "\n";
+            }
+            var_dump(array_keys($this->_config['xmlrpc'][$method]), $params);
+            die("Error - parameters not configured properly for $method");
+        }
+        return $this->_config['xmlrpc'][$method][serialize($params)];
     }
     
     function doXmlrpcFault($info)
@@ -50,14 +109,14 @@ class PEAR_test_mock_pearweb {
     
     function do200()
     {
-        return 'HTTP/1.1 200 ';
+        return "HTTP/1.1 200 \n";
     }
     
     function do404($address)
     {
         return 'HTTP/1.1 404 ' . $address . ' Is not valid';
     }
-    
+
     /**
      * Parse an xmlrpc request
      * @param string fake HTTP_RAW_POST_DATA
diff --git a/pear/tests/download_test.config.inc b/pear/tests/download_test.config.inc
new file mode 100644 (file)
index 0000000..b330e0a
--- /dev/null
@@ -0,0 +1,920 @@
+<?php
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg6\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '2.0b1' =>
+        array(
+        'id' =>
+            "9",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:34:03",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '1.1' =>
+        array(
+        'id' =>
+            "7",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:03:37",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg2\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '1.1' =>
+        array(
+        'id' =>
+            "3",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:02:56",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg3\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '1.4' =>
+        array(
+        'id' =>
+            "11",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:51:31",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "alpha",
+        ),
+    '1.1' =>
+        array(
+        'id' =>
+            "4",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:03:06",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg4\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '1.1' =>
+        array(
+        'id' =>
+            "5",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:03:17",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg5\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '1.1' =>
+        array(
+        'id' =>
+            "6",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:03:25",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:4:\"pkg1\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '2.0b1' =>
+        array(
+        'id' =>
+            "8",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:29:15",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '1.1' =>
+        array(
+        'id' =>
+            "2",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:02:43",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info", unserialize("a:3:{i:0;s:12:\"pkg4AndAHalf\";i:1;s:8:\"releases\";i:2;b:1;}"),     array(
+    '1.3' =>
+        array(
+        'id' =>
+            "10",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:50:05",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "noreleases",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "pkg1",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    '2.0b1' =>
+        array(
+        'id' =>
+            "8",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:29:15",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '1.1' =>
+        array(
+        'id' =>
+            "2",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:02:43",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "stabilitytoolow",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    '3.0dev' =>
+        array(
+        'id' =>
+            "23",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:27:38",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "devel",
+        ),
+    '2.0a1' =>
+        array(
+        'id' =>
+            "22",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:27:19",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "alpha",
+        ),
+    '1.0b1' =>
+        array(
+        'id' =>
+            "21",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:26:42",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '0.6beta' =>
+        array(
+        'id' =>
+            "20",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:26:36",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '0.5' =>
+        array(
+        'id' =>
+            "19",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:26:28",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "alpha",
+        ),
+    '0.3' =>
+        array(
+        'id' =>
+            "18",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 00:26:21",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "devel",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "pkg6",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    '2.0b1' =>
+        array(
+        'id' =>
+            "9",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 18:34:03",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "beta",
+        ),
+    '1.1' =>
+        array(
+        'id' =>
+            "7",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-03 17:03:37",
+        'releasenotes' =>
+            "required dependency test",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "depnoreleases",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    '1.0' =>
+        array(
+        'id' =>
+            "24",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 17:10:42",
+        'releasenotes' =>
+            "dependency has no releases test",
+        'state' =>
+            "beta",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "depunstable",
+    1 =>
+        "releases",
+    2 =>
+        true,
+    ),     array(
+    '1.0' =>
+        array(
+        'id' =>
+            "26",
+        'doneby' =>
+            "cellog",
+        'license' =>
+            "",
+        'summary' =>
+            "",
+        'description' =>
+            "",
+        'releasedate' =>
+            "2003-12-06 17:32:38",
+        'releasenotes' =>
+            "dependency stability is too low",
+        'state' =>
+            "stable",
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "stabilitytoolow",
+    ),     array(
+    'packageid' =>
+        "9",
+    'name' =>
+        "stabilitytoolow",
+    'type' =>
+        "pear",
+    'categoryid' =>
+        "1",
+    'category' =>
+        "Test",
+    'stable' =>
+        "3.0dev",
+    'license' =>
+        "PHP License",
+    'summary' =>
+        "required test for PEAR_Installer",
+    'homepage' =>
+        "",
+    'description' =>
+        "fake package",
+    'cvs_link' =>
+        "",
+    'doc_link' =>
+        "",
+    'releases' =>
+        array(
+        '3.0dev' =>
+            array(
+            'id' =>
+                "23",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:27:38",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "devel",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        '2.0a1' =>
+            array(
+            'id' =>
+                "22",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:27:19",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "alpha",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        '1.0b1' =>
+            array(
+            'id' =>
+                "21",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:26:42",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "beta",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        '0.6beta' =>
+            array(
+            'id' =>
+                "20",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:26:36",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "beta",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        '0.5' =>
+            array(
+            'id' =>
+                "19",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:26:28",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "alpha",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        '0.3' =>
+            array(
+            'id' =>
+                "18",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 00:26:21",
+            'releasenotes' =>
+                "required dependency test",
+            'state' =>
+                "devel",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "pkg6",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        ),
+    'notes' =>
+        array(
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "depnoreleases",
+    ),     array(
+    'packageid' =>
+        "10",
+    'name' =>
+        "depnoreleases",
+    'type' =>
+        "pear",
+    'categoryid' =>
+        "1",
+    'category' =>
+        "Test",
+    'stable' =>
+        "1.0",
+    'license' =>
+        "PHP License",
+    'summary' =>
+        "required test for PEAR_Installer",
+    'homepage' =>
+        "",
+    'description' =>
+        "fake package",
+    'cvs_link' =>
+        "",
+    'doc_link' =>
+        "",
+    'releases' =>
+        array(
+        '1.0' =>
+            array(
+            'id' =>
+                "24",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 17:10:42",
+            'releasenotes' =>
+                "dependency has no releases test",
+            'state' =>
+                "beta",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0",
+                    'name' =>
+                        "noreleases",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        ),
+    'notes' =>
+        array(
+        ),
+    ));
+$pearweb->addXmlrpcConfig("package.info",     array(
+    0 =>
+        "depunstable",
+    ),     array(
+    'packageid' =>
+        "11",
+    'name' =>
+        "depunstable",
+    'type' =>
+        "pear",
+    'categoryid' =>
+        "1",
+    'category' =>
+        "Test",
+    'stable' =>
+        "1.0",
+    'license' =>
+        "PHP License",
+    'summary' =>
+        "required test for PEAR_Installer",
+    'homepage' =>
+        "",
+    'description' =>
+        "fake package",
+    'cvs_link' =>
+        "",
+    'doc_link' =>
+        "",
+    'releases' =>
+        array(
+        '1.0' =>
+            array(
+            'id' =>
+                "26",
+            'doneby' =>
+                "cellog",
+            'license' =>
+                "",
+            'summary' =>
+                "",
+            'description' =>
+                "",
+            'releasedate' =>
+                "2003-12-06 17:32:38",
+            'releasenotes' =>
+                "dependency stability is too low",
+            'state' =>
+                "stable",
+            'deps' =>
+                array(
+                0 =>
+                    array(
+                    'type' =>
+                        "pkg",
+                    'relation' =>
+                        "ge",
+                    'version' =>
+                        "1.0b1",
+                    'name' =>
+                        "stabilitytoolow",
+                    'optional' =>
+                        "0",
+                    ),
+                ),
+            ),
+        ),
+    'notes' =>
+        array(
+        ),
+    ));
+
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg6-1.1.tgz",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'pkg6-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg6-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'pkg6-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg6-2.0b1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'pkg6-2.0b1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg2-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pkg2-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg3-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg3-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg4-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg4-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg5-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg5-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg1-1.1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pkg1-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg1-1.1.tgz",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pkg1-1.1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg1-2.0b1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg1-2.0b1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg3-1.4",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg3-1.4.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/pkg4AndAHalf-1.3",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'pkg4AndAHalf-1.3.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-0.3",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-0.3.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-0.5",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-0.5.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-0.6beta",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-0.6beta.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-1.0b1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-1.0b1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-2.0a1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-2.0a1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-2.0b1",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-2.0b1.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-2.0dev",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-2.0dev.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow-3.0dev",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-3.0dev.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/depnoreleases-1.0",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'depnoreleases-1.0.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/depunstable-1.0",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'depunstable-1.0.tgz');
+$pearweb->addHtmlConfig("http://pear.Chiara/get/stabilitytoolow",
+    dirname(__FILE__) . DIRECTORY_SEPARATOR .  'stabilitytoolow-3.0dev.tgz');
+?>
\ No newline at end of file
diff --git a/pear/tests/download_test_classes.php.inc b/pear/tests/download_test_classes.php.inc
new file mode 100644 (file)
index 0000000..c27696d
--- /dev/null
@@ -0,0 +1,404 @@
+<?php
+require_once 'XML/RPC.php';
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'PEAR_test_mock_pearweb.php.inc';
+$GLOBALS['pearweb'] = new PEAR_test_mock_pearweb;
+class test_XML_RPC_Client extends XML_RPC_Client {
+    function test_XML_RPC_Client()
+    {
+        $this->_fakepearweb = &$GLOBALS['pearweb'];
+    }
+
+    function sendPayloadHTTP10($msg, $server, $port, $timeout=0,
+                               $username="", $password="")
+    {
+        // Only create the payload if it was not created previously
+        if(empty($msg->payload)) $msg->createPayload();
+
+        $resp = $this->_fakepearweb->receiveXmlrpc($msg->payload);
+        
+        $resp=$msg->parseResponse($resp);
+        return $resp;
+    }
+}
+require_once 'PEAR/Remote.php';
+
+class test_PEAR_Remote extends PEAR_Remote {
+    var $_pearweb;
+    var $_fakepearweb = true;
+    var $_simulateEpi = true;
+    function test_PEAR_Remote($config)
+    {
+        $pearweb = &$GLOBALS['pearweb'];
+        include dirname(__FILE__) . DIRECTORY_SEPARATOR . 'download_test.config.inc';
+        $this->_pearweb = $pearweb;
+        parent::PEAR_Remote($config);
+        $this->_pearweb->setRemote($this);
+    }
+    
+    function parentcall()
+    {
+        $args = func_get_args();
+        $method = array_shift($args);
+        switch (count($args)) {
+            case 0:
+                $result = PEAR_Remote::call_epi($method);
+            break;
+            case 1:
+                $result = PEAR_Remote::call_epi($method, $args[0]);
+            break;
+            case 2:
+                $result = PEAR_Remote::call_epi($method, $args[0], $args[1]);
+            break;
+            case 3:
+                $result = PEAR_Remote::call_epi($method, $args[0], $args[1], $args[2]);
+            break;
+            case 4:
+                $result = PEAR_Remote::call_epi($method, $args[0], $args[1], $args[2], $args[3]);
+            break;
+            case 5:
+                $result = PEAR_Remote::call_epi($method, $args[0], $args[1], $args[2], $args[3], $args[4]);
+            break;
+            case 6:
+                $result = PEAR_Remote::call_epi($method, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
+            break;
+        }
+        return $result;
+    }
+
+    function call($method)
+    {
+        $_args = $args = func_get_args();
+
+        $server_channel = $this->config->get('default_channel');
+        $channel = $this->_registry->getChannel($server_channel);
+        if ($channel) {
+            if (!$channel->supports('xml-rpc', $method)) {
+                // check for channel.list, which is implicitly supported for the PEAR channel
+                if (!(strtolower($server_channel) == 'pear' && $method == 'channel.list')) {
+                    return $this->raiseError("Channel $server_channel does not support xml-rpc method $method");
+                }
+            }
+        }
+
+        array_unshift($_args, $channel); // cache by channel
+        $this->cache = $this->getCache($_args);
+        $cachettl = $this->config->get('cache_ttl');
+        // If cache is newer than $cachettl seconds, we use the cache!
+        if ($this->cache !== null && $this->cache['age'] < $cachettl) {
+            return $this->cache['content'];
+        };
+        if ($this->_simulateEpi) {
+            $result = call_user_func_array(array(&$this, 'call_epi'), $args);
+            if (!PEAR::isError($result)) {
+                $this->saveCache($_args, $result);
+            };
+            return $result;
+        }
+        if (!@include_once("XML/RPC.php")) {
+            return $this->raiseError("For this remote PEAR operation you need to install the XML_RPC package");
+        }
+        array_shift($args);
+        $server_host = $this->_registry->channelInfo($server_channel, 'server');
+        $username = $this->config->get('username');
+        $password = $this->config->get('password');
+        $eargs = array();
+        foreach($args as $arg) $eargs[] = $this->_encode($arg);
+        $f = new XML_RPC_Message($method, $eargs);
+        if ($this->cache !== null) {
+            $maxAge = '?maxAge='.$this->cache['lastChange'];
+        } else {
+            $maxAge = '';
+        };
+        $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
+        if ($proxy = parse_url($this->config->get('http_proxy'))) {
+            $proxy_host = @$proxy['host'];
+            $proxy_port = @$proxy['port'];
+            $proxy_user = @$proxy['user'];
+            $proxy_pass = @$proxy['pass'];
+        }
+        $c = new test_XML_RPC_Client('/xmlrpc.php'.$maxAge, $server_host, 80, $proxy_host, $proxy_port, $proxy_user, $proxy_pass);
+        if ($username && $password) {
+            $c->setCredentials($username, $password);
+        }
+        if ($this->config->get('verbose') >= 3) {
+            $c->setDebug(1);
+        }
+        $r = $c->send($f);
+        if (!$r) {
+            return $this->raiseError("XML_RPC send failed");
+        }
+        $v = $r->value();
+        if ($e = $r->faultCode()) {
+            if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) {
+                return $this->cache['content'];
+            }
+            return $this->raiseError($r->faultString(), $e);
+        }
+
+        $result = XML_RPC_decode($v);
+        $this->saveCache($_args, $result);
+        return $result;
+    }
+
+    function call_epi($method)
+    {
+        $args = func_get_args();
+        array_shift($args);
+        if ($this->_fakepearweb) {
+            if (count($args)) {
+                $result = $this->_pearweb->call($method, $args);
+            } else {
+                $result = $this->_pearweb->call($method);
+            }
+        }/* else {
+            switch (count($args)) {
+                case 0:
+                    $result = parent::call($method);
+                break;
+                case 1:
+                    $result = parent::call($method, $args[0]);
+                break;
+                case 2:
+                    $result = parent::call($method, $args[0], $args[1]);
+                break;
+                case 3:
+                    $result = parent::call($method, $args[0], $args[1], $args[2]);
+                break;
+                case 4:
+                    $result = parent::call($method, $args[0], $args[1], $args[2], $args[3]);
+                break;
+                case 5:
+                    $result = parent::call($method, $args[0], $args[1], $args[2], $args[3], $args[4]);
+                break;
+                case 6:
+                    $result = parent::call($method, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
+                break;
+            }
+        }*/
+        if (PEAR::isError($result)) {
+            return $result;
+        }
+        return $result;
+    }
+}
+
+require_once 'PEAR/Installer.php';
+class test_PEAR_Installer extends PEAR_Installer {
+    function download($packages, $options, &$config, &$installpackages,
+                      &$errors, $installed = false, $willinstall = false, $state = false)
+    {
+        // trickiness: initialize here
+        $this->PEAR_Downloader($this->ui, $options, $config);
+        $this->_remote = &new test_PEAR_Remote($config);
+        $ret = PEAR_Downloader::download($packages);
+        $errors = $this->getErrorMsgs();
+        $installpackages = $this->getDownloadedPackages();
+        trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
+                      "in favor of PEAR_Downloader class", E_USER_WARNING);
+        return $ret;
+    }
+    
+    function downloadHttp($url, &$ui, $save_dir = '.', $callback = null)
+    {
+//        return parent::downloadHttp($url, $ui, $save_dir, $callback);
+        if ($callback) {
+            call_user_func($callback, 'setup', array(&$ui));
+        }
+        if (preg_match('!^http://([^/:?#]*)(:(\d+))?(/.*)!', $url, $matches)) {
+            list(,$host,,$port,$path) = $matches;
+        }
+        if (isset($this)) {
+            $config = &$this->config;
+        } else {
+            $config = &PEAR_Config::singleton();
+        }
+        $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
+        if ($proxy = parse_url($config->get('http_proxy'))) {
+            $proxy_host = @$proxy['host'];
+            $proxy_port = @$proxy['port'];
+            $proxy_user = @$proxy['user'];
+            $proxy_pass = @$proxy['pass'];
+
+            if ($proxy_port == '') {
+                $proxy_port = 8080;
+            }
+            if ($callback) {
+                call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
+            }
+        }
+        if (empty($port)) {
+            $port = 80;
+        }
+        // use _pearweb to get file
+        $retrieved = explode("\n", $this->_remote->_pearweb->receiveHttp($url));
+        $headers = array();
+        $line = array_shift($retrieved);
+        while (strlen(trim($line))) {
+            if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
+                $headers[strtolower($matches[1])] = trim($matches[2]);
+            } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
+                if ($matches[1] != 200) {
+                    return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)");
+                }
+            }
+            $line = array_shift($retrieved);
+        }
+        $retrieved = join("\n", $retrieved);
+        if (isset($headers['content-disposition']) &&
+            preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) {
+            $save_as = basename($matches[1]);
+        } else {
+            $save_as = basename($url);
+        }
+        if ($callback) {
+            $tmp = call_user_func($callback, 'saveas', $save_as);
+            if ($tmp) {
+                $save_as = $tmp;
+            }
+        }
+        $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as;
+        if (!$wp = @fopen($dest_file, 'wb')) {
+            fclose($fp);
+            if ($callback) {
+                call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+            }
+            return PEAR::raiseError("could not open $dest_file for writing");
+        }
+        if (isset($headers['content-length'])) {
+            $length = $headers['content-length'];
+        } else {
+            $length = -1;
+        }
+        $bytes = 0;
+        if ($callback) {
+            call_user_func($callback, 'start', array(basename($dest_file), $length));
+        }
+        $start = 0;
+        while ($start < strlen($retrieved) - 1) {
+            $data = substr($retrieved, $start, 1024);
+            $start += 1024;
+            $bytes += strlen($data);
+            if ($callback) {
+                call_user_func($callback, 'bytesread', $bytes);
+            }
+            if (!@fwrite($wp, $data)) {
+                if ($callback) {
+                    call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+                }
+                return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
+            }
+        }
+        fclose($wp);
+        if ($callback) {
+            call_user_func($callback, 'done', $bytes);
+        }
+        return $dest_file;
+    }
+}
+
+require_once 'PEAR/Downloader.php';
+class test_PEAR_Downloader extends PEAR_Downloader {
+    function test_PEAR_Downloader(&$ui, $options, &$config)
+    {
+        parent::PEAR_Downloader($ui, $options, $config);
+        $this->_remote = new test_PEAR_Remote($config);
+    }
+    
+    function downloadHttp($url, &$ui, $save_dir = '.', $callback = null)
+    {
+//        return parent::downloadHttp($url, $ui, $save_dir, $callback);
+        if ($callback) {
+            call_user_func($callback, 'setup', array(&$ui));
+        }
+        if (preg_match('!^http://([^/:?#]*)(:(\d+))?(/.*)!', $url, $matches)) {
+            list(,$host,,$port,$path) = $matches;
+        }
+        if (isset($this)) {
+            $config = &$this->config;
+        } else {
+            $config = &PEAR_Config::singleton();
+        }
+        $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
+        if ($proxy = parse_url($config->get('http_proxy'))) {
+            $proxy_host = @$proxy['host'];
+            $proxy_port = @$proxy['port'];
+            $proxy_user = @$proxy['user'];
+            $proxy_pass = @$proxy['pass'];
+
+            if ($proxy_port == '') {
+                $proxy_port = 8080;
+            }
+            if ($callback) {
+                call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
+            }
+        }
+        if (empty($port)) {
+            $port = 80;
+        }
+        // use _pearweb to get file
+        $retrieved = explode("\n", $this->_remote->_pearweb->receiveHttp($url));
+        $headers = array();
+        $line = array_shift($retrieved);
+        while (strlen(trim($line))) {
+            if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
+                $headers[strtolower($matches[1])] = trim($matches[2]);
+            } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
+                if ($matches[1] != 200) {
+                    return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)");
+                }
+            }
+            $line = array_shift($retrieved);
+        }
+        $retrieved = join("\n", $retrieved);
+        if (isset($headers['content-disposition']) &&
+            preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) {
+            $save_as = basename($matches[1]);
+        } else {
+            $save_as = basename($url);
+        }
+        if ($callback) {
+            $tmp = call_user_func($callback, 'saveas', $save_as);
+            if ($tmp) {
+                $save_as = $tmp;
+            }
+        }
+        $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as;
+        if (!$wp = @fopen($dest_file, 'wb')) {
+            fclose($fp);
+            if ($callback) {
+                call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+            }
+            return PEAR::raiseError("could not open $dest_file for writing");
+        }
+        if (isset($headers['content-length'])) {
+            $length = $headers['content-length'];
+        } else {
+            $length = -1;
+        }
+        $bytes = 0;
+        if ($callback) {
+            call_user_func($callback, 'start', array(basename($dest_file), $length));
+        }
+        $start = 0;
+        while ($start < strlen($retrieved) - 1) {
+            $data = substr($retrieved, $start, 1024);
+            $start += 1024;
+            $bytes += strlen($data);
+            if ($callback) {
+                call_user_func($callback, 'bytesread', $bytes);
+            }
+            if (!@fwrite($wp, $data)) {
+                if ($callback) {
+                    call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+                }
+                return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
+            }
+        }
+        fclose($wp);
+        if ($callback) {
+            call_user_func($callback, 'done', $bytes);
+        }
+        return $dest_file;
+    }
+}
+?>
\ No newline at end of file
diff --git a/pear/tests/merge2.input b/pear/tests/merge2.input
new file mode 100644 (file)
index 0000000..853a6d1
--- /dev/null
@@ -0,0 +1 @@
+a:2:{s:7:"verbose";i:35;s:10:"__channels";a:2:{s:5:"test1";a:1:{s:7:"verbose";i:898;}s:5:"test2";a:1:{s:7:"verbose";i:899;}}}
\ No newline at end of file
diff --git a/pear/tests/pear_channelfile.phpt b/pear/tests/pear_channelfile.phpt
new file mode 100644 (file)
index 0000000..826892e
--- /dev/null
@@ -0,0 +1,1545 @@
+--TEST--
+PEAR_Channelfile
+--SKIPIF--
+<?php
+if (!getenv('PHP_PEAR_RUNTESTS')) {
+    echo 'skip';
+}
+?>
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+chdir(dirname(__FILE__));
+include "PEAR/Channelfile.php";
+require_once 'PEAR/ErrorStack.php';
+
+function logStack($err)
+{
+    echo "caught Error Stack error:\n";
+    echo $err['message'] . "\n";
+    echo 'code : ' . $err['code'] . "\n";
+}
+PEAR_ErrorStack::setDefaultCallback('logStack');
+echo "test default\n";
+$chf = new PEAR_ChannelFile;
+$chf->fromXmlString('<?xml version="1.0" encoding="ISO-8859-1" ?>
+<channel version="1.0">
+ <name>PEAR5</name>
+<summary>PEAR packages for PHP 5</summary>
+<server>pear.php.net</server>
+<subchannels>
+<subchannel name="PEAR5.qa">
+<server>qa.pear.php.net</server>
+<summary>Quality Assurance releases of unmaintained packages</summary>
+<deps><dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+<dep type="php" rel="ge" version="5.0.0"/></deps>
+</subchannel>
+<subchannel name="pear.boo">
+<server>boo.pear.php.net</server>
+<summary>booya</summary>
+<deps><dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+<dep type="php" rel="ge" version="5.1.0"/></deps>
+</subchannel>
+</subchannels>
+<deps>
+ <dep type="php" rel="ge" version="5.0.0"/>
+</deps>
+</channel>');
+
+echo "after parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+$chf->fromXmlString($chf->toXml());
+
+echo "after re-parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+
+echo "test compatibility\n";
+$chf = new PEAR_ChannelFile(true);
+$chf->fromXmlString('<?xml version="1.0" encoding="ISO-8859-1" ?>
+<channel version="1.0">
+ <name>PEAR5</name>
+<summary>PEAR packages for PHP 5</summary>
+<server>pear.php.net</server>
+<subchannels>
+<subchannel name="PEAR5.qa">
+<server>qa.pear.php.net</server>
+<summary>Quality Assurance releases of unmaintained packages</summary>
+<deps><dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+<dep type="php" rel="ge" version="5.0.0"/></deps>
+</subchannel>
+<subchannel name="pear.boo">
+<server>boo.pear.php.net</server>
+<summary>booya</summary>
+<deps><dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+<dep type="php" rel="ge" version="5.1.0"/></deps>
+</subchannel>
+</subchannels>
+<deps>
+ <dep type="php" rel="ge" version="5.0.0"/>
+</deps>
+</channel>');
+
+echo "after parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+$chf->fromXmlString($chf->toXml());
+
+echo "after re-parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+
+echo "\ntest add packagenameregex\n";
+$chf->setPackageNameRegex('[A-Z]+');
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+$chf->fromXmlString($chf->toXml());
+
+echo "after re-parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+
+echo "\ntest add protocols\n";
+$chf->addProtocol('xml-rpc', '1.0', 'package.listall');
+$chf->addProtocol('xml-rpc', '1.0', 'release.list');
+$chf->addProtocol('get', '1.0');
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+$chf->fromXmlString($chf->toXml());
+
+echo "after re-parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+
+echo "\ntest add mirror\n";
+$chf->addMirror('server', 'mirror.php.net');
+$chf->addMirrorProtocol('mirror.php.net', 'xml-rpc', '1.0', 'package.listall');
+$chf->addMirrorProtocol('mirror.php.net', 'xml-rpc', '1.0', 'release.list');
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+$chf->fromXmlString($chf->toXml());
+
+echo "after re-parsing\n";
+var_dump($chf->validate());
+var_dump($chf->toArray());
+var_dump($chf->toXml());
+?>
+--EXPECT--
+test default
+after parsing
+bool(true)
+array(6) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(823) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+after re-parsing
+bool(true)
+array(6) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(823) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+test compatibility
+after parsing
+bool(true)
+array(6) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(823) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+after re-parsing
+bool(true)
+array(6) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(823) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+
+test add packagenameregex
+array(7) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+  ["packagenameregex"]=>
+  string(6) "[A-Z]+"
+}
+string(868) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <packagenameregex>[A-Z]+</packagenameregex>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+after re-parsing
+bool(true)
+array(7) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["packagenameregex"]=>
+  string(6) "[A-Z]+"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(868) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <packagenameregex>[A-Z]+</packagenameregex>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+
+test add protocols
+array(8) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["packagenameregex"]=>
+  string(6) "[A-Z]+"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+  ["provides"]=>
+  array(3) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(15) "package.listall"
+    }
+    [2]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(12) "release.list"
+    }
+    [3]=>
+    array(2) {
+      ["type"]=>
+      string(3) "get"
+      ["version"]=>
+      string(3) "1.0"
+    }
+  }
+}
+string(1065) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <provides>
+  <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+  <protocol type="xml-rpc" version="1.0">release.list</protocol>
+  <protocol type="get" version="1.0"/>
+ </provides>
+ <packagenameregex>[A-Z]+</packagenameregex>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+after re-parsing
+bool(true)
+array(8) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["provides"]=>
+  array(3) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(15) "package.listall"
+    }
+    [2]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(12) "release.list"
+    }
+    [3]=>
+    array(2) {
+      ["type"]=>
+      string(3) "get"
+      ["version"]=>
+      string(3) "1.0"
+    }
+  }
+  ["packagenameregex"]=>
+  string(6) "[A-Z]+"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(1065) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <provides>
+  <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+  <protocol type="xml-rpc" version="1.0">release.list</protocol>
+  <protocol type="get" version="1.0"/>
+ </provides>
+ <packagenameregex>[A-Z]+</packagenameregex>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+
+test add mirror
+array(9) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["provides"]=>
+  array(3) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(15) "package.listall"
+    }
+    [2]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(12) "release.list"
+    }
+    [3]=>
+    array(2) {
+      ["type"]=>
+      string(3) "get"
+      ["version"]=>
+      string(3) "1.0"
+    }
+  }
+  ["packagenameregex"]=>
+  string(6) "[A-Z]+"
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+  ["mirrors"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(6) "server"
+      ["name"]=>
+      string(14) "mirror.php.net"
+      ["provides"]=>
+      array(2) {
+        [1]=>
+        array(3) {
+          ["type"]=>
+          string(7) "xml-rpc"
+          ["version"]=>
+          string(3) "1.0"
+          ["name"]=>
+          string(15) "package.listall"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(7) "xml-rpc"
+          ["version"]=>
+          string(3) "1.0"
+          ["name"]=>
+          string(12) "release.list"
+        }
+      }
+    }
+  }
+}
+string(1313) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <provides>
+  <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+  <protocol type="xml-rpc" version="1.0">release.list</protocol>
+  <protocol type="get" version="1.0"/>
+ </provides>
+ <packagenameregex>[A-Z]+</packagenameregex>
+ <mirrors>
+  <mirror type="server" name="mirror.php.net">
+   <provides>
+    <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+    <protocol type="xml-rpc" version="1.0">release.list</protocol>
+   </provides>
+  </mirror>
+ </mirrors>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
+after re-parsing
+bool(true)
+array(9) {
+  ["version"]=>
+  string(3) "1.0"
+  ["deps"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(3) "php"
+      ["rel"]=>
+      string(2) "ge"
+      ["version"]=>
+      string(5) "5.0.0"
+    }
+  }
+  ["name"]=>
+  string(5) "PEAR5"
+  ["summary"]=>
+  string(23) "PEAR packages for PHP 5"
+  ["server"]=>
+  string(12) "pear.php.net"
+  ["provides"]=>
+  array(3) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(15) "package.listall"
+    }
+    [2]=>
+    array(3) {
+      ["type"]=>
+      string(7) "xml-rpc"
+      ["version"]=>
+      string(3) "1.0"
+      ["name"]=>
+      string(12) "release.list"
+    }
+    [3]=>
+    array(2) {
+      ["type"]=>
+      string(3) "get"
+      ["version"]=>
+      string(3) "1.0"
+    }
+  }
+  ["packagenameregex"]=>
+  string(12) "release.list"
+  ["mirrors"]=>
+  array(1) {
+    [1]=>
+    array(3) {
+      ["type"]=>
+      string(6) "server"
+      ["name"]=>
+      string(14) "mirror.php.net"
+      ["provides"]=>
+      array(2) {
+        [1]=>
+        array(3) {
+          ["type"]=>
+          string(7) "xml-rpc"
+          ["version"]=>
+          string(3) "1.0"
+          ["name"]=>
+          string(15) "package.listall"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(7) "xml-rpc"
+          ["version"]=>
+          string(3) "1.0"
+          ["name"]=>
+          string(12) "release.list"
+        }
+      }
+    }
+  }
+  ["subchannels"]=>
+  array(2) {
+    [1]=>
+    array(4) {
+      ["name"]=>
+      string(8) "PEAR5.qa"
+      ["server"]=>
+      string(15) "qa.pear.php.net"
+      ["summary"]=>
+      string(51) "Quality Assurance releases of unmaintained packages"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.4"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.0.0"
+        }
+      }
+    }
+    [2]=>
+    array(4) {
+      ["name"]=>
+      string(8) "pear.boo"
+      ["server"]=>
+      string(16) "boo.pear.php.net"
+      ["summary"]=>
+      string(5) "booya"
+      ["deps"]=>
+      array(2) {
+        [1]=>
+        array(4) {
+          ["type"]=>
+          string(3) "pkg"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(3) "1.5"
+          ["name"]=>
+          string(4) "PEAR"
+        }
+        [2]=>
+        array(3) {
+          ["type"]=>
+          string(3) "php"
+          ["rel"]=>
+          string(2) "ge"
+          ["version"]=>
+          string(5) "5.1.0"
+        }
+      }
+    }
+  }
+}
+string(1319) "<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/channel-1.0">
+<channel version="1.0">
+ <name>PEAR5</name>
+ <summary>PEAR packages for PHP 5</summary>
+ <server>pear.php.net</server>
+ <provides>
+  <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+  <protocol type="xml-rpc" version="1.0">release.list</protocol>
+  <protocol type="get" version="1.0"/>
+ </provides>
+ <packagenameregex>release.list</packagenameregex>
+ <mirrors>
+  <mirror type="server" name="mirror.php.net">
+   <provides>
+    <protocol type="xml-rpc" version="1.0">package.listall</protocol>
+    <protocol type="xml-rpc" version="1.0">release.list</protocol>
+   </provides>
+  </mirror>
+ </mirrors>
+ <subchannels>
+  <subchannel name="PEAR5.qa" server="qa.pear.php.net">
+   <summary>Quality Assurance releases of unmaintained packages</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.4">PEAR</dep>
+    <dep type="php" rel="ge" version="5.0.0"/>
+   </deps>
+  </subchannel>
+  <subchannel name="pear.boo" server="boo.pear.php.net">
+   <summary>booya</summary>
+   <deps>
+    <dep type="pkg" rel="ge" version="1.5">PEAR</dep>
+    <dep type="php" rel="ge" version="5.1.0"/>
+   </deps>
+  </subchannel>
+ </subchannels>
+ <deps>
+  <dep type="php" rel="ge" version="5.0.0"/>
+ </deps>
+</channel>
+"
\ No newline at end of file
diff --git a/pear/tests/pear_installer_installFile_channels.phpt b/pear/tests/pear_installer_installFile_channels.phpt
new file mode 100644 (file)
index 0000000..376b3c5
--- /dev/null
@@ -0,0 +1,447 @@
+--TEST--
+PEAR_Installer test _installFile() with channels
+--SKIPIF--
+<?php
+if (!getenv('PHP_PEAR_RUNTESTS')) {
+    echo 'skip';
+}
+?>
+--FILE--
+<?php
+$temp_path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'testinstallertemp';
+if (!is_dir($temp_path)) {
+    mkdir($temp_path);
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'php')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'php');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'data')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'data');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'doc')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'doc');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'test')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'test');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'ext')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'ext');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'script')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'script');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'tmp')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'tmp');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'bin')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'bin');
+}
+// make the fake configuration - we'll use one of these and it should work
+$config = serialize(array('master_server' => 'pear.php.net',
+    'default_channel' => 'pear',
+    'php_dir' => $temp_path . DIRECTORY_SEPARATOR . 'php',
+    'ext_dir' => $temp_path . DIRECTORY_SEPARATOR . 'ext',
+    'data_dir' => $temp_path . DIRECTORY_SEPARATOR . 'data',
+    'doc_dir' => $temp_path . DIRECTORY_SEPARATOR . 'doc',
+    'test_dir' => $temp_path . DIRECTORY_SEPARATOR . 'tests',
+    'bin_dir' => $temp_path . DIRECTORY_SEPARATOR . 'bin',
+    '__channels' =>
+    array(
+        'test' => array(
+            'php_dir' => $temp_path . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . 'test',
+            'ext_dir' => $temp_path . DIRECTORY_SEPARATOR . 'ext' . DIRECTORY_SEPARATOR . 'test',
+            'data_dir' => $temp_path . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'test',
+            'doc_dir' => $temp_path . DIRECTORY_SEPARATOR . 'doc' . DIRECTORY_SEPARATOR . 'test',
+            'test_dir' => $temp_path . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'tests',
+            'bin_dir' => $temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test',
+        ),
+    )));
+touch($temp_path . DIRECTORY_SEPARATOR . 'pear.conf');
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'pear.conf', 'w');
+fwrite($fp, $config);
+fclose($fp);
+touch($temp_path . DIRECTORY_SEPARATOR . 'pear.ini');
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'pear.ini', 'w');
+fwrite($fp, $config);
+fclose($fp);
+
+putenv('PHP_PEAR_SYSCONF_DIR='.$temp_path);
+$home = getenv('HOME');
+if (!empty($home)) {
+    // for PEAR_Config initialization
+    putenv('HOME="'.$temp_path);
+}
+require_once 'PEAR/Config.php';
+$config = &PEAR_Config::singleton($temp_path . DIRECTORY_SEPARATOR . 'pear.ini');
+require_once 'PEAR/Registry.php';
+$reg = &new PEAR_Registry($config->get('php_dir', null, 'pear'));
+require_once 'PEAR/ChannelFile.php';
+$chan = new PEAR_ChannelFile;
+$chan->setName('test');
+$chan->setServer('test');
+$chan->setSummary('test');
+$reg->addChannel($chan);
+require_once "PEAR/Installer.php";
+
+// no UI is needed for these tests
+$ui = false;
+$installer = new PEAR_Installer($ui);
+$curdir = getcwd();
+chdir(dirname(__FILE__));
+
+echo "test _installFile():\n";
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'installer2.phpt.testfile.php', 'w');
+fwrite($fp, 'a');
+fclose($fp);
+// pretend we just parsed a package.xml
+$installer->pkginfo = array('package' => 'Foo', 'channel' => 'test');
+
+echo "install as role=\"php\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'php'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file php/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . 'test' .
+    DIRECTORY_SEPARATOR . 
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install as role=\"ext\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'ext'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file ext/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'ext' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install as role=\"data\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'data'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file data/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    'Foo' . DIRECTORY_SEPARATOR . '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install as role=\"doc\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'doc'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file doc/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'doc' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    'Foo' . DIRECTORY_SEPARATOR . '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install as role=\"test\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'test'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file test/tests/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'tests'
+    . DIRECTORY_SEPARATOR .
+    'Foo' . DIRECTORY_SEPARATOR . '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install as role=\"script\":\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file bin/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+$installer->rollbackFileTransaction();
+
+echo "install as invalid role=\"klingon\":\n";
+$err = $installer->_installFile('installer2.phpt.testfile.php', array('role' => 'klingon'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array());
+echo 'returned PEAR_Error: ' . (get_class($err) == 'pear_error' ? "yes\n" : "no\n");
+if (is_object($err)) {
+    echo 'message: ' . $err->getMessage() . "\n\n";
+}
+echo 'file bin/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "install non-existent file:\n";
+$err = $installer->_installFile('....php', array('role' => 'php'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array());
+echo 'returned PEAR_Error: ' . (get_class($err) == 'pear_error' ? "yes\n" : "no\n");
+if (is_object($err)) {
+    echo 'message: ' . $err->getMessage() . "\n";
+}
+echo 'file php/test/.tmp....php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmp....php') ? "yes\n" : "no\n");
+
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'installer2.phpt.testfile.php', 'w');
+fwrite($fp, '@TEST@ stuff');
+fclose($fp);
+
+echo "\ntest valid md5sum:\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script', 'md5sum' => md5('@TEST@ stuff')),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo 'file bin/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+$installer->rollbackFileTransaction();
+
+echo "test invalid md5sum:\n";
+$err = $installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script', 'md5sum' => md5('oops stuff')),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array());
+echo 'returned PEAR_Error: ' . (get_class($err) == 'pear_error' ? "yes\n" : "no\n");
+if (is_object($err)) {
+    echo 'message: ' . ($err->getMessage() == 'bad md5sum for file ' . $temp_path . DIRECTORY_SEPARATOR . 'bin' .
+    DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR . 'installer2.phpt.testfile.php' ? 'match' : 'no match') . "\n";
+}
+echo 'file bin/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+echo "test invalid md5sum with --force:\n";
+ob_start();
+$err = $installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script', 'md5sum' => md5('oops stuff')),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array('force' => true));
+$warning = ob_get_contents();
+ob_end_clean();
+echo 'warning : ';
+echo ($warning == 'warning : bad md5sum for file ' . $temp_path . DIRECTORY_SEPARATOR . 'bin' .
+    DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR . "installer2.phpt.testfile.php\n" ? "match\n" : "no match\n");
+echo 'returned PEAR_Error: ' . (get_class($err) == 'pear_error' ? "yes\n" : "no\n");
+if (is_object($err)) {
+    echo 'message: ' . ($err->getMessage() == 'bad md5sum for file ' . $temp_path . DIRECTORY_SEPARATOR . 'bin' .
+    DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR . 'installer2.phpt.testfile.php' ? 'match' : 'no match') . "\n";
+}
+echo 'file bin/test/.tmpinstaller2.phpt.testfile.php exists? => ';
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php') ? "yes\n" : "no\n");
+
+define('PEARINSTALLERTEST2_FAKE_FOO_CONST', 'good');
+echo "\ntest replacements:\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'php-const', 'from' => '@TEST@', 'to' => 'PEARINSTALLERTEST2_FAKE_FOO_CONST'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo "==>test php-const replacement: equals 'good stuff'? => ";
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+$installer->rollbackFileTransaction();
+
+echo "==>test invalid php-const replacement:\n";
+$err = $installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'php-const', 'from' => '@TEST@', 'to' => '%PEARINSTALLERTEST2_FAKE_FOO_CONST'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array());
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+
+$installer->rollbackFileTransaction();
+
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'pear-config', 'from' => '@TEST@', 'to' => 'master_server'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo "==>test pear-config replacement: equals 'test stuff'? => ";
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+$installer->rollbackFileTransaction();
+
+echo "==>test invalid pear-config replacement\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'pear-config', 'from' => '@TEST@', 'to' => 'blahblahblah'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+$installer->rollbackFileTransaction();
+
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'package-info', 'from' => '@TEST@', 'to' => 'package'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo "==>test package-info replacement: equals 'Foo stuff'? => ";
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+$installer->rollbackFileTransaction();
+
+echo "==>test invalid package-info replacement:\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'replacements' => array(array('type' => 'package-info', 'from' => '@TEST@', 'to' => 'gronk'))),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'))
+{
+    $a = implode(file($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpinstaller2.phpt.testfile.php'), '');
+    echo "$a\n";
+} else {
+    echo "no! file installation failed\n";
+}
+$installer->rollbackFileTransaction();
+
+echo "\ntest install-as:\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'install-as' => 'foobar.php'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo "==>test install as 'foobar.php'.  file exists? ";
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    '.tmpfoobar.php'))
+{
+    echo "yes\n";
+} else {
+    echo "no\n";
+}
+$installer->rollbackFileTransaction();
+
+echo "\ntest baseinstalldir:\n";
+var_dump($installer->_installFile('installer2.phpt.testfile.php', array('role' => 'script',
+    'baseinstalldir' => 'Foo/Mine'),
+    $temp_path . DIRECTORY_SEPARATOR . 'tmp', array()));
+echo "==>test baseinstalldir = 'Foo/Mine'.  file exists? ";
+if (file_exists($temp_path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'test'
+    . DIRECTORY_SEPARATOR .
+    'Foo' . DIRECTORY_SEPARATOR . 'Mine' . DIRECTORY_SEPARATOR . '.tmpinstaller2.phpt.testfile.php'))
+{
+    echo "yes\n";
+} else {
+    echo "no\n";
+}
+$installer->rollbackFileTransaction();
+
+//cleanup
+chdir($curdir);
+cleanall($temp_path);
+function cleanall($dir)
+{
+    $dp = opendir($dir);
+    while ($ent = readdir($dp)) {
+        if ($ent == '.' || $ent == '..') {
+            continue;
+        }
+        if (is_dir($dir . DIRECTORY_SEPARATOR . $ent)) {
+            cleanall($dir . DIRECTORY_SEPARATOR . $ent);
+        } else {
+            unlink($dir . DIRECTORY_SEPARATOR . $ent);
+        }
+    }
+    closedir($dp);
+    rmdir($dir);
+}
+?>
+--GET--
+--POST--
+--EXPECT--
+test _installFile():
+install as role="php":
+int(1)
+file php/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as role="ext":
+int(1)
+file ext/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as role="data":
+int(1)
+file data/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as role="doc":
+int(1)
+file doc/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as role="test":
+int(1)
+file test/tests/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as role="script":
+int(1)
+file bin/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+install as invalid role="klingon":
+returned PEAR_Error: yes
+message: Invalid role `klingon' for file installer2.phpt.testfile.php
+
+file bin/test/.tmpinstaller2.phpt.testfile.php exists? => no
+install non-existent file:
+returned PEAR_Error: yes
+message: file does not exist
+file php/test/.tmp....php exists? => no
+
+test valid md5sum:
+int(1)
+file bin/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+test invalid md5sum:
+returned PEAR_Error: yes
+message: match
+file bin/test/.tmpinstaller2.phpt.testfile.php exists? => no
+test invalid md5sum with --force:
+warning : match
+returned PEAR_Error: no
+file bin/test/.tmpinstaller2.phpt.testfile.php exists? => yes
+
+test replacements:
+int(1)
+==>test php-const replacement: equals 'good stuff'? => good stuff
+==>test invalid php-const replacement:
+invalid php-const replacement: %PEARINSTALLERTEST2_FAKE_FOO_CONST
+@TEST@ stuff
+int(1)
+==>test pear-config replacement: equals 'test stuff'? => test stuff
+==>test invalid pear-config replacement
+invalid pear-config replacement: blahblahblah
+int(1)
+@TEST@ stuff
+int(1)
+==>test package-info replacement: equals 'Foo stuff'? => Foo stuff
+==>test invalid package-info replacement:
+invalid package-info replacement: gronk
+int(1)
+@TEST@ stuff
+
+test install-as:
+int(1)
+==>test install as 'foobar.php'.  file exists? yes
+
+test baseinstalldir:
+int(1)
+==>test baseinstalldir = 'Foo/Mine'.  file exists? yes
+
diff --git a/pear/tests/pear_installer_install_channels.phpt b/pear/tests/pear_installer_install_channels.phpt
new file mode 100644 (file)
index 0000000..4680f3f
--- /dev/null
@@ -0,0 +1,259 @@
+--TEST--
+PEAR_Installer test #4: PEAR_Installer::install() with channels
+--SKIPIF--
+<?php
+if (!getenv('PHP_PEAR_RUNTESTS')) {
+    echo 'skip';
+}
+?>
+--FILE--
+<?php
+$temp_path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'testinstallertemp';
+if (!is_dir($temp_path)) {
+    mkdir($temp_path);
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'php')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'php');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'data')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'data');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'doc')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'doc');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'test')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'test');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'ext')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'ext');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'script')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'script');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'tmp')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'tmp');
+}
+if (!is_dir($temp_path . DIRECTORY_SEPARATOR . 'bin')) {
+    mkdir($temp_path . DIRECTORY_SEPARATOR . 'bin');
+}
+// make the fake configuration - we'll use one of these and it should work
+$config = serialize(array('master_server' => 'pear.php.net',
+    'php_dir' => $temp_path . DIRECTORY_SEPARATOR . 'php',
+    'ext_dir' => $temp_path . DIRECTORY_SEPARATOR . 'ext',
+    'data_dir' => $temp_path . DIRECTORY_SEPARATOR . 'data',
+    'doc_dir' => $temp_path . DIRECTORY_SEPARATOR . 'doc',
+    'test_dir' => $temp_path . DIRECTORY_SEPARATOR . 'test',
+    'bin_dir' => $temp_path . DIRECTORY_SEPARATOR . 'bin',));
+touch($temp_path . DIRECTORY_SEPARATOR . 'pear.conf');
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'pear.conf', 'w');
+fwrite($fp, $config);
+fclose($fp);
+touch($temp_path . DIRECTORY_SEPARATOR . 'pear.ini');
+$fp = fopen($temp_path . DIRECTORY_SEPARATOR . 'pear.ini', 'w');
+fwrite($fp, $config);
+fclose($fp);
+
+putenv('PHP_PEAR_SYSCONF_DIR='.$temp_path);
+$home = getenv('HOME');
+if (!empty($home)) {
+    // for PEAR_Config initialization
+    putenv('HOME="'.$temp_path);
+}
+require_once "PEAR/Installer.php";
+
+// no UI is needed for these tests
+$ui = false;
+$installer = new PEAR_Installer($ui);
+$curdir = getcwd();
+chdir(dirname(__FILE__));
+
+PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'catchit');
+
+$error_to_catch = false;
+function catchit($err)
+{
+    global $error_to_catch;
+    if ($error_to_catch) {
+        if ($err->getMessage() == $error_to_catch) {
+            $error_to_catch = false;
+            echo "Caught expected error\n";
+            return;
+        }
+    }
+    echo "Caught error: " . $err->getMessage() . "\n";
+}
+
+echo "Test package.xml direct install:\n";
+$installer->install(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'package.xml');
+$reg = &new PEAR_Registry($temp_path . DIRECTORY_SEPARATOR . 'php');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+echo "After uninstall:\n";
+$installer->uninstall('pkg6');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+echo "goompness exists? ";
+echo (is_dir($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'))
+    ? "yes\n" : "no\n";
+
+echo "Test .tgz install:\n";
+$installer->install(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'pkg6-1.1.tgz');
+$reg = &new PEAR_Registry($temp_path . DIRECTORY_SEPARATOR . 'php');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+echo "After uninstall:\n";
+$installer->uninstall('pkg6');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+echo "goompness exists? ";
+echo (is_dir($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'))
+    ? "yes\n" : "no\n";
+
+echo "Test invalid .tgz install:\n";
+$error_to_catch = 'unable to unpack ' . dirname(__FILE__) . DIRECTORY_SEPARATOR .
+    'test-pkg6' . DIRECTORY_SEPARATOR . 'invalidtgz.tgz';
+$installer->install(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'invalidtgz.tgz');
+$reg = &new PEAR_Registry($temp_path . DIRECTORY_SEPARATOR . 'php');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+
+echo "Test missing package.xml in .tgz install:\n";
+$installer->install(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'test-pkg6' . DIRECTORY_SEPARATOR . 'nopackagexml.tgz');
+$reg = &new PEAR_Registry($temp_path . DIRECTORY_SEPARATOR . 'php');
+var_dump($reg->listPackages());
+echo "zoorb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'zoorb.php')) ? "yes\n" : "no\n";
+echo "goompness/Mopreeb.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'Mopreeb.php')) ? "yes\n" : "no\n";
+echo "goompness/oggbrzitzkee.php exists? ";
+echo (file_exists($temp_path . DIRECTORY_SEPARATOR . 'php'
+    . DIRECTORY_SEPARATOR . 'groob' . DIRECTORY_SEPARATOR . 'goompness'
+    . DIRECTORY_SEPARATOR . 'oggbrzitzkee.php')) ? "yes\n" : "no\n";
+
+chdir($curdir);
+cleanall($temp_path);
+
+// ------------------------------------------------------------------------- //
+
+function cleanall($dir)
+{
+    $dp = opendir($dir);
+    while ($ent = readdir($dp)) {
+        if ($ent == '.' || $ent == '..') {
+            continue;
+        }
+        if (is_dir($dir . DIRECTORY_SEPARATOR . $ent)) {
+            cleanall($dir . DIRECTORY_SEPARATOR . $ent);
+        } else {
+            unlink($dir . DIRECTORY_SEPARATOR . $ent);
+        }
+    }
+    closedir($dp);
+    rmdir($dir);
+}
+?>
+--GET--
+--POST--
+--EXPECT--
+Test package.xml direct install:
+array(1) {
+  [0]=>
+  string(4) "pkg6"
+}
+zoorb.php exists? yes
+goompness/Mopreeb.php exists? yes
+goompness/oggbrzitzkee.php exists? yes
+After uninstall:
+array(0) {
+}
+zoorb.php exists? no
+goompness/Mopreeb.php exists? no
+goompness/oggbrzitzkee.php exists? no
+goompness exists? no
+Test .tgz install:
+array(1) {
+  [0]=>
+  string(4) "pkg6"
+}
+zoorb.php exists? yes
+goompness/Mopreeb.php exists? yes
+goompness/oggbrzitzkee.php exists? yes
+After uninstall:
+array(0) {
+}
+zoorb.php exists? no
+goompness/Mopreeb.php exists? no
+goompness/oggbrzitzkee.php exists? no
+goompness exists? no
+Test invalid .tgz install:
+Caught error: Invalid checksum for file "<?xml version="1.0" encoding="ISO-8859-1" ?>
+    <!DOCTYPE package SYSTEM "http://pear.php.net/dtd/" : 37649 calculated, 0 expected
+Caught expected error
+array(0) {
+}
+zoorb.php exists? no
+goompness/Mopreeb.php exists? no
+goompness/oggbrzitzkee.php exists? no
+Test missing package.xml in .tgz install:
+warning : you are using an archive with an old format
+Caught error: no package.xml file after extracting the archive
+array(0) {
+}
+zoorb.php exists? no
+goompness/Mopreeb.php exists? no
+goompness/oggbrzitzkee.php exists? no
diff --git a/pear/tests/pear_registry_1.1.phpt b/pear/tests/pear_registry_1.1.phpt
new file mode 100644 (file)
index 0000000..8c81c0e
--- /dev/null
@@ -0,0 +1,290 @@
+--TEST--
+PEAR_Registry v1.1
+--SKIPIF--
+<?php
+if (!getenv('PHP_PEAR_RUNTESTS')) {
+    echo 'skip';
+}
+$statedir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'registry_tester';
+if (file_exists($statedir)) {
+    // don't delete existing directories!
+    echo 'skip';
+}
+include_once 'PEAR/Registry.php';
+$pv = phpversion() . '';
+$av = $pv{0} == '4' ? 'apiversion' : 'apiVersion';
+if (!in_array($av, get_class_methods('PEAR_Registry'))) {
+    echo 'skip';
+}
+if (PEAR_Registry::apiVersion() != '1.1') {
+    echo 'skip';
+}
+?>
+--FILE--
+<?php
+error_reporting(E_ALL);
+include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pear_registry_inc.php';
+include_once "PEAR/Registry.php";
+PEAR::setErrorHandling(PEAR_ERROR_DIE, "%s\n");
+$statedir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'registry_tester';
+cleanall();
+
+$files1 = array(
+    "pkg1-1.php" => array(
+        "role" => "php",
+        ),
+    "pkg1-2.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg1",
+        ),
+    );
+$files1_test = array(
+    "pkg12-1.php" => array(
+        "role" => "php",
+        ),
+    "pkg12-2.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg1",
+        ),
+    );
+$files1_grnok = array(
+    "pkg32-1.php" => array(
+        "role" => "php",
+        ),
+    "pkg32-2.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg1",
+        ),
+    );
+$files2 = array(
+    "pkg2-1.php" => array(
+        "role" => "php",
+        ),
+    "pkg2-2.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg2",
+        ),
+    );
+$files3 = array(
+    "pkg3-1.php" => array(
+        "role" => "php",
+        ),
+    "pkg3-2.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg3",
+        ),
+    );
+$files3_new = array(
+    "pkg3-3.php" => array(
+        "role" => "php",
+        "baseinstalldir" => "pkg3",
+        ),
+    "pkg3-4.php" => array(
+        "role" => "php",
+        ),
+    );
+
+print "creating registry object\n";
+$reg = new PEAR_Registry($statedir);
+dumpall($reg);
+
+$reg->addPackage("pkg1", array("name" => "pkg1", "version" => "1.0", "filelist" => $files1));
+dumpall($reg);
+
+$reg->addPackage("pkg2", array("name" => "pkg2", "version" => "2.0", "filelist" => $files2));
+$reg->addPackage("pkg3", array("name" => "pkg3", "version" => "3.0", "filelist" => $files3));
+dumpall($reg);
+
+$reg->updatePackage("pkg2", array("version" => "2.1"));
+dumpall($reg);
+
+var_dump($reg->deletePackage("pkg2"));
+dumpall($reg);
+
+var_dump($reg->deletePackage("pkg2"));
+dumpall($reg);
+
+$reg->updatePackage("pkg3", array("version" => "3.1b1", "status" => "beta"));
+dumpall($reg);
+
+$testing = $reg->checkFilemap(array_merge($files3, $files2));
+$ok = ($testing == array('pkg3-1.php' => 'pkg3', 'pkg3' . DIRECTORY_SEPARATOR . 'pkg3-2.php' => 'pkg3'));
+echo 'filemap OK? ' . ($ok ? "yes\n" : "no\n");
+if (!$ok) {
+    var_dump($testing);
+}
+
+$reg->updatePackage("pkg3", array("filelist" => $files3_new));
+dumpall($reg);
+
+echo "testing channel registry\n\n";
+
+print "test add channel\n";
+
+require_once 'PEAR/ChannelFile.php';
+$chan = new PEAR_ChannelFile;
+
+$chan->setName('test');
+$chan->setServer('pear.php.net');
+$chan->setSummary('hello');
+$reg->addChannel($chan);
+
+dumpall($reg);
+
+echo "test add bad channel\n";
+$chan = new PEAR_ChannelFile;
+
+$chan->setServer('pear.php.net');
+$chan->setSummary('hello');
+$reg->addChannel($chan);
+
+dumpall($reg);
+
+print "test add good package\n";
+$reg->addPackage('pkg1', array('name' => 'pkg1', 'version' => '1.0', 'filelist' => $files1_test), 'test');
+
+dumpall($reg);
+
+echo "test add package with unknown channel\n";
+
+var_dump($reg->addPackage('pkg2', array('name'=> 'pkg2', 'version' => '1.0', 'filelist' => $files1_grnok), 'grnok'));
+
+dumpall($reg);
+
+echo "test channel exists\n";
+
+var_dump($reg->channelExists('test'));
+var_dump($reg->channelExists('pear'));
+var_dump($reg->channelExists('grnok'));
+
+echo "testing restart with new object\n";
+
+unset($reg);
+
+$reg = &new PEAR_Registry($statedir);
+
+dumpall($reg);
+
+echo "test delete channel with packages\n";
+var_dump($reg->deleteChannel('test'));
+
+dumpall($reg);
+
+echo "test delete channel with no packages\n";
+$reg->deletePackage('pkg1', 'test');
+
+var_dump($reg->deleteChannel('test'));
+
+dumpall($reg);
+
+print "tests done\n";
+?>
+--EXPECT--
+creating registry object
+dumping registry...
+channel pear:
+dump done
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+dump done
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg2: version="2.0" filelist=array(pkg2-1.php[role=php],pkg2-2.php[role=php,baseinstalldir=pkg2])
+pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
+dump done
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg2: version="2.1" filelist=array(pkg2-1.php[role=php],pkg2-2.php[role=php,baseinstalldir=pkg2])
+pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
+dump done
+bool(true)
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
+dump done
+bool(false)
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
+dump done
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3]) status="beta"
+dump done
+filemap OK? yes
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+dump done
+testing channel registry
+
+test add channel
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+dump done
+test add bad channel
+caught ErrorStack error:
+message: Missing channel name
+code: 6
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+dump done
+test add good package
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+pkg1: version="1.0" filelist=array(pkg12-1.php[role=php],pkg12-2.php[role=php,baseinstalldir=pkg1])
+dump done
+test add package with unknown channel
+bool(false)
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+pkg1: version="1.0" filelist=array(pkg12-1.php[role=php],pkg12-2.php[role=php,baseinstalldir=pkg1])
+dump done
+test channel exists
+bool(true)
+bool(true)
+bool(false)
+testing restart with new object
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+pkg1: version="1.0" filelist=array(pkg12-1.php[role=php],pkg12-2.php[role=php,baseinstalldir=pkg1])
+dump done
+test delete channel with packages
+bool(false)
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+channel test:
+pkg1: version="1.0" filelist=array(pkg12-1.php[role=php],pkg12-2.php[role=php,baseinstalldir=pkg1])
+dump done
+test delete channel with no packages
+bool(true)
+dumping registry...
+channel pear:
+pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
+pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
+dump done
+tests done
diff --git a/pear/tests/user3.input b/pear/tests/user3.input
new file mode 100644 (file)
index 0000000..e4ff5f4
--- /dev/null
@@ -0,0 +1 @@
+a:2:{s:7:"verbose";i:60;s:10:"__channels";a:2:{s:5:"test1";a:1:{s:7:"verbose";i:70;}s:5:"test2";a:1:{s:7:"verbose";i:71;}}}
\ No newline at end of file