Unverified Commit a42e3479 authored by Andreas Braun's avatar Andreas Braun

Merge branch 'v1.5'

* v1.5:
  PHPLIB-494: Fix validation of options with default values
  PHPLIB-494: Test against null for options with default values
  Simplify generator setup in tests
  PHPLIB-501: Use IteratorIterator to prevent memory leak with generators
parents 384649de 9480f994
...@@ -95,7 +95,7 @@ class Client ...@@ -95,7 +95,7 @@ class Client
{ {
$driverOptions += ['typeMap' => self::$defaultTypeMap]; $driverOptions += ['typeMap' => self::$defaultTypeMap];
if (isset($driverOptions['typeMap']) && ! is_array($driverOptions['typeMap'])) { if (! is_array($driverOptions['typeMap'])) {
throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array'); throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array');
} }
......
...@@ -143,19 +143,19 @@ class Bucket ...@@ -143,19 +143,19 @@ class Bucket
'disableMD5' => false, 'disableMD5' => false,
]; ];
if (isset($options['bucketName']) && ! is_string($options['bucketName'])) { if (! is_string($options['bucketName'])) {
throw InvalidArgumentException::invalidType('"bucketName" option', $options['bucketName'], 'string'); throw InvalidArgumentException::invalidType('"bucketName" option', $options['bucketName'], 'string');
} }
if (isset($options['chunkSizeBytes']) && ! is_integer($options['chunkSizeBytes'])) { if (! is_integer($options['chunkSizeBytes'])) {
throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer'); throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer');
} }
if (isset($options['chunkSizeBytes']) && $options['chunkSizeBytes'] < 1) { if ($options['chunkSizeBytes'] < 1) {
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes'])); throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
} }
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) { if (! is_bool($options['disableMD5'])) {
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
} }
......
...@@ -114,15 +114,15 @@ class WritableStream ...@@ -114,15 +114,15 @@ class WritableStream
throw InvalidArgumentException::invalidType('"aliases" option', $options['aliases'], 'array of strings'); throw InvalidArgumentException::invalidType('"aliases" option', $options['aliases'], 'array of strings');
} }
if (isset($options['chunkSizeBytes']) && ! is_integer($options['chunkSizeBytes'])) { if (! is_integer($options['chunkSizeBytes'])) {
throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer'); throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer');
} }
if (isset($options['chunkSizeBytes']) && $options['chunkSizeBytes'] < 1) { if ($options['chunkSizeBytes'] < 1) {
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes'])); throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
} }
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) { if (! is_bool($options['disableMD5'])) {
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
} }
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
namespace MongoDB\Model; namespace MongoDB\Model;
use Countable; use Countable;
use Generator;
use Iterator; use Iterator;
use IteratorIterator;
use Traversable; use Traversable;
use function count; use function count;
use function current; use function current;
...@@ -41,7 +41,7 @@ class CachingIterator implements Countable, Iterator ...@@ -41,7 +41,7 @@ class CachingIterator implements Countable, Iterator
/** @var array */ /** @var array */
private $items = []; private $items = [];
/** @var Generator */ /** @var IteratorIterator */
private $iterator; private $iterator;
/** @var boolean */ /** @var boolean */
...@@ -61,7 +61,9 @@ class CachingIterator implements Countable, Iterator ...@@ -61,7 +61,9 @@ class CachingIterator implements Countable, Iterator
*/ */
public function __construct(Traversable $traversable) public function __construct(Traversable $traversable)
{ {
$this->iterator = $this->wrapTraversable($traversable); $this->iterator = new IteratorIterator($traversable);
$this->iterator->rewind();
$this->storeCurrentItem(); $this->storeCurrentItem();
} }
...@@ -101,8 +103,12 @@ class CachingIterator implements Countable, Iterator ...@@ -101,8 +103,12 @@ class CachingIterator implements Countable, Iterator
public function next() public function next()
{ {
if (! $this->iteratorExhausted) { if (! $this->iteratorExhausted) {
$this->iteratorAdvanced = true;
$this->iterator->next(); $this->iterator->next();
$this->storeCurrentItem(); $this->storeCurrentItem();
$this->iteratorExhausted = ! $this->iterator->valid();
} }
next($this->items); next($this->items);
...@@ -156,20 +162,4 @@ class CachingIterator implements Countable, Iterator ...@@ -156,20 +162,4 @@ class CachingIterator implements Countable, Iterator
$this->items[$key] = $this->iterator->current(); $this->items[$key] = $this->iterator->current();
} }
/**
* Wraps the Traversable with a Generator.
*
* @param Traversable $traversable
* @return Generator
*/
private function wrapTraversable(Traversable $traversable)
{
foreach ($traversable as $key => $value) {
yield $key => $value;
$this->iteratorAdvanced = true;
}
$this->iteratorExhausted = true;
}
} }
...@@ -178,10 +178,14 @@ class Watch implements Executable, /* @internal */ CommandSubscriber ...@@ -178,10 +178,14 @@ class Watch implements Executable, /* @internal */ CommandSubscriber
'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY), 'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
]; ];
if (isset($options['fullDocument']) && ! is_string($options['fullDocument'])) { if (! is_string($options['fullDocument'])) {
throw InvalidArgumentException::invalidType('"fullDocument" option', $options['fullDocument'], 'string'); throw InvalidArgumentException::invalidType('"fullDocument" option', $options['fullDocument'], 'string');
} }
if (! $options['readPreference'] instanceof ReadPreference) {
throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
}
if (isset($options['resumeAfter']) && ! is_array($options['resumeAfter']) && ! is_object($options['resumeAfter'])) { if (isset($options['resumeAfter']) && ! is_array($options['resumeAfter']) && ! is_object($options['resumeAfter'])) {
throw InvalidArgumentException::invalidType('"resumeAfter" option', $options['resumeAfter'], 'array or object'); throw InvalidArgumentException::invalidType('"resumeAfter" option', $options['resumeAfter'], 'array or object');
} }
......
...@@ -33,7 +33,7 @@ class ClientTest extends TestCase ...@@ -33,7 +33,7 @@ class ClientTest extends TestCase
{ {
$options = []; $options = [];
foreach ($this->getInvalidArrayValues() as $value) { foreach ($this->getInvalidArrayValues(true) as $value) {
$options[][] = ['typeMap' => $value]; $options[][] = ['typeMap' => $value];
} }
......
...@@ -62,15 +62,15 @@ class BucketFunctionalTest extends FunctionalTestCase ...@@ -62,15 +62,15 @@ class BucketFunctionalTest extends FunctionalTestCase
{ {
$options = []; $options = [];
foreach ($this->getInvalidStringValues() as $value) { foreach ($this->getInvalidStringValues(true) as $value) {
$options[][] = ['bucketName' => $value]; $options[][] = ['bucketName' => $value];
} }
foreach ($this->getInvalidIntegerValues() as $value) { foreach ($this->getInvalidIntegerValues(true) as $value) {
$options[][] = ['chunkSizeBytes' => $value]; $options[][] = ['chunkSizeBytes' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['disableMD5' => $value]; $options[][] = ['disableMD5' => $value];
} }
......
...@@ -50,11 +50,11 @@ class WritableStreamFunctionalTest extends FunctionalTestCase ...@@ -50,11 +50,11 @@ class WritableStreamFunctionalTest extends FunctionalTestCase
{ {
$options = []; $options = [];
foreach ($this->getInvalidIntegerValues() as $value) { foreach ($this->getInvalidIntegerValues(true) as $value) {
$options[][] = ['chunkSizeBytes' => $value]; $options[][] = ['chunkSizeBytes' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['disableMD5' => $value]; $options[][] = ['disableMD5' => $value];
} }
......
...@@ -53,7 +53,7 @@ class CachingIteratorTest extends TestCase ...@@ -53,7 +53,7 @@ class CachingIteratorTest extends TestCase
public function testPartialIterationDoesNotExhaust() public function testPartialIterationDoesNotExhaust()
{ {
$traversable = $this->getTraversableThatThrows([1, 2, new Exception()]); $traversable = $this->getTraversable([1, 2, new Exception()]);
$iterator = new CachingIterator($traversable); $iterator = new CachingIterator($traversable);
$expectedKey = 0; $expectedKey = 0;
...@@ -110,13 +110,6 @@ class CachingIteratorTest extends TestCase ...@@ -110,13 +110,6 @@ class CachingIteratorTest extends TestCase
} }
private function getTraversable($items) private function getTraversable($items)
{
foreach ($items as $item) {
yield $item;
}
}
private function getTraversableThatThrows($items)
{ {
foreach ($items as $item) { foreach ($items as $item) {
if ($item instanceof Exception) { if ($item instanceof Exception) {
......
...@@ -27,7 +27,7 @@ class AggregateTest extends TestCase ...@@ -27,7 +27,7 @@ class AggregateTest extends TestCase
{ {
$options = []; $options = [];
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['allowDiskUse' => $value]; $options[][] = ['allowDiskUse' => $value];
} }
...@@ -79,7 +79,7 @@ class AggregateTest extends TestCase ...@@ -79,7 +79,7 @@ class AggregateTest extends TestCase
$options[][] = ['typeMap' => $value]; $options[][] = ['typeMap' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['useCursor' => $value]; $options[][] = ['useCursor' => $value];
} }
......
...@@ -412,7 +412,7 @@ class BulkWriteTest extends TestCase ...@@ -412,7 +412,7 @@ class BulkWriteTest extends TestCase
$options[][] = ['bypassDocumentValidation' => $value]; $options[][] = ['bypassDocumentValidation' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['ordered' => $value]; $options[][] = ['ordered' => $value];
} }
......
...@@ -40,7 +40,7 @@ class FindAndModifyTest extends TestCase ...@@ -40,7 +40,7 @@ class FindAndModifyTest extends TestCase
$options[][] = ['maxTimeMS' => $value]; $options[][] = ['maxTimeMS' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['new' => $value]; $options[][] = ['new' => $value];
} }
...@@ -48,7 +48,7 @@ class FindAndModifyTest extends TestCase ...@@ -48,7 +48,7 @@ class FindAndModifyTest extends TestCase
$options[][] = ['query' => $value]; $options[][] = ['query' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['remove' => $value]; $options[][] = ['remove' => $value];
} }
...@@ -68,7 +68,7 @@ class FindAndModifyTest extends TestCase ...@@ -68,7 +68,7 @@ class FindAndModifyTest extends TestCase
$options[][] = ['update' => $value]; $options[][] = ['update' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['upsert' => $value]; $options[][] = ['upsert' => $value];
} }
......
...@@ -49,7 +49,7 @@ class FindOneAndReplaceTest extends TestCase ...@@ -49,7 +49,7 @@ class FindOneAndReplaceTest extends TestCase
$options[][] = ['projection' => $value]; $options[][] = ['projection' => $value];
} }
foreach ($this->getInvalidIntegerValues() as $value) { foreach ($this->getInvalidIntegerValues(true) as $value) {
$options[][] = ['returnDocument' => $value]; $options[][] = ['returnDocument' => $value];
} }
......
...@@ -49,7 +49,7 @@ class FindOneAndUpdateTest extends TestCase ...@@ -49,7 +49,7 @@ class FindOneAndUpdateTest extends TestCase
$options[][] = ['projection' => $value]; $options[][] = ['projection' => $value];
} }
foreach ($this->getInvalidIntegerValues() as $value) { foreach ($this->getInvalidIntegerValues(true) as $value) {
$options[][] = ['returnDocument' => $value]; $options[][] = ['returnDocument' => $value];
} }
......
...@@ -48,7 +48,7 @@ class InsertManyTest extends TestCase ...@@ -48,7 +48,7 @@ class InsertManyTest extends TestCase
$options[][] = ['bypassDocumentValidation' => $value]; $options[][] = ['bypassDocumentValidation' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['ordered' => $value]; $options[][] = ['ordered' => $value];
} }
......
...@@ -52,7 +52,7 @@ class UpdateTest extends TestCase ...@@ -52,7 +52,7 @@ class UpdateTest extends TestCase
$options[][] = ['collation' => $value]; $options[][] = ['collation' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['multi' => $value]; $options[][] = ['multi' => $value];
} }
...@@ -60,7 +60,7 @@ class UpdateTest extends TestCase ...@@ -60,7 +60,7 @@ class UpdateTest extends TestCase
$options[][] = ['session' => $value]; $options[][] = ['session' => $value];
} }
foreach ($this->getInvalidBooleanValues() as $value) { foreach ($this->getInvalidBooleanValues(true) as $value) {
$options[][] = ['upsert' => $value]; $options[][] = ['upsert' => $value];
} }
......
...@@ -52,7 +52,7 @@ class WatchTest extends FunctionalTestCase ...@@ -52,7 +52,7 @@ class WatchTest extends FunctionalTestCase
$options[][] = ['collation' => $value]; $options[][] = ['collation' => $value];
} }
foreach ($this->getInvalidStringValues() as $value) { foreach ($this->getInvalidStringValues(true) as $value) {
$options[][] = ['fullDocument' => $value]; $options[][] = ['fullDocument' => $value];
} }
...@@ -64,7 +64,7 @@ class WatchTest extends FunctionalTestCase ...@@ -64,7 +64,7 @@ class WatchTest extends FunctionalTestCase
$options[][] = ['readConcern' => $value]; $options[][] = ['readConcern' => $value];
} }
foreach ($this->getInvalidReadPreferenceValues() as $value) { foreach ($this->getInvalidReadPreferenceValues(true) as $value) {
$options[][] = ['readPreference' => $value]; $options[][] = ['readPreference' => $value];
} }
......
...@@ -14,6 +14,7 @@ use ReflectionClass; ...@@ -14,6 +14,7 @@ use ReflectionClass;
use stdClass; use stdClass;
use Traversable; use Traversable;
use function array_map; use function array_map;
use function array_merge;
use function array_values; use function array_values;
use function call_user_func; use function call_user_func;
use function getenv; use function getenv;
...@@ -165,91 +166,109 @@ abstract class TestCase extends BaseTestCase ...@@ -165,91 +166,109 @@ abstract class TestCase extends BaseTestCase
/** /**
* Return a list of invalid array values. * Return a list of invalid array values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidArrayValues() protected function getInvalidArrayValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true, new stdClass()]; return array_merge([123, 3.14, 'foo', true, new stdClass()], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid boolean values. * Return a list of invalid boolean values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidBooleanValues() protected function getInvalidBooleanValues($includeNull = false)
{ {
return [123, 3.14, 'foo', [], new stdClass()]; return array_merge([123, 3.14, 'foo', [], new stdClass()], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid document values. * Return a list of invalid document values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidDocumentValues() protected function getInvalidDocumentValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true]; return array_merge([123, 3.14, 'foo', true], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid integer values. * Return a list of invalid integer values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidIntegerValues() protected function getInvalidIntegerValues($includeNull = false)
{ {
return [3.14, 'foo', true, [], new stdClass()]; return array_merge([3.14, 'foo', true, [], new stdClass()], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid ReadPreference values. * Return a list of invalid ReadPreference values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidReadConcernValues() protected function getInvalidReadConcernValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true, [], new stdClass(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)]; return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid ReadPreference values. * Return a list of invalid ReadPreference values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidReadPreferenceValues() protected function getInvalidReadPreferenceValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new WriteConcern(1)]; return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new WriteConcern(1)], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid Session values. * Return a list of invalid Session values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidSessionValues() protected function getInvalidSessionValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)]; return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid string values. * Return a list of invalid string values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidStringValues() protected function getInvalidStringValues($includeNull = false)
{ {
return [123, 3.14, true, [], new stdClass()]; return array_merge([123, 3.14, true, [], new stdClass()], $includeNull ? [null] : []);
} }
/** /**
* Return a list of invalid WriteConcern values. * Return a list of invalid WriteConcern values.
* *
* @param boolean $includeNull
*
* @return array * @return array
*/ */
protected function getInvalidWriteConcernValues() protected function getInvalidWriteConcernValues($includeNull = false)
{ {
return [123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY)]; return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY)], $includeNull ? [null] : []);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment