1
0
mirror of https://github.com/guzzle/guzzle.git synced 2025-02-12 11:30:49 +01:00

Adding tests for Url namespace and starting to sort tests

This commit is contained in:
Michael Dowling 2013-09-19 23:15:56 -07:00
parent 2dc27a9158
commit 02b910d0f2
12 changed files with 747 additions and 247 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php"
<phpunit bootstrap="./vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"

View File

@ -39,6 +39,9 @@ class Client implements ClientInterface
/** @var Collection Parameter object holding configuration data */
private $config;
/** @var UriTemplate */
private static $uriTemplate;
/**
* Clients accept an array of constructor parameters.
*
@ -226,9 +229,15 @@ class Client implements ClientInterface
*/
private function expandTemplate($template, array $variables)
{
return function_exists('uri_template')
? uri_template($template, $variables)
: UriTemplate::getInstance()->expand($template, $variables);
if (function_exists('uri_template')) {
return uri_template($template, $variables);
}
if (!self::$uriTemplate) {
self::$uriTemplate = new UriTemplate();
}
return self::$uriTemplate->expand($template, $variables);
}
/**

View File

@ -80,18 +80,26 @@ class QueryString extends Collection
}
$result = '';
$query = $this->aggregator->aggregate($this->data);
foreach ($query as $key => $values) {
foreach ($this->aggregator->aggregate($this->data) as $key => $values) {
foreach ($values as $value) {
if ($result) {
$result .= '&';
}
if ($this->encoding == self::RFC1738) {
$result .= urlencode($key) . '=' . urlencode($value);
$result .= urlencode($key);
if ($value !== null) {
$result .= '=' . urlencode($value);
}
} elseif ($this->encoding == self::RFC3986) {
$result .= rawurlencode($key) . '=' . rawurldecode($value);
$result .= rawurlencode($key);
if ($value !== null) {
$result .= '=' . rawurlencode($value);
}
} else {
$result .= $key . '=' . $value;
$result .= $key;
if ($value !== null) {
$result .= '=' . $value;
}
}
}
}
@ -119,10 +127,15 @@ class QueryString extends Collection
* @param string|bool $type One of 'RFC1738', 'RFC3986', or false to disable encoding
*
* @return self
* @throws \InvalidArgumentException
*/
public function setEncodingType($type)
{
if ($type === false || $type === self::RFC1738 || $type === self::RFC3986) {
$this->encoding = $type;
} else {
throw new \InvalidArgumentException('Invalid URL encoding type');
}
return $this;
}

View File

@ -11,9 +11,6 @@ class UriTemplate
{
const DEFAULT_PATTERN = '/\{([^\}]+)\}/';
/** @var self */
private static $instance;
/** @var string URI template */
private $template;
@ -39,15 +36,6 @@ class UriTemplate
'%3B', '%3D'
);
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function expand($template, array $variables)
{
if ($this->regex == self::DEFAULT_PATTERN && false === strpos($template, '{')) {

View File

@ -93,7 +93,7 @@ class Url
}
// Add the query string if present
if (isset($parts['query'])) {
if (isset($parts['query']) && strlen($parts['query'])) {
$url .= '?' . $parts['query'];
}
@ -173,7 +173,7 @@ class Url
'host' => $this->host,
'port' => $this->port,
'path' => $this->getPath(),
'query' => (string) $this->query ?: null,
'query' => (string) $this->query,
'fragment' => $this->fragment,
);
}
@ -294,7 +294,7 @@ class Url
return $this;
}
$results = array();
$results = [];
$segments = $this->getPathSegments();
foreach ($segments as $segment) {
if ($segment == '..') {

View File

@ -2,32 +2,13 @@
namespace Guzzle\Tests;
use Guzzle\Common\HasDispatcherInterface;
use Guzzle\Common\Event;
use Guzzle\Http\Message\Response;
use Guzzle\Http\Message\RequestInterface;
use Guzzle\Tests\Http\Message\HeaderComparison;
use Guzzle\Plugin\Mock\MockPlugin;
use Guzzle\Service\Client;
use Guzzle\Service\Builder\ServiceBuilderInterface;
use Guzzle\Service\Builder\ServiceBuilder;
use Guzzle\Tests\Mock\MockObserver;
use Guzzle\Tests\Http\Server;
use RuntimeException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Base testcase class for all Guzzle testcases.
*/
abstract class GuzzleTestCase extends \PHPUnit_Framework_TestCase
{
protected static $mockBasePath;
public static $serviceBuilder;
public static $server;
private $requests = array();
public $mockObserver;
/**
* Get the global server object used throughout the unit tests of Guzzle
*
@ -46,184 +27,4 @@ abstract class GuzzleTestCase extends \PHPUnit_Framework_TestCase
return self::$server;
}
/**
* Set the service builder to use for tests
*
* @param ServiceBuilderInterface $builder Service builder
*/
public static function setServiceBuilder(ServiceBuilderInterface $builder)
{
self::$serviceBuilder = $builder;
}
/**
* Get a service builder object that can be used throughout the service tests
*
* @return ServiceBuilder
*/
public static function getServiceBuilder()
{
if (!self::$serviceBuilder) {
throw new RuntimeException('No service builder has been set via setServiceBuilder()');
}
return self::$serviceBuilder;
}
/**
* Check if an event dispatcher has a subscriber
*
* @param HasDispatcherInterface $dispatcher
* @param EventSubscriberInterface $subscriber
*
* @return bool
*/
protected function hasSubscriber(HasDispatcherInterface $dispatcher, EventSubscriberInterface $subscriber)
{
$class = get_class($subscriber);
$all = array_keys(call_user_func(array($class, 'getSubscribedEvents')));
foreach ($all as $i => $event) {
foreach ($dispatcher->getEventDispatcher()->getListeners($event) as $e) {
if ($e[0] === $subscriber) {
unset($all[$i]);
break;
}
}
}
return count($all) == 0;
}
/**
* Get a wildcard observer for an event dispatcher
*
* @param HasDispatcherInterface $hasEvent
*
* @return MockObserver
*/
public function getWildcardObserver(HasDispatcherInterface $hasDispatcher)
{
$class = get_class($hasDispatcher);
$o = new MockObserver();
$events = call_user_func(array($class, 'getAllEvents'));
foreach ($events as $event) {
$hasDispatcher->getEventDispatcher()->addListener($event, array($o, 'update'));
}
return $o;
}
/**
* Set the mock response base path
*
* @param string $path Path to mock response folder
*
* @return GuzzleTestCase
*/
public static function setMockBasePath($path)
{
self::$mockBasePath = $path;
}
/**
* Mark a request as being mocked
*
* @param RequestInterface $request
*
* @return self
*/
public function addMockedRequest(RequestInterface $request)
{
$this->requests[] = $request;
return $this;
}
/**
* Get all of the mocked requests
*
* @return array
*/
public function getMockedRequests()
{
return $this->requests;
}
/**
* Get a mock response for a client by mock file name
*
* @param string $path Relative path to the mock response file
*
* @return Response
*/
public function getMockResponse($path)
{
return $path instanceof Response
? $path
: MockPlugin::getMockFile(self::$mockBasePath . DIRECTORY_SEPARATOR . $path);
}
/**
* Set a mock response from a mock file on the next client request.
*
* This method assumes that mock response files are located under the
* Command/Mock/ directory of the Service being tested
* (e.g. Unfuddle/Command/Mock/). A mock response is added to the next
* request sent by the client.
*
* @param Client $client Client object to modify
* @param string $paths Path to files within the Mock folder of the service
*
* @return MockPlugin returns the created mock plugin
*/
public function setMockResponse(Client $client, $paths)
{
$this->requests = array();
$that = $this;
$mock = new MockPlugin(null, true);
$client->getEventDispatcher()->removeSubscriber($mock);
$mock->getEventDispatcher()->addListener('mock.request', function(Event $event) use ($that) {
$that->addMockedRequest($event['request']);
});
foreach ((array) $paths as $path) {
$mock->addResponse($this->getMockResponse($path));
}
$client->getEventDispatcher()->addSubscriber($mock);
return $mock;
}
/**
* Compare HTTP headers and use special markup to filter values
* A header prefixed with '!' means it must not exist
* A header prefixed with '_' means it must be ignored
* A header value of '*' means anything after the * will be ignored
*
* @param array $filteredHeaders Array of special headers
* @param array $actualHeaders Array of headers to check against
*
* @return array|bool Returns an array of the differences or FALSE if none
*/
public function compareHeaders($filteredHeaders, $actualHeaders)
{
$comparison = new HeaderComparison();
return $comparison->compare($filteredHeaders, $actualHeaders);
}
/**
* Case insensitive assertContains
*
* @param string $needle Search string
* @param string $haystack Search this
* @param string $message Optional failure message
*/
public function assertContainsIns($needle, $haystack, $message = null)
{
$this->assertContains(strtolower($needle), strtolower($haystack), $message);
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Guzzle\Tests\Url;
use Guzzle\Url\DuplicateAggregator;
/**
* @covers \Guzzle\Url\DuplicateAggregator
* @covers \Guzzle\Url\AbstractAggregator
*/
class DuplicateAggregatorTest extends \Guzzle\Tests\GuzzleTestCase
{
private $encodeData = [
't' => [
'v1' => ['a', '1'],
'v2' => 'b',
'v3' => ['v4' => 'c', 'v5' => 'd']
]
];
public function testEncodes()
{
$agg = new DuplicateAggregator();
$result = $agg->aggregate($this->encodeData);
$this->assertEquals(array(
't[v1]' => ['a', '1'],
't[v2]' => ['b'],
't[v3][v4]' => ['c'],
't[v3][v5]' => ['d'],
), $result);
}
public function testEncodesNoNumericIndices()
{
$agg = new DuplicateAggregator(false);
$result = $agg->aggregate($this->encodeData);
$this->assertEquals(array(
't[v1]' => ['a', '1'],
't[v2]' => ['b'],
't[v3][v4]' => ['c'],
't[v3][v5]' => ['d'],
), $result);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Guzzle\Tests\Url;
use Guzzle\Url\PhpAggregator;
/**
* @covers \Guzzle\Url\PhpAggregator
* @covers \Guzzle\Url\AbstractAggregator
*/
class PhpAggregatorTest extends \Guzzle\Tests\GuzzleTestCase
{
private $encodeData = [
't' => [
'v1' => ['a', '1'],
'v2' => 'b',
'v3' => ['v4' => 'c', 'v5' => 'd']
]
];
public function testEncodes()
{
$agg = new PhpAggregator();
$result = $agg->aggregate($this->encodeData);
$this->assertEquals(array(
't[v1][0]' => ['a'],
't[v1][1]' => ['1'],
't[v2]' => ['b'],
't[v3][v4]' => ['c'],
't[v3][v5]' => ['d'],
), $result);
}
public function testEncodesNoNumericIndices()
{
$agg = new PhpAggregator(false);
$result = $agg->aggregate($this->encodeData);
$this->assertEquals(array(
't[v1][]' => ['a', '1'],
't[v2]' => ['b'],
't[v3][v4]' => ['c'],
't[v3][v5]' => ['d'],
), $result);
}
}

View File

@ -0,0 +1,176 @@
<?php
namespace Guzzle\Tests\Url;
use Guzzle\Url\QueryString;
use Guzzle\Url\DuplicateAggregator;
class QueryStringTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testCanCastToString()
{
$q = new QueryString(['foo' => 'baz', 'bar' => 'bam boozle']);
$this->assertEquals('foo=baz&bar=bam%20boozle', (string) $q);
}
public function testCanDisableUrlEncoding()
{
$q = new QueryString(['bar' => 'bam boozle']);
$q->setEncodingType(false);
$this->assertEquals('bar=bam boozle', (string) $q);
}
public function testCanSpecifyRfc1783UrlEncodingType()
{
$q = new QueryString(['bar abc' => 'bam boozle']);
$q->setEncodingType(QueryString::RFC1738);
$this->assertEquals('bar+abc=bam+boozle', (string) $q);
}
public function testCanSpecifyRfc3986UrlEncodingType()
{
$q = new QueryString(['bar abc' => 'bam boozle', 'ሴ' => 'hi']);
$q->setEncodingType(QueryString::RFC3986);
$this->assertEquals('bar%20abc=bam%20boozle&%E1%88%B4=hi', (string) $q);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesEncodingType()
{
(new QueryString(['bar' => 'bam boozle']))->setEncodingType('foo');
}
public function testAggregatesMultipleValues()
{
$q = new QueryString(['foo' => ['bar', 'baz']]);
$this->assertEquals('foo%5B0%5D=bar&foo%5B1%5D=baz', (string) $q);
}
public function testCanSetAggregator()
{
$agg = $this->getMockBuilder('Guzzle\Url\QueryAggregatorInterface')
->setMethods('aggregate')
->getMockForAbstractClass();
$q = new QueryString(['foo' => ['bar', 'baz']]);
$q->setAggregator($agg);
$agg->expects($this->once())
->method('aggregate')
->will($this->returnValue(['foo' => ['barANDbaz']]));
$this->assertEquals('foo=barANDbaz', (string) $q);
}
public function testAllowsMultipleValuesPerKey()
{
$q = new QueryString();
$q->add('facet', 'size');
$q->add('facet', 'width');
$q->add('facet.field', 'foo');
// Use the duplicate aggregator
$q->setAggregator(new DuplicateAggregator());
$this->assertEquals('facet=size&facet=width&facet.field=foo', (string) $q);
}
public function parseQueryProvider()
{
return array(
// Ensure that multiple query string values are allowed per value
array('q=a&q=b', array('q' => array('a', 'b'))),
// Ensure that PHP array style query string values are parsed
array('q[]=a&q[]=b', array('q' => array('a', 'b'))),
// Ensure that a single PHP array style query string value is parsed into an array
array('q[]=a', array('q' => array('a'))),
// Ensure that decimals are allowed in query strings
array('q.a=a&q.b=b', array(
'q.a' => 'a',
'q.b' => 'b'
)),
// Ensure that query string values are percent decoded
array('q%20a=a%20b', array('q a' => 'a b')),
// Ensure null values can be added
array('q&a', array('q' => null, 'a' => null)),
);
}
/**
* @dataProvider parseQueryProvider
*/
public function testParsesQueryStrings($query, $data)
{
$query = QueryString::fromString($query);
$this->assertEquals($data, $query->toArray());
}
public function testProperlyDealsWithDuplicateQueryStringValues()
{
$query = QueryString::fromString('foo=a&foo=b&?µ=c');
$this->assertEquals(array('a', 'b'), $query->get('foo'));
$this->assertEquals('c', $query->get('?µ'));
}
public function testAllowsNullQueryStringValues()
{
$query = QueryString::fromString('foo');
$this->assertEquals('foo', (string) $query);
$query->set('foo', null);
$this->assertEquals('foo', (string) $query);
}
public function testAllowsFalsyQueryStringValues()
{
$query = QueryString::fromString('0');
$this->assertEquals('0', (string) $query);
$query->set('0', '');
$this->assertSame('0=', (string) $query);
}
public function testConvertsPlusSymbolsToSpaces()
{
$query = QueryString::fromString('var=foo+bar');
$this->assertEquals('foo bar', $query->get('var'));
}
public function testFromStringDoesntMangleZeroes()
{
$query = QueryString::fromString('var=0');
$this->assertSame('0', $query->get('var'));
}
public function testAllowsZeroValues()
{
$query = new QueryString(array(
'foo' => 0,
'baz' => '0',
'bar' => null,
'boo' => false
));
$this->assertEquals('foo=0&baz=0&bar&boo=', (string) $query);
}
public function testFromStringDoesntStripTrailingEquals()
{
$query = QueryString::fromString('data=mF0b3IiLCJUZWFtIERldiJdfX0=');
$this->assertEquals('mF0b3IiLCJUZWFtIERldiJdfX0=', $query->get('data'));
}
public function testGuessesIfDuplicateAggregatorShouldBeUsed()
{
$query = QueryString::fromString('test=a&test=b');
$this->assertEquals('test=a&test=b', (string) $query);
}
public function testGuessesIfDuplicateAggregatorShouldBeUsedAndChecksForPhpStyle()
{
$query = QueryString::fromString('test[]=a&test[]=b');
$this->assertEquals('test%5B0%5D=a&test%5B1%5D=b', (string) $query);
}
public function testCastingToAndCreatingFromStringWithEmptyValuesIsFast()
{
$this->assertEquals('', (string) QueryString::fromString(''));
}
}

View File

@ -0,0 +1,203 @@
<?php
namespace Guzzle\Tests\Parsers\UriTemplate;
use Guzzle\Url\UriTemplate;
use Guzzle\Tests\GuzzleTestCase;
/**
* @covers Guzzle\Url\UriTemplate
*/
class UriTemplateTest extends GuzzleTestCase
{
/**
* @return array
*/
public function templateProvider()
{
$params = array(
'var' => 'value',
'hello' => 'Hello World!',
'empty' => '',
'path' => '/foo/bar',
'x' => '1024',
'y' => '768',
'null' => null,
'list' => array('red', 'green', 'blue'),
'keys' => array(
"semi" => ';',
"dot" => '.',
"comma" => ','
),
'empty_keys' => array(),
);
return array_map(function($t) use ($params) {
$t[] = $params;
return $t;
}, array(
array('foo', 'foo'),
array('{var}', 'value'),
array('{hello}', 'Hello%20World%21'),
array('{+var}', 'value'),
array('{+hello}', 'Hello%20World!'),
array('{+path}/here', '/foo/bar/here'),
array('here?ref={+path}', 'here?ref=/foo/bar'),
array('X{#var}', 'X#value'),
array('X{#hello}', 'X#Hello%20World!'),
array('map?{x,y}', 'map?1024,768'),
array('{x,hello,y}', '1024,Hello%20World%21,768'),
array('{+x,hello,y}', '1024,Hello%20World!,768'),
array('{+path,x}/here', '/foo/bar,1024/here'),
array('{#x,hello,y}', '#1024,Hello%20World!,768'),
array('{#path,x}/here', '#/foo/bar,1024/here'),
array('X{.var}', 'X.value'),
array('X{.x,y}', 'X.1024.768'),
array('{/var}', '/value'),
array('{/var,x}/here', '/value/1024/here'),
array('{;x,y}', ';x=1024;y=768'),
array('{;x,y,empty}', ';x=1024;y=768;empty'),
array('{?x,y}', '?x=1024&y=768'),
array('{?x,y,empty}', '?x=1024&y=768&empty='),
array('?fixed=yes{&x}', '?fixed=yes&x=1024'),
array('{&x,y,empty}', '&x=1024&y=768&empty='),
array('{var:3}', 'val'),
array('{var:30}', 'value'),
array('{list}', 'red,green,blue'),
array('{list*}', 'red,green,blue'),
array('{keys}', 'semi,%3B,dot,.,comma,%2C'),
array('{keys*}', 'semi=%3B,dot=.,comma=%2C'),
array('{+path:6}/here', '/foo/b/here'),
array('{+list}', 'red,green,blue'),
array('{+list*}', 'red,green,blue'),
array('{+keys}', 'semi,;,dot,.,comma,,'),
array('{+keys*}', 'semi=;,dot=.,comma=,'),
array('{#path:6}/here', '#/foo/b/here'),
array('{#list}', '#red,green,blue'),
array('{#list*}', '#red,green,blue'),
array('{#keys}', '#semi,;,dot,.,comma,,'),
array('{#keys*}', '#semi=;,dot=.,comma=,'),
array('X{.var:3}', 'X.val'),
array('X{.list}', 'X.red,green,blue'),
array('X{.list*}', 'X.red.green.blue'),
array('X{.keys}', 'X.semi,%3B,dot,.,comma,%2C'),
array('X{.keys*}', 'X.semi=%3B.dot=..comma=%2C'),
array('{/var:1,var}', '/v/value'),
array('{/list}', '/red,green,blue'),
array('{/list*}', '/red/green/blue'),
array('{/list*,path:4}', '/red/green/blue/%2Ffoo'),
array('{/keys}', '/semi,%3B,dot,.,comma,%2C'),
array('{/keys*}', '/semi=%3B/dot=./comma=%2C'),
array('{;hello:5}', ';hello=Hello'),
array('{;list}', ';list=red,green,blue'),
array('{;list*}', ';list=red;list=green;list=blue'),
array('{;keys}', ';keys=semi,%3B,dot,.,comma,%2C'),
array('{;keys*}', ';semi=%3B;dot=.;comma=%2C'),
array('{?var:3}', '?var=val'),
array('{?list}', '?list=red,green,blue'),
array('{?list*}', '?list=red&list=green&list=blue'),
array('{?keys}', '?keys=semi,%3B,dot,.,comma,%2C'),
array('{?keys*}', '?semi=%3B&dot=.&comma=%2C'),
array('{&var:3}', '&var=val'),
array('{&list}', '&list=red,green,blue'),
array('{&list*}', '&list=red&list=green&list=blue'),
array('{&keys}', '&keys=semi,%3B,dot,.,comma,%2C'),
array('{&keys*}', '&semi=%3B&dot=.&comma=%2C'),
array('{.null}', ''),
array('{.null,var}', '.value'),
array('X{.empty_keys*}', 'X'),
array('X{.empty_keys}', 'X'),
// Test that missing expansions are skipped
array('test{&missing*}', 'test'),
// Test that multiple expansions can be set
array('http://{var}/{var:2}{?keys*}', 'http://value/va?semi=%3B&dot=.&comma=%2C'),
// Test more complex query string stuff
array('http://www.test.com{+path}{?var,keys*}', 'http://www.test.com/foo/bar?var=value&semi=%3B&dot=.&comma=%2C')
));
}
/**
* @dataProvider templateProvider
*/
public function testExpandsUriTemplates($template, $expansion, $params)
{
$uri = new UriTemplate($template);
$this->assertEquals($expansion, $uri->expand($template, $params));
}
public function expressionProvider()
{
return array(
array(
'{+var*}', array(
'operator' => '+',
'values' => array(
array('value' => 'var', 'modifier' => '*')
)
),
),
array(
'{?keys,var,val}', array(
'operator' => '?',
'values' => array(
array('value' => 'keys', 'modifier' => ''),
array('value' => 'var', 'modifier' => ''),
array('value' => 'val', 'modifier' => '')
)
),
),
array(
'{+x,hello,y}', array(
'operator' => '+',
'values' => array(
array('value' => 'x', 'modifier' => ''),
array('value' => 'hello', 'modifier' => ''),
array('value' => 'y', 'modifier' => '')
)
)
)
);
}
/**
* @dataProvider expressionProvider
*/
public function testParsesExpressions($exp, $data)
{
$template = new UriTemplate($exp);
// Access the config object
$class = new \ReflectionClass($template);
$method = $class->getMethod('parseExpression');
$method->setAccessible(true);
$exp = substr($exp, 1, -1);
$this->assertEquals($data, $method->invokeArgs($template, array($exp)));
}
/**
* @ticket https://github.com/guzzle/guzzle/issues/90
*/
public function testAllowsNestedArrayExpansion()
{
$template = new UriTemplate();
$result = $template->expand('http://example.com{+path}{/segments}{?query,data*,foo*}', array(
'path' => '/foo/bar',
'segments' => array('one', 'two'),
'query' => 'test',
'data' => array(
'more' => array('fun', 'ice cream')
),
'foo' => array(
'baz' => array(
'bar' => 'fizz',
'test' => 'buzz'
),
'bam' => 'boo'
)
));
$this->assertEquals('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result);
}
}

View File

@ -0,0 +1,244 @@
<?php
namespace Guzzle\Tests\Http;
use Guzzle\Url\QueryString;
use Guzzle\Url\Url;
/**
* @covers Guzzle\Url\Url
*/
class UrlTest extends \Guzzle\Tests\GuzzleTestCase
{
public function testEmptyUrl()
{
$url = Url::fromString('');
$this->assertEquals('', (string) $url);
}
public function testPortIsDeterminedFromScheme()
{
$this->assertEquals(80, Url::fromString('http://www.test.com/')->getPort());
$this->assertEquals(443, Url::fromString('https://www.test.com/')->getPort());
$this->assertEquals(null, Url::fromString('ftp://www.test.com/')->getPort());
$this->assertEquals(8192, Url::fromString('http://www.test.com:8192/')->getPort());
}
public function testCloneCreatesNewInternalObjects()
{
$u1 = Url::fromString('http://www.test.com/');
$u2 = clone $u1;
$this->assertNotSame($u1->getQuery(), $u2->getQuery());
}
public function testValidatesUrlPartsInFactory()
{
$url = Url::fromString('/index.php');
$this->assertEquals('/index.php', (string) $url);
$this->assertFalse($url->isAbsolute());
$url = 'http://michael:test@test.com:80/path/123?q=abc#test';
$u = Url::fromString($url);
$this->assertEquals('http://michael:test@test.com/path/123?q=abc#test', (string) $u);
$this->assertTrue($u->isAbsolute());
}
public function testAllowsFalsyUrlParts()
{
$url = Url::fromString('http://0:50/0?0#0');
$this->assertSame('0', $url->getHost());
$this->assertEquals(50, $url->getPort());
$this->assertSame('/0', $url->getPath());
$this->assertEquals('0', (string) $url->getQuery());
$this->assertSame('0', $url->getFragment());
$this->assertEquals('http://0:50/0?0#0', (string) $url);
$url = Url::fromString('');
$this->assertSame('', (string) $url);
$url = Url::fromString('0');
$this->assertSame('0', (string) $url);
}
public function testBuildsRelativeUrlsWithFalsyParts()
{
$url = Url::buildUrl(array(
'host' => '0',
'path' => '0',
));
$this->assertSame('//0/0', $url);
$url = Url::buildUrl(array(
'path' => '0',
));
$this->assertSame('0', $url);
}
public function testUrlStoresParts()
{
$url = Url::fromString('http://test:pass@www.test.com:8081/path/path2/?a=1&b=2#fragment');
$this->assertEquals('http', $url->getScheme());
$this->assertEquals('test', $url->getUsername());
$this->assertEquals('pass', $url->getPassword());
$this->assertEquals('www.test.com', $url->getHost());
$this->assertEquals(8081, $url->getPort());
$this->assertEquals('/path/path2/', $url->getPath());
$this->assertEquals('fragment', $url->getFragment());
$this->assertEquals('a=1&b=2', (string) $url->getQuery());
$this->assertEquals(array(
'fragment' => 'fragment',
'host' => 'www.test.com',
'pass' => 'pass',
'path' => '/path/path2/',
'port' => 8081,
'query' => 'a=1&b=2',
'scheme' => 'http',
'user' => 'test'
), $url->getParts());
}
public function testHandlesPathsCorrectly()
{
$url = Url::fromString('http://www.test.com');
$this->assertEquals('', $url->getPath());
$url->setPath('test');
$this->assertEquals('test', $url->getPath());
$url->setPath('/test/123/abc');
$this->assertEquals(array('test', '123', 'abc'), $url->getPathSegments());
$parts = parse_url('http://www.test.com/test');
$parts['path'] = '';
$this->assertEquals('http://www.test.com', Url::buildUrl($parts));
$parts['path'] = 'test';
$this->assertEquals('http://www.test.com/test', Url::buildUrl($parts));
}
public function testAddsQueryStringIfPresent()
{
$this->assertEquals('?foo=bar', Url::buildUrl(array(
'query' => 'foo=bar'
)));
}
public function testAddsToPath()
{
// Does nothing here
$this->assertEquals('http://e.com/base?a=1', (string) Url::fromString('http://e.com/base?a=1')->addPath(false));
$this->assertEquals('http://e.com/base?a=1', (string) Url::fromString('http://e.com/base?a=1')->addPath(''));
$this->assertEquals('http://e.com/base?a=1', (string) Url::fromString('http://e.com/base?a=1')->addPath('/'));
$this->assertEquals('http://e.com/base/relative?a=1', (string) Url::fromString('http://e.com/base?a=1')->addPath('relative'));
$this->assertEquals('http://e.com/base/relative?a=1', (string) Url::fromString('http://e.com/base?a=1')->addPath('/relative'));
}
/**
* URL combination data provider
*
* @return array
*/
public function urlCombineDataProvider()
{
return array(
array('http://www.example.com/', 'http://www.example.com/', 'http://www.example.com/'),
array('http://www.example.com/path', '/absolute', 'http://www.example.com/absolute'),
array('http://www.example.com/path', '/absolute?q=2', 'http://www.example.com/absolute?q=2'),
array('http://www.example.com/path', 'more', 'http://www.example.com/path/more'),
array('http://www.example.com/path', 'more?q=1', 'http://www.example.com/path/more?q=1'),
array('http://www.example.com/', '?q=1', 'http://www.example.com/?q=1'),
array('http://www.example.com/path', 'http://test.com', 'http://test.com'),
array('http://www.example.com:8080/path', 'http://test.com', 'http://test.com'),
array('http://www.example.com:8080/path', '?q=2#abc', 'http://www.example.com:8080/path?q=2#abc'),
array('http://u:a@www.example.com/path', 'test', 'http://u:a@www.example.com/path/test'),
array('http://www.example.com/path', 'http://u:a@www.example.com/', 'http://u:a@www.example.com/'),
array('/path?q=2', 'http://www.test.com/', 'http://www.test.com/path?q=2'),
array('http://api.flickr.com/services/', 'http://www.flickr.com/services/oauth/access_token', 'http://www.flickr.com/services/oauth/access_token'),
array('https://www.example.com/path', '//foo.com/abc', 'https://foo.com/abc'),
);
}
/**
* @dataProvider urlCombineDataProvider
*/
public function testCombinesUrls($a, $b, $c)
{
$this->assertEquals($c, (string) Url::fromString($a)->combine($b));
}
public function testHasGettersAndSetters()
{
$url = Url::fromString('http://www.test.com/');
$this->assertEquals('example.com', $url->setHost('example.com')->getHost());
$this->assertEquals('8080', $url->setPort(8080)->getPort());
$this->assertEquals('/foo/bar', $url->setPath(array('foo', 'bar'))->getPath());
$this->assertEquals('a', $url->setPassword('a')->getPassword());
$this->assertEquals('b', $url->setUsername('b')->getUsername());
$this->assertEquals('abc', $url->setFragment('abc')->getFragment());
$this->assertEquals('https', $url->setScheme('https')->getScheme());
$this->assertEquals('a=123', (string) $url->setQuery('a=123')->getQuery());
$this->assertEquals('https://b:a@example.com:8080/foo/bar?a=123#abc', (string) $url);
$this->assertEquals('b=boo', (string) $url->setQuery(new QueryString(array(
'b' => 'boo'
)))->getQuery());
$this->assertEquals('https://b:a@example.com:8080/foo/bar?b=boo#abc', (string) $url);
}
public function testSetQueryAcceptsArray()
{
$url = Url::fromString('http://www.test.com');
$url->setQuery(array('a' => 'b'));
$this->assertEquals('http://www.test.com?a=b', (string) $url);
}
public function urlProvider()
{
return array(
array('/foo/..', '/'),
array('//foo//..', '/'),
array('/foo/../..', '/'),
array('/foo/../.', '/'),
array('/./foo/..', '/'),
array('/./foo', '/foo'),
array('/./foo/', '/foo/'),
array('/./foo/bar/baz/pho/../..', '/foo/bar'),
array('*', '*'),
array('/foo', '/foo'),
array('/abc/123/../foo/', '/abc/foo/')
);
}
/**
* @dataProvider urlProvider
*/
public function testNormalizesPaths($path, $result)
{
$url = Url::fromString('http://www.example.com');
$url->setPath($path)->normalizePath();
$this->assertEquals($result, $url->getPath());
}
public function testSettingHostWithPortModifiesPort()
{
$url = Url::fromString('http://www.example.com');
$url->setHost('foo:8983');
$this->assertEquals('foo', $url->getHost());
$this->assertEquals(8983, $url->getPort());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesUrlCanBeParsed()
{
Url::fromString('foo:////');
}
public function testConvertsSpecialCharsInPathWhenCastingToString()
{
$url = Url::fromString('http://foo.com/baz bar?a=b');
$url->addPath('?');
$this->assertEquals('http://foo.com/baz%20bar/%3F?a=b', (string) $url);
}
}

View File

@ -1,23 +0,0 @@
<?php
error_reporting(E_ALL | E_STRICT);
// Ensure that composer has installed all dependencies
if (!file_exists(dirname(__DIR__) . '/composer.lock')) {
die("Dependencies must be installed using composer:\n\nphp composer.phar install --dev\n\n"
. "See http://getcomposer.org for help with installing composer\n");
}
require_once 'PHPUnit/TextUI/TestRunner.php';
// Include the phar files if testing against the phars
if (get_cfg_var('guzzle_phar')) {
require get_cfg_var('guzzle_phar');
}
// Include the composer autoloader
$autoloader = require dirname(__DIR__) . '/vendor/autoload.php';
// Add the services file to the default service builder
$servicesFile = __DIR__ . '/Guzzle/Tests/TestData/services/services.json';
Guzzle\Tests\GuzzleTestCase::setServiceBuilder(Guzzle\Service\Builder\ServiceBuilder::factory($servicesFile));