diff --git a/.gitignore b/.gitignore index 164311db8..e997c8587 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ build phpunit.xml composer.phar composer.lock -vendor \ No newline at end of file +vendor diff --git a/CHANGELOG.md b/CHANGELOG.md index c73a8a6a2..83c7a6364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # CHANGELOG +## 3.4.0 - 2015-06-14 + +- bugfix: only check type for added documents to add query if provided as an array +- improvement: added support for calling empty() and isset() on result document properties +- improvement: added composer test script +- bugfix: curl file upload handling +- improvement: added 'contributing' file +- improvement: docblock fixes in grouping component facets +- added: facet interval support +- added: ZF2 http adapter +- added: stats for pivot facet +- bugfix: spellcheck 'collations' and 'correctlyspelled' updated to support Solr 5 format +- bugfix: curl adapter now uses Solr 5 compatible headers for a GET request +- improvement: lots of code style fixes, using the SF2 code style + + ## 3.3.0 - 2014-11-16 - improvement: fixes in build.xml (use phpunit in vendor directory) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..250c56bcc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing to Solarium + +So you consider contributing to Solarium? That’s great! +Here are some pointers to hopefully get a good result. + +If you are uncertain about any part or need help please feel free to ask for help. + +## Bug reports + +* Bugs are intended for problems in the code or missing / faulty documentation. Not for issues with your own environment, questions in how to use feature X etcetera. +* Include info about your environment: the version of Solarium you are using, PHP version, Solr version +* If you get a specific error, include as much info as possible. The PHP exception, a Solr error log line, etcetera. +* When something doesn't work as expected for you, also describe the behaviour you expect. +* Do a quick search to check if the issue has already been reported +* Describe your issue well, especially the title. Instead of ‘Select query exception’ use ‘Using a dash in a filterquery tag causes an exception’. +* Provide steps to reproduce the issue. A unittest is ideal, but a description of manual steps is also very helpful. + +## Pull requests + +* Your pull requests should target the develop branch, not master. Nothing will be directly merged into master! +* A pull request should be mergeable (fast-forward) if not, you will be asked to update it. +* Ideally any change should include updated or new unittests to cover the changes. You can submit a PR without tests, but it will take longer to merge as someone else will need to fix the test coverage. +* Solarium follows the Symfony2 code standards: http://symfony.com/doc/current/contributing/code/standards.html +* Each PR will be checked by the CI environment automatically. Ofcourse anything other than a 'green' status needs to be fixed before a PR can be merged. diff --git a/README.md b/README.md index f2b177361..1c8672dc2 100644 --- a/README.md +++ b/README.md @@ -49,5 +49,3 @@ http://wiki.solarium-project.org/index.php/V3:Installation#Getting_Solarium * Develop branch [![Coverage Status](https://coveralls.io/repos/solariumphp/solarium/badge.png?branch=develop)](https://coveralls.io/r/solariumphp/solarium?branch=develop) * Master branch [![Develop build status](https://secure.travis-ci.org/solariumphp/solarium.png?branch=master)](http://travis-ci.org/solariumphp/solarium) * Master branch [![Coverage Status](https://coveralls.io/repos/solariumphp/solarium/badge.png?branch=master)](https://coveralls.io/r/solariumphp/solarium?branch=master) - - diff --git a/examples/2.1.5.1.6-facet-interval.php b/examples/2.1.5.1.6-facet-interval.php new file mode 100644 index 000000000..012b24ba2 --- /dev/null +++ b/examples/2.1.5.1.6-facet-interval.php @@ -0,0 +1,43 @@ +createSelect(); + +// get the facetset component +$facetSet = $query->getFacetSet(); + +// create a facet field instance and set options +$facet = $facetSet->createFacetInterval('price'); +$facet->setField('price'); +$facet->setSet(array('1-9' => '[1,10)', '10-49' => '[10,50)', '49>' => '[50,*)')); + +// this executes the query and returns the result +$resultset = $client->select($query); + +// display the total number of documents found by solr +echo 'NumFound: '.$resultset->getNumFound(); + +// display facet counts +echo '
Facet intervals:
'; +$facet = $resultset->getFacetSet()->getFacet('price'); +foreach ($facet as $range => $count) { + echo $range . ' to ' . ($range + 100) . ' [' . $count . ']
'; +} + +// show documents using the resultset iterator +foreach ($resultset as $document) { + + echo '
'; + echo ''; + echo ''; + echo ''; + echo '
id' . $document->id . '
name' . $document->name . '
price' . $document->price . '
'; +} + +htmlFooter(); diff --git a/examples/index.html b/examples/index.html index 83927c9fd..a802d4e25 100644 --- a/examples/index.html +++ b/examples/index.html @@ -42,6 +42,7 @@

Solarium examples

  • 2.1.5.1.3 Facet multiquery
  • 2.1.5.1.4 Facet range
  • 2.1.5.1.5 Facet pivot
  • +
  • 2.1.5.1.6 Facet interval
  • 2.1.5.2 MoreLikeThis
  • 2.1.5.3 Highlighting
  • diff --git a/library/Solarium/Client.php b/library/Solarium/Client.php index 5ecc6fbf8..67c1441b9 100644 --- a/library/Solarium/Client.php +++ b/library/Solarium/Client.php @@ -70,7 +70,7 @@ class Client extends CoreClient * * @var string */ - const VERSION = '3.2.0'; + const VERSION = '3.4.0'; /** * Check for an exact version diff --git a/library/Solarium/Core/Client/Adapter/Curl.php b/library/Solarium/Core/Client/Adapter/Curl.php index a155cc4c8..a1d8dec0a 100644 --- a/library/Solarium/Core/Client/Adapter/Curl.php +++ b/library/Solarium/Core/Client/Adapter/Curl.php @@ -184,7 +184,7 @@ public function createHandle($request, $endpoint) if ($request->getFileUpload()) { if (version_compare(PHP_VERSION, '5.5.0') >= 0) { $curlFile = curl_file_create($request->getFileUpload()); - curl_setopt($handler, CURLOPT_POSTFIELDS, array('content', $curlFile)); + curl_setopt($handler, CURLOPT_POSTFIELDS, array('content' => $curlFile)); } else { curl_setopt($handler, CURLOPT_POSTFIELDS, array('content' => '@'.$request->getFileUpload())); } diff --git a/library/Solarium/Core/Client/Adapter/Zend2Http.php b/library/Solarium/Core/Client/Adapter/Zend2Http.php new file mode 100644 index 000000000..19693dc36 --- /dev/null +++ b/library/Solarium/Core/Client/Adapter/Zend2Http.php @@ -0,0 +1,257 @@ + + * @copyright Copyright 2012 Alexander Brausewetter + * @copyright Copyright 2014 Marin Purgar + * @license http://github.com/basdenooijer/solarium/raw/master/COPYING + * @link http://www.solarium-project.org/ + */ + +/** + * @namespace + */ +namespace Solarium\Core\Client\Adapter; + +use Solarium\Core\Configurable; +use Solarium\Core\Client; +use Solarium\Core\Client\Request; +use Solarium\Core\Client\Response; +use Solarium\Core\Client\Endpoint; +use Solarium\Exception\HttpException; +use Solarium\Exception\OutOfBoundsException; + +/** + * Adapter that uses a ZF2 Zend\Http\Client + * + * The Zend Framework HTTP client has many great features and has lots of + * configuration options. For more info see the manual at + * {@link http://framework.zend.com/manual/en/zend.http.html} + * + * To use this adapter you need to have the Zend Framework available (autoloading) + */ +class Zend2Http extends Configurable implements AdapterInterface +{ + /** + * Zend Http instance for communication with Solr + * + * @var \Zend\Http\Client + */ + protected $zendHttp; + + /** + * @var int + */ + protected $timeout; + + /** + * Set options + * + * Overrides any existing values. + * + * If the options array has an 'options' entry it is forwarded to the + * Zend\Http\Client. See the Zend\Http\Client docs for the many config + * options available. + * + * The $options param should be an array or an object that has a toArray + * method, like Zend_Config + * + * @param array|object $options + * @param boolean $overwrite + * @return self Provides fluent interface + */ + public function setOptions($options, $overwrite = false) + { + parent::setOptions($options, $overwrite); + + // forward options to zendHttp instance + if (null !== $this->zendHttp) { + + // forward timeout setting + $adapterOptions = array(); + + // forward adapter options if available + if (isset($this->options['options'])) { + $adapterOptions = array_merge($adapterOptions, $this->options['options']); + } + + $this->zendHttp->setOptions($adapterOptions); + } + + return $this; + } + + /** + * Set the Zend\Http\Client instance + * + * This method is optional, if you don't set a client it will be created + * upon first use, using default and/or custom options (the most common use + * case) + * + * @param \Zend\Http\Client $zendHttp + * @return self Provides fluent interface + */ + public function setZendHttp($zendHttp) + { + $this->zendHttp = $zendHttp; + + return $this; + } + + /** + * Get the Zend\Http\Client instance + * + * If no instance is available yet it will be created automatically based on + * options. + * + * You can use this method to get a reference to the client instance to set + * options, get the last response and use many other features offered by the + * Zend\Http\Client API. + * + * @return \Zend\Http\Client + */ + public function getZendHttp() + { + if (null == $this->zendHttp) { + $options = array(); + + // forward zendhttp options + if (isset($this->options['options'])) { + $options = array_merge( + $options, + $this->options['options'] + ); + } + + $this->zendHttp = new \Zend\Http\Client(null, $options); + } + + return $this->zendHttp; + } + + /** + * Execute a Solr request using the Zend\Http\Client instance + * + * @throws HttpException + * @throws OutOfBoundsException + * @param Request $request + * @param Endpoint $endpoint + * @return Response + */ + public function execute($request, $endpoint) + { + $client = $this->getZendHttp(); + $client->resetParameters(); + + switch ($request->getMethod()) { + case Request::METHOD_GET: + $client->setMethod('GET'); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_POST: + $client->setMethod('POST'); + if ($request->getFileUpload()) { + $this->prepareFileUpload($client, $request); + } else { + $client->setParameterGet($request->getParams()); + $client->setRawBody($request->getRawData()); + $request->addHeader('Content-Type: text/xml; charset=UTF-8'); + } + break; + case Request::METHOD_HEAD: + $client->setMethod('HEAD'); + $client->setParameterGet($request->getParams()); + break; + default: + throw new OutOfBoundsException('Unsupported method: ' . $request->getMethod()); + break; + } + + $client->setUri($endpoint->getBaseUri() . $request->getHandler()); + $client->setHeaders($request->getHeaders()); + $this->timeout = $endpoint->getTimeout(); + + $response = $client->send(); + + return $this->prepareResponse( + $request, + $response + ); + } + + /** + * Prepare a solarium response from the given request and client + * response + * + * @throws HttpException + * @param Request $request + * @param \Zend\Http\Response $response + * @return Response + */ + protected function prepareResponse($request, $response) + { + if ($response->isClientError()) { + throw new HttpException( + $response->getReasonPhrase(), + $response->getStatusCode() + ); + } + + if ($request->getMethod() == Request::METHOD_HEAD) { + $data = ''; + } else { + $data = $response->getBody(); + } + + // this is used because in ZF2 status line isn't in the headers anymore + $headers = array($response->renderStatusLine()); + + return new Response($data, $headers); + } + + /** + * Prepare the client to send the file and params in request + * + * @param \Zend\Http\Client $client + * @param Request $request + * @return void + */ + protected function prepareFileUpload($client, $request) + { + $filename = $request->getFileUpload(); + $client->setFileUpload( + 'content', + 'content', + file_get_contents($filename), + 'application/octet-stream; charset=binary' + ); + } +} diff --git a/library/Solarium/Plugin/MinimumScoreFilter/Document.php b/library/Solarium/Plugin/MinimumScoreFilter/Document.php index f9e172952..c3f1a6683 100644 --- a/library/Solarium/Plugin/MinimumScoreFilter/Document.php +++ b/library/Solarium/Plugin/MinimumScoreFilter/Document.php @@ -104,6 +104,17 @@ public function __get($name) { return $this->document->__get($name); } + /** + * Forward isset call to the original document + * + * @param string $name + * @return boolean + */ + public function __isset($name) + { + return $this->document->__isset($name); + } + /** * IteratorAggregate implementation * diff --git a/library/Solarium/QueryType/Select/Query/Component/Facet/Interval.php b/library/Solarium/QueryType/Select/Query/Component/Facet/Interval.php new file mode 100644 index 000000000..3b2ef3c92 --- /dev/null +++ b/library/Solarium/QueryType/Select/Query/Component/Facet/Interval.php @@ -0,0 +1,137 @@ + + * @license http://github.com/basdenooijer/solarium/raw/master/COPYING + * @link http://www.solarium-project.org/ + */ + +/** + * @namespace + */ +namespace Solarium\QueryType\Select\Query\Component\Facet; + +use Solarium\QueryType\Select\Query\Component\FacetSet; + +/** + * Facet interval + * + * @link http://wiki.apache.org/solr/SimpleFacetParameters#Interval_Faceting + */ +class Interval extends Facet +{ + + /** + * Initialize options + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + * + * @return void + */ + protected function init() + { + parent::init(); + + foreach ($this->options as $name => $value) { + switch ($name) { + case 'set': + $this->setSet($value); + break; + } + } + } + + /** + * Get the facet type + * + * @return string + */ + public function getType() + { + return FacetSet::FACET_INTERVAL; + } + + /** + * Set the field name + * + * @param string $field + * @return self Provides fluent interface + */ + public function setField($field) + { + return $this->setOption('field', $field); + } + + /** + * Get the field name + * + * @return string + */ + public function getField() + { + return $this->getOption('field'); + } + + /** + * Set set counts + * + * Use one of the constants as value. + * If you want to use multiple values supply an array or comma separated string + * + * @param string|array $set + * @return self Provides fluent interface + */ + public function setSet($set) + { + if (is_string($set)) { + $set = explode(',', $set); + $set = array_map('trim', $set); + } + + return $this->setOption('set', $set); + } + + /** + * Get set counts + * + * @return array + */ + public function getSet() + { + $set = $this->getOption('set'); + if ($set === null) { + $set = array(); + } + + return $set; + } + +} diff --git a/library/Solarium/QueryType/Select/Query/Component/Facet/Pivot.php b/library/Solarium/QueryType/Select/Query/Component/Facet/Pivot.php index 79687d2d0..6f92a62c7 100644 --- a/library/Solarium/QueryType/Select/Query/Component/Facet/Pivot.php +++ b/library/Solarium/QueryType/Select/Query/Component/Facet/Pivot.php @@ -54,6 +54,13 @@ class Pivot extends Facet */ protected $fields = array(); + /** + * Optional stats + * + * @var array + */ + protected $stats = array(); + /** * Initialize options * @@ -61,8 +68,15 @@ class Pivot extends Facet */ protected function init() { - if (isset($this->options['fields'])) { - $this->addFields($this->options['fields']); + foreach ($this->options as $name => $value) { + switch ($name) { + case 'fields': + $this->addFields($value); + break; + case 'stats': + $this->setStats($value); + break; + } } } @@ -184,4 +198,92 @@ public function setFields($fields) return $this; } + + /** + * Add stat + * + * @param string $stat + * @return self Provides fluent interface + */ + public function addStat($stat) + { + $this->stats[$stat] = true; + + return $this; + } + + /** + * Specify multiple Stats + * + * @param string|array $stats can be an array or string with comma + * separated statnames + * + * @return self Provides fluent interface + */ + public function addStats($stats) + { + if (is_string($stats)) { + $stats = explode(',', $stats); + $stats = array_map('trim', $stats); + } + + foreach ($stats as $stat) { + $this->addStat($stat); + } + + return $this; + } + + /** + * Remove a stat from the stats list + * + * @param string $stat + * @return self Provides fluent interface + */ + public function removeStat($stat) + { + if (isset($this->stats[$stat])) { + unset($this->stats[$stat]); + } + + return $this; + } + + /** + * Remove all stats from the stats list. + * + * @return self Provides fluent interface + */ + public function clearStats() + { + $this->stats = array(); + + return $this; + } + + /** + * Get the list of stats + * + * @return array + */ + public function getStats() + { + return array_keys($this->stats); + } + + /** + * Set multiple stats + * + * This overwrites any existing stats + * + * @param array $stats + * @return self Provides fluent interface + */ + public function setStats($stats) + { + $this->clearStats(); + $this->addStats($stats); + + return $this; + } } diff --git a/library/Solarium/QueryType/Select/Query/Component/FacetSet.php b/library/Solarium/QueryType/Select/Query/Component/FacetSet.php index 0dd92f2b8..a65289d25 100644 --- a/library/Solarium/QueryType/Select/Query/Component/FacetSet.php +++ b/library/Solarium/QueryType/Select/Query/Component/FacetSet.php @@ -77,6 +77,11 @@ class FacetSet extends Component */ const FACET_PIVOT = 'pivot'; + /** + * Facet type interval + */ + const FACET_INTERVAL = 'interval'; + /** * Facet type mapping * @@ -88,6 +93,7 @@ class FacetSet extends Component self::FACET_MULTIQUERY => 'Solarium\QueryType\Select\Query\Component\Facet\MultiQuery', self::FACET_RANGE => 'Solarium\QueryType\Select\Query\Component\Facet\Range', self::FACET_PIVOT => 'Solarium\QueryType\Select\Query\Component\Facet\Pivot', + self::FACET_INTERVAL => 'Solarium\QueryType\Select\Query\Component\Facet\Interval', ); /** @@ -526,4 +532,16 @@ public function createFacetPivot($options = null, $add = true) { return $this->createFacet(self::FACET_PIVOT, $options, $add); } + + /** + * Get a facet interval instance + * + * @param mixed $options + * @param bool $add + * @return \Solarium\QueryType\Select\Query\Component\Facet\Interval + */ + public function createFacetInterval($options = null, $add = true) + { + return $this->createFacet(self::FACET_INTERVAL, $options, $add); + } } diff --git a/library/Solarium/QueryType/Select/Query/Component/Grouping.php b/library/Solarium/QueryType/Select/Query/Component/Grouping.php index 06b72b1e6..37eed331b 100644 --- a/library/Solarium/QueryType/Select/Query/Component/Grouping.php +++ b/library/Solarium/QueryType/Select/Query/Component/Grouping.php @@ -477,11 +477,12 @@ public function getFunction() /** * Set facet option * - * Group based on the unique values of a function query. + * Whether to compute grouped facets. + * Grouped facets are computed based on the first specified group. * This parameter only is supported on Solr 4.0+ * - * @param string $value - * @return self Provides fluent interface + * @param boolean $value + * @return self Provides fluent interface */ public function setFacet($value) { @@ -491,7 +492,7 @@ public function setFacet($value) /** * Get facet option * - * @return string|null + * @return boolean|null */ public function getFacet() { diff --git a/library/Solarium/QueryType/Select/Query/Component/Stats/Field.php b/library/Solarium/QueryType/Select/Query/Component/Stats/Field.php index 84b7f8fec..d5b72fa47 100644 --- a/library/Solarium/QueryType/Select/Query/Component/Stats/Field.php +++ b/library/Solarium/QueryType/Select/Query/Component/Stats/Field.php @@ -52,6 +52,13 @@ class Field extends Configurable */ protected $facets = array(); + /** + * pivot facets for these stats + * + * @var array + */ + protected $pivots = array(); + /** * Initialize options * @@ -67,6 +74,9 @@ protected function init() case 'facet': $this->setFacets($value); break; + case 'pivot': + $this->setPivots($value); + break; } } } @@ -179,4 +189,92 @@ public function setFacets($facets) return $this; } + + /** + * Add pivot + * + * @param string $pivot + * @return self Provides fluent interface + */ + public function addPivot($pivot) + { + $this->pivots[$pivot] = true; + + return $this; + } + + /** + * Specify multiple Pivots + * + * @param string|array $pivots can be an array or string with comma + * separated facetnames + * + * @return self Provides fluent interface + */ + public function addPivots($pivots) + { + if (is_string($pivots)) { + $pivots = explode(',', $pivots); + $pivots = array_map('trim', $pivots); + } + + foreach ($pivots as $facet) { + $this->addPivot($facet); + } + + return $this; + } + + /** + * Remove a pivot facet from the pivot list + * + * @param string $pivot + * @return self Provides fluent interface + */ + public function removePivot($pivot) + { + if (isset($this->pivots[$pivot])) { + unset($this->pivots[$pivot]); + } + + return $this; + } + + /** + * Remove all pivot facets from the pivot list. + * + * @return self Provides fluent interface + */ + public function clearPivots() + { + $this->pivots = array(); + + return $this; + } + + /** + * Get the list of pivot facets + * + * @return array + */ + public function getPivots() + { + return array_keys($this->pivots); + } + + /** + * Set multiple pivot facets + * + * This overwrites any existing pivots + * + * @param array $pivots + * @return self Provides fluent interface + */ + public function setPivots($pivots) + { + $this->clearPivots(); + $this->addPivots($pivots); + + return $this; + } } diff --git a/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php b/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php index a1a74109a..122c1ec75 100644 --- a/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php +++ b/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php @@ -46,6 +46,7 @@ use Solarium\QueryType\Select\Query\Component\Facet\Query as FacetQuery; use Solarium\QueryType\Select\Query\Component\Facet\Range as FacetRange; use Solarium\QueryType\Select\Query\Component\Facet\Pivot as FacetPivot; +use Solarium\QueryType\Select\Query\Component\Facet\Interval as FacetInterval; use Solarium\Exception\UnexpectedValueException; /** @@ -93,6 +94,9 @@ public function buildComponent($component, $request) case FacetsetComponent::FACET_PIVOT: $this->addFacetPivot($request, $facet); break; + case FacetsetComponent::FACET_INTERVAL: + $this->addFacetInterval($request, $facet); + break; default: throw new UnexpectedValueException('Unknown facet type'); } @@ -205,13 +209,52 @@ public function addFacetRange($request, $facet) */ public function addFacetPivot($request, $facet) { + $stats = $facet->getStats(); + + if (count($stats) > 0) { + $key = array('stats' => implode('', $stats)); + + // when specifying stats, solr sets the field as key + $facet->setKey(implode(',', $facet->getFields())); + } else { + $key = array('key' => $facet->getKey()); + } + $request->addParam( 'facet.pivot', $this->renderLocalParams( implode(',', $facet->getFields()), - array('key' => $facet->getKey(), 'ex' => $facet->getExcludes()) + array_merge($key, array('ex' => $facet->getExcludes())) ) ); $request->addParam('facet.pivot.mincount', $facet->getMinCount(), true); } + + /** + * Add params for a interval facet to request + * + * @param Request $request + * @param FacetInterval $facet + * @return void + */ + public function addFacetInterval($request, $facet) + { + $field = $facet->getField(); + + $request->addParam( + 'facet.interval', + $this->renderLocalParams( + $field + // key & ex not supported for interval + //,array('key' => $facet->getKey(), 'ex' => $facet->getExcludes()) + ) + ); + + foreach ($facet->getSet() as $key => $setValue) { + if(is_string($key)) { + $setValue = '{!key="'.$key.'"}'.$setValue; + } + $request->addParam("f.$field.facet.interval.set", $setValue); + } + } } diff --git a/library/Solarium/QueryType/Select/RequestBuilder/Component/Stats.php b/library/Solarium/QueryType/Select/RequestBuilder/Component/Stats.php index 351ed610a..78b7d9ab4 100644 --- a/library/Solarium/QueryType/Select/RequestBuilder/Component/Stats.php +++ b/library/Solarium/QueryType/Select/RequestBuilder/Component/Stats.php @@ -60,8 +60,10 @@ public function buildComponent($component, $request) // add fields foreach ($component->getFields() as $field) { + $pivots = $field->getPivots(); - $request->addParam('stats.field', $field->getKey()); + $prefix = (count($pivots) > 0) ? '{!tag='.implode(',', $pivots).'}' : ''; + $request->addParam('stats.field', $prefix . $field->getKey()); // add field specific facet stats foreach ($field->getFacets() as $facet) { diff --git a/library/Solarium/QueryType/Select/ResponseParser/Component/FacetSet.php b/library/Solarium/QueryType/Select/ResponseParser/Component/FacetSet.php index 70ae27411..e12771277 100644 --- a/library/Solarium/QueryType/Select/ResponseParser/Component/FacetSet.php +++ b/library/Solarium/QueryType/Select/ResponseParser/Component/FacetSet.php @@ -51,6 +51,7 @@ use Solarium\QueryType\Select\Result\Facet\MultiQuery as ResultFacetMultiQuery; use Solarium\QueryType\Select\Result\Facet\Range as ResultFacetRange; use Solarium\QueryType\Select\Result\Facet\Pivot\Pivot as ResultFacetPivot; +use Solarium\QueryType\Select\Result\Facet\Interval as ResultFacetInterval; use Solarium\Exception\RuntimeException; use Solarium\Core\Query\ResponseParser as ResponseParserAbstract; @@ -86,6 +87,9 @@ public function parse($query, $facetSet, $data) case 'facet_pivot': $method = 'createFacetPivot'; break; + case 'facet_interval': + $method = 'createFacetInterval'; + break; default: throw new RuntimeException('Unknown facet class identifier'); } @@ -118,6 +122,9 @@ public function parse($query, $facetSet, $data) case QueryFacetSet::FACET_PIVOT: $result = $this->facetPivot($query, $facet, $data); break; + case QueryFacetSet::FACET_INTERVAL: + $result = $this->facetInterval($query, $facet, $data); + break; default: throw new RuntimeException('Unknown facet type'); } @@ -236,6 +243,24 @@ protected function facetRange($query, $facet, $data) return new ResultFacetRange($data['counts'], $before, $after, $between, $start, $end, $gap); } + + /** + * Add a facet result for a interval facet + * + * @param Query $query + * @param QueryFacetInterval $facet + * @param array $data + * @return ResultFacetInterval|null + */ + protected function facetInterval($query, $facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_intervals'][$key])) { + return null; + } + + return new ResultFacetInterval($data['facet_counts']['facet_intervals'][$key]); + } /** * Add a facet result for a range facet diff --git a/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php b/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php index d0ca69d3a..b1910bb45 100644 --- a/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php +++ b/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php @@ -96,6 +96,30 @@ public function parse($query, $spellcheck, $data) } } + /* + * https://issues.apache.org/jira/browse/SOLR-3029 + * Solr5 has moved collations and correctlySpelled + * directly under spellcheck. + */ + if (isset($data['spellcheck']['collations']) && + is_array($data['spellcheck']['collations']) + ) { + foreach ($data['spellcheck']['collations'] as $collationResult) { + if (is_array($collationResult)) { + $collation = array(); + foreach ($collationResult as $key => $value) { + $collation = array_merge($collation, array($key, $value)); + } + $collations = array_merge($collations, $this->parseCollation($query, $collation )); + } + } + } + + if (isset($data['spellcheck']['correctlySpelled']) + ) { + $correctlySpelled = $data['spellcheck']['correctlySpelled']; + } + return new SpellcheckResult\Result($suggestions, $collations, $correctlySpelled); } else { return null; diff --git a/library/Solarium/QueryType/Select/Result/AbstractDocument.php b/library/Solarium/QueryType/Select/Result/AbstractDocument.php index 50207d4ec..2b514de05 100644 --- a/library/Solarium/QueryType/Select/Result/AbstractDocument.php +++ b/library/Solarium/QueryType/Select/Result/AbstractDocument.php @@ -78,6 +78,20 @@ public function __get($name) return $this->fields[$name]; } + /** + * Check if field is set by name + * + * Magic method for checking if fields are set as properties of this document + * object, by field name. Also used by empty(). + * + * @param string $name + * @return boolean + */ + public function __isset($name) + { + return isset($this->fields[$name]); + } + /** * IteratorAggregate implementation * diff --git a/library/Solarium/QueryType/Select/Result/Facet/Interval.php b/library/Solarium/QueryType/Select/Result/Facet/Interval.php new file mode 100644 index 000000000..723370d2b --- /dev/null +++ b/library/Solarium/QueryType/Select/Result/Facet/Interval.php @@ -0,0 +1,51 @@ + + * @license http://github.com/basdenooijer/solarium/raw/master/COPYING + * @link http://www.solarium-project.org/ + */ + +/** + * @namespace + */ +namespace Solarium\QueryType\Select\Result\Facet; + +/** + * Select interval facet result + * + * A interval facet will usually return a dataset of multiple rows, in each row a + * value and its count. You can access the values as an array using + * {@link getValues()} or iterate this object. + */ +class Interval extends Field +{ + +} diff --git a/library/Solarium/QueryType/Select/Result/Facet/Pivot/PivotItem.php b/library/Solarium/QueryType/Select/Result/Facet/Pivot/PivotItem.php index ef2505362..b233adcca 100644 --- a/library/Solarium/QueryType/Select/Result/Facet/Pivot/PivotItem.php +++ b/library/Solarium/QueryType/Select/Result/Facet/Pivot/PivotItem.php @@ -38,6 +38,8 @@ */ namespace Solarium\QueryType\Select\Result\Facet\Pivot; +use Solarium\QueryType\Select\Result\Stats\Stats; + /** * Select field pivot result * @@ -65,6 +67,13 @@ class PivotItem extends Pivot */ protected $count; + /** + * Field stats + * + * @var mixed + */ + protected $stats; + /** * Constructor * @@ -81,6 +90,10 @@ public function __construct($data) $this->pivot[] = new PivotItem($pivotData); } } + + if (isset($data['stats'])) { + $this->stats = new Stats($data['stats']); + } } /** @@ -112,4 +125,14 @@ public function getCount() { return $this->count; } + + /** + * Get stats + * + * @return Stats + */ + public function getStats() + { + return $this->stats; + } } diff --git a/library/Solarium/QueryType/Update/Query/Command/Add.php b/library/Solarium/QueryType/Update/Query/Command/Add.php index cd16a19cf..51ddf55d6 100644 --- a/library/Solarium/QueryType/Update/Query/Command/Add.php +++ b/library/Solarium/QueryType/Update/Query/Command/Add.php @@ -89,9 +89,12 @@ public function addDocument(DocumentInterface $document) */ public function addDocuments($documents) { - foreach ($documents as $document) { - if (!($document instanceof DocumentInterface)) { - throw new RuntimeException('Documents must implement DocumentInterface.'); + //only check documents for type if in an array (iterating a Traversable may do unnecessary work) + if (is_array($documents)) { + foreach ($documents as $document) { + if (!($document instanceof DocumentInterface)) { + throw new RuntimeException('Documents must implement DocumentInterface.'); + } } } diff --git a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/DocumentTest.php b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/DocumentTest.php index 38f03cb26..ec4b5ffdd 100644 --- a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/DocumentTest.php +++ b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/DocumentTest.php @@ -33,9 +33,9 @@ use Solarium\QueryType\Select\Result\Document; use Solarium\Plugin\MinimumScoreFilter\Document as FilterDocument; -use Solarium\Tests\QueryType\Select\Result\DocumentTest as SelectDocumentTest; +use Solarium\Tests\QueryType\Select\Result\AbstractDocumentTest; -class DocumentTest extends SelectDocumentTest +class DocumentTest extends AbstractDocumentTest { protected function setUp() { diff --git a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/QueryTest.php b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/QueryTest.php index deea33e28..2b6ca65bc 100644 --- a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/QueryTest.php +++ b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/QueryTest.php @@ -32,11 +32,10 @@ namespace Solarium\Tests\Plugin\MinimumScoreFilter; use Solarium\Plugin\MinimumScoreFilter\Query; -use Solarium\Tests\QueryType\Select\Query\QueryTest as SelectQueryTest; +use Solarium\Tests\QueryType\Select\Query\AbstractQueryTest; -class QueryTest extends SelectQueryTest +class QueryTest extends AbstractQueryTest { - public function setUp() { $this->query = new Query; diff --git a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/ResultTest.php b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/ResultTest.php index 94236ae9e..f6550b4ea 100644 --- a/tests/Solarium/Tests/Plugin/MinimumScoreFilter/ResultTest.php +++ b/tests/Solarium/Tests/Plugin/MinimumScoreFilter/ResultTest.php @@ -34,9 +34,9 @@ use Solarium\Plugin\MinimumScoreFilter\Query; use Solarium\Plugin\MinimumScoreFilter\Result; use Solarium\QueryType\Select\Result\Document; -use Solarium\Tests\QueryType\Select\Result\ResultTest as SelectResultTest; +use Solarium\Tests\QueryType\Select\Result\AbstractResultTest; -class ResultTest extends SelectResultTest +class ResultTest extends AbstractResultTest { public function setUp() { diff --git a/tests/Solarium/Tests/QueryType/Extract/RequestBuilderTest.php b/tests/Solarium/Tests/QueryType/Extract/RequestBuilderTest.php index 0c7433085..5f52cb06f 100644 --- a/tests/Solarium/Tests/QueryType/Extract/RequestBuilderTest.php +++ b/tests/Solarium/Tests/QueryType/Extract/RequestBuilderTest.php @@ -131,4 +131,14 @@ public function testDocumentWithBoostThrowsException() $this->setExpectedException('Solarium\Exception\RuntimeException'); $this->builder->build($this->query); } + + public function testContentTypeHeader() + { + $headers = array( + 'Content-Type: multipart/form-data' + ); + $request = $this->builder->build($this->query); + $this->assertEquals($headers, + $request->getHeaders()); + } } diff --git a/tests/Solarium/Tests/QueryType/Extract/ResultTest.php b/tests/Solarium/Tests/QueryType/Extract/ResultTest.php index d607b27fa..852774b6f 100644 --- a/tests/Solarium/Tests/QueryType/Extract/ResultTest.php +++ b/tests/Solarium/Tests/QueryType/Extract/ResultTest.php @@ -31,10 +31,10 @@ namespace Solarium\Tests\QueryType\Extract; -use Solarium\Tests\QueryType\Update\ResultTest as UpdateResultTest; use Solarium\QueryType\Extract\Result as ExtractResult; +use Solarium\Tests\QueryType\Update\AbstractResultTest; -class ResultTest extends UpdateResultTest +class ResultTest extends AbstractResultTest { public function setUp() { diff --git a/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php b/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php new file mode 100644 index 000000000..e31485db5 --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php @@ -0,0 +1,711 @@ +assertEquals(Client::QUERY_SELECT, $this->query->getType()); + } + + public function testGetResponseParser() + { + $this->assertInstanceOf( + 'Solarium\QueryType\Select\ResponseParser\ResponseParser', + $this->query->getResponseParser() + ); + } + + public function testGetRequestBuilder() + { + $this->assertInstanceOf( + 'Solarium\QueryType\Select\RequestBuilder\RequestBuilder', + $this->query->getRequestBuilder() + ); + } + + public function testSetAndGetStart() + { + $this->query->setStart(234); + $this->assertEquals(234, $this->query->getStart()); + } + + public function testSetAndGetQueryWithTrim() + { + $this->query->setQuery(' *:* '); + $this->assertEquals('*:*', $this->query->getQuery()); + } + + public function testSetAndGetQueryWithBind() + { + $this->query->setQuery('id:%1%', array(678)); + $this->assertEquals('id:678', $this->query->getQuery()); + } + + public function testSetAndGetQueryDefaultOperator() + { + $value = Query::QUERY_OPERATOR_AND; + + $this->query->setQueryDefaultOperator($value); + $this->assertEquals($value, $this->query->getQueryDefaultOperator()); + } + + public function testSetAndGetQueryDefaultField() + { + $value = 'mydefault'; + + $this->query->setQueryDefaultField($value); + $this->assertEquals($value, $this->query->getQueryDefaultField()); + } + + public function testSetAndGetResultClass() + { + $this->query->setResultClass('MyResult'); + $this->assertEquals('MyResult', $this->query->getResultClass()); + } + + public function testSetAndGetDocumentClass() + { + $this->query->setDocumentClass('MyDocument'); + $this->assertEquals('MyDocument', $this->query->getDocumentClass()); + } + + public function testSetAndGetRows() + { + $this->query->setRows(100); + $this->assertEquals(100, $this->query->getRows()); + } + + public function testAddField() + { + $expectedFields = $this->query->getFields(); + $expectedFields[] = 'newfield'; + $this->query->addField('newfield'); + $this->assertEquals($expectedFields, $this->query->getFields()); + } + + public function testClearFields() + { + $this->query->addField('newfield'); + $this->query->clearFields(); + $this->assertEquals(array(), $this->query->getFields()); + } + + public function testAddFields() + { + $fields = array('field1', 'field2'); + + $this->query->clearFields(); + $this->query->addFields($fields); + $this->assertEquals($fields, $this->query->getFields()); + } + + public function testAddFieldsAsStringWithTrim() + { + $this->query->clearFields(); + $this->query->addFields('field1, field2'); + $this->assertEquals(array('field1', 'field2'), $this->query->getFields()); + } + + public function testRemoveField() + { + $this->query->clearFields(); + $this->query->addFields(array('field1', 'field2')); + $this->query->removeField('field1'); + $this->assertEquals(array('field2'), $this->query->getFields()); + } + + public function testSetFields() + { + $this->query->clearFields(); + $this->query->addFields(array('field1', 'field2')); + $this->query->setFields(array('field3', 'field4')); + $this->assertEquals(array('field3', 'field4'), $this->query->getFields()); + } + + public function testAddSort() + { + $this->query->addSort('field1', Query::SORT_DESC); + $this->assertEquals( + array('field1' => Query::SORT_DESC), + $this->query->getSorts() + ); + } + + public function testAddSorts() + { + $sorts = array( + 'field1' => Query::SORT_DESC, + 'field2' => Query::SORT_ASC, + ); + + $this->query->addSorts($sorts); + $this->assertEquals( + $sorts, + $this->query->getSorts() + ); + } + + public function testRemoveSort() + { + $sorts = array( + 'field1' => Query::SORT_DESC, + 'field2' => Query::SORT_ASC, + ); + + $this->query->addSorts($sorts); + $this->query->removeSort('field1'); + $this->assertEquals( + array('field2' => Query::SORT_ASC), + $this->query->getSorts() + ); + } + + public function testRemoveInvalidSort() + { + $sorts = array( + 'field1' => Query::SORT_DESC, + 'field2' => Query::SORT_ASC, + ); + + $this->query->addSorts($sorts); + $this->query->removeSort('invalidfield'); //continue silently + $this->assertEquals( + $sorts, + $this->query->getSorts() + ); + } + + public function testClearSorts() + { + $sorts = array( + 'field1' => Query::SORT_DESC, + 'field2' => Query::SORT_ASC, + ); + + $this->query->addSorts($sorts); + $this->query->clearSorts(); + $this->assertEquals( + array(), + $this->query->getSorts() + ); + } + + public function testSetSorts() + { + $sorts = array( + 'field1' => Query::SORT_DESC, + 'field2' => Query::SORT_ASC, + ); + + $this->query->addSorts($sorts); + $this->query->setSorts(array('field3' => Query::SORT_ASC)); + $this->assertEquals( + array('field3' => Query::SORT_ASC), + $this->query->getSorts() + ); + } + + public function testAddAndGetFilterQuery() + { + $fq = new FilterQuery; + $fq->setKey('fq1')->setQuery('category:1'); + $this->query->addFilterQuery($fq); + + $this->assertEquals( + $fq, + $this->query->getFilterQuery('fq1') + ); + } + + public function testAddAndGetFilterQueryWithKey() + { + $key = 'fq1'; + + $fq = $this->query->createFilterQuery($key, true); + $fq->setQuery('category:1'); + + $this->assertEquals( + $key, + $fq->getKey() + ); + + $this->assertEquals( + $fq, + $this->query->getFilterQuery('fq1') + ); + } + + public function testAddFilterQueryWithoutKey() + { + $fq = new FilterQuery; + $fq->setQuery('category:1'); + + $this->setExpectedException('Solarium\Exception\InvalidArgumentException'); + $this->query->addFilterQuery($fq); + } + + public function testAddFilterQueryWithUsedKey() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq1')->setQuery('category:2'); + + $this->query->addFilterQuery($fq1); + $this->setExpectedException('Solarium\Exception\InvalidArgumentException'); + $this->query->addFilterQuery($fq2); + } + + public function testGetInvalidFilterQuery() + { + $this->assertEquals( + null, + $this->query->getFilterQuery('invalidtag') + ); + } + + public function testAddFilterQueries() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries = array('fq1' => $fq1, 'fq2' => $fq2); + + $this->query->addFilterQueries($filterQueries); + $this->assertEquals( + $filterQueries, + $this->query->getFilterQueries() + ); + } + + public function testRemoveFilterQuery() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries = array($fq1, $fq2); + + $this->query->addFilterQueries($filterQueries); + $this->query->removeFilterQuery('fq1'); + $this->assertEquals( + array('fq2' => $fq2), + $this->query->getFilterQueries() + ); + } + + public function testRemoveFilterQueryWithObjectInput() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries = array($fq1, $fq2); + + $this->query->addFilterQueries($filterQueries); + $this->query->removeFilterQuery($fq1); + $this->assertEquals( + array('fq2' => $fq2), + $this->query->getFilterQueries() + ); + } + + public function testRemoveInvalidFilterQuery() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries = array('fq1' => $fq1, 'fq2' => $fq2); + + $this->query->addFilterQueries($filterQueries); + $this->query->removeFilterQuery('fq3'); //continue silently + $this->assertEquals( + $filterQueries, + $this->query->getFilterQueries() + ); + } + + public function testClearFilterQueries() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries = array($fq1, $fq2); + + $this->query->addFilterQueries($filterQueries); + $this->query->clearFilterQueries(); + $this->assertEquals( + array(), + $this->query->getFilterQueries() + ); + } + + public function testSetFilterQueries() + { + $fq1 = new FilterQuery; + $fq1->setKey('fq1')->setQuery('category:1'); + + $fq2 = new FilterQuery; + $fq2->setKey('fq2')->setQuery('category:2'); + + $filterQueries1 = array('fq1' => $fq1, 'fq2' => $fq2); + + $this->query->addFilterQueries($filterQueries1); + + $fq3 = new FilterQuery; + $fq3->setKey('fq3')->setQuery('category:3'); + + $fq4 = new FilterQuery; + $fq4->setKey('fq4')->setQuery('category:4'); + + $filterQueries2 = array('fq3' => $fq3, 'fq4' => $fq4); + + $this->query->setFilterQueries($filterQueries2); + + $this->assertEquals( + $filterQueries2, + $this->query->getFilterQueries() + ); + } + + public function testConfigMode() + { + $config = array( + 'query' => 'text:mykeyword', + 'sort' => array('score' => 'asc'), + 'fields' => array('id', 'title', 'category'), + 'rows' => 100, + 'start' => 200, + 'filterquery' => array( + array('key' => 'pub', 'tag' => array('pub'), 'query' => 'published:true'), + 'online' => array('tag' => 'onl', 'query' => 'online:true') + ), + 'component' => array( + 'facetset' => array( + 'facet' => array( + array('type' => 'field', 'key' => 'categories', 'field' => 'category'), + 'category13' => array('type' => 'query', 'query' => 'category:13') + ) + ), + ), + 'resultclass' => 'MyResultClass', + 'documentclass' => 'MyDocumentClass', + 'tag' => array('t1', 't2'), + ); + $query = new Query($config); + + $this->assertEquals($config['query'], $query->getQuery()); + $this->assertEquals($config['sort'], $query->getSorts()); + $this->assertEquals($config['fields'], $query->getFields()); + $this->assertEquals($config['rows'], $query->getRows()); + $this->assertEquals($config['start'], $query->getStart()); + $this->assertEquals($config['documentclass'], $query->getDocumentClass()); + $this->assertEquals($config['resultclass'], $query->getResultClass()); + $this->assertEquals('published:true', $query->getFilterQuery('pub')->getQuery()); + $this->assertEquals('online:true', $query->getFilterQuery('online')->getQuery()); + + $facets = $query->getFacetSet()->getFacets(); + $this->assertEquals( + 'category', + $facets['categories']->getField() + ); + $this->assertEquals( + 'category:13', + $facets['category13']->getQuery() + ); + + $components = $query->getComponents(); + $this->assertEquals(1, count($components)); + $this->assertThat( + array_pop($components), + $this->isInstanceOf('Solarium\QueryType\Select\Query\Component\FacetSet') + ); + $this->assertEquals(array('t1', 't2'), $query->getTags()); + } + + public function testConfigModeWithSingleValueTag() + { + $query = $query = new Query(array('tag' => 't1')); + $this->assertEquals(array('t1'), $query->getTags()); + } + + public function testSetAndGetComponents() + { + $mlt = new MoreLikeThis; + $this->query->setComponent('mlt', $mlt); + + $this->assertEquals( + array('mlt' => $mlt), + $this->query->getComponents() + ); + } + + public function testSetAndGetComponent() + { + $mlt = new MoreLikeThis; + $this->query->setComponent('mlt', $mlt); + + $this->assertEquals( + $mlt, + $this->query->getComponent('mlt') + ); + } + + public function testSetAndGetComponentQueryInstance() + { + $mlt = new MoreLikeThis; + $this->query->setComponent('mlt', $mlt); + + $this->assertEquals( + $this->query, + $this->query->getComponent('mlt')->getQueryInstance() + ); + } + + public function testGetInvalidComponent() + { + $this->assertEquals( + null, + $this->query->getComponent('invalid') + ); + } + + public function testGetInvalidComponentAutoload() + { + $this->setExpectedException('Solarium\Exception\OutOfBoundsException'); + $this->query->getComponent('invalid', true); + } + + public function testRemoveComponent() + { + $mlt = new MoreLikeThis; + $this->query->setComponent('mlt', $mlt); + + $this->assertEquals( + array('mlt' => $mlt), + $this->query->getComponents() + ); + + $this->query->removeComponent('mlt'); + + $this->assertEquals( + array(), + $this->query->getComponents() + ); + } + + public function testRemoveComponentWithObjectInput() + { + $mlt = new MoreLikeThis; + $this->query->setComponent('mlt', $mlt); + + $this->assertEquals( + array('mlt' => $mlt), + $this->query->getComponents() + ); + + $this->query->removeComponent($mlt); + + $this->assertEquals( + array(), + $this->query->getComponents() + ); + } + + public function testGetMoreLikeThis() + { + $mlt = $this->query->getMoreLikeThis(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\MoreLikeThis', + get_class($mlt) + ); + } + + public function testGetDisMax() + { + $dismax = $this->query->getDisMax(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\DisMax', + get_class($dismax) + ); + } + + public function testGetHighlighting() + { + $hlt = $this->query->getHighlighting(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Highlighting\Highlighting', + get_class($hlt) + ); + } + + public function testGetGrouping() + { + $grouping = $this->query->getGrouping(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Grouping', + get_class($grouping) + ); + } + + public function testRegisterComponentType() + { + $components = $this->query->getComponentTypes(); + $components['mykey'] = 'mycomponent'; + + $this->query->registerComponentType('mykey', 'mycomponent', 'mybuilder', 'myparser'); + + $this->assertEquals( + $components, + $this->query->getComponentTypes() + ); + } + + public function testCreateFilterQuery() + { + $options = array('optionA' => 1, 'optionB' => 2); + $fq = $this->query->createFilterQuery($options); + + // check class + $this->assertThat($fq, $this->isInstanceOf('Solarium\QueryType\Select\Query\FilterQuery')); + + // check option forwarding + $fqOptions = $fq->getOptions(); + $this->assertEquals( + $options['optionB'], + $fqOptions['optionB'] + ); + } + + public function testGetSpellcheck() + { + $spellcheck = $this->query->getSpellcheck(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Spellcheck', + get_class($spellcheck) + ); + } + + public function testGetDistributedSearch() + { + $spellcheck = $this->query->getDistributedSearch(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\DistributedSearch', + get_class($spellcheck) + ); + } + + public function testGetStats() + { + $stats = $this->query->getStats(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Stats\Stats', + get_class($stats) + ); + } + + public function testGetDebug() + { + $stats = $this->query->getDebug(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Debug', + get_class($stats) + ); + } + + public function testAddTag() + { + $this->query->addTag('testtag'); + $this->assertEquals(array('testtag'), $this->query->getTags()); + } + + public function testAddTags() + { + $this->query->addTags(array('t1', 't2')); + $this->assertEquals(array('t1', 't2'), $this->query->getTags()); + } + + public function testRemoveTag() + { + $this->query->addTags(array('t1', 't2')); + $this->query->removeTag('t1'); + $this->assertEquals(array('t2'), $this->query->getTags()); + } + + public function testClearTags() + { + $this->query->addTags(array('t1', 't2')); + $this->query->clearTags(); + $this->assertEquals(array(), $this->query->getTags()); + } + + public function testSetTags() + { + $this->query->addTags(array('t1', 't2')); + $this->query->setTags(array('t3', 't4')); + $this->assertEquals(array('t3', 't4'), $this->query->getTags()); + } +} diff --git a/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/PivotTest.php b/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/PivotTest.php index 6a8bdaa0f..a0a22a8f5 100644 --- a/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/PivotTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/PivotTest.php @@ -67,6 +67,13 @@ public function testGetType() ); } + public function testSetMinCount() + { + $this->facet->setMinCount(5); + + $this->assertEquals(5, $this->facet->getMinCount()); + } + public function testAddField() { $expectedFields = $this->facet->getFields(); @@ -113,4 +120,51 @@ public function testSetFields() $this->facet->setFields(array('field3', 'field4')); $this->assertEquals(array('field3', 'field4'), $this->facet->getFields()); } + + public function testAddStat() + { + $expectedStats = $this->facet->getStats(); + $expectedStats[] = 'newstat'; + $this->facet->addStat('newstat'); + $this->assertEquals($expectedStats, $this->facet->getStats()); + } + + public function testClearStats() + { + $this->facet->addStat('newstat'); + $this->facet->clearStats(); + $this->assertEquals(array(), $this->facet->getStats()); + } + + public function testAddStats() + { + $stats = array('stat1', 'stat2'); + + $this->facet->clearStats(); + $this->facet->addStats($stats); + $this->assertEquals($stats, $this->facet->getStats()); + } + + public function testAddStatsAsStringWithTrim() + { + $this->facet->clearStats(); + $this->facet->addStats('stat1, stat2'); + $this->assertEquals(array('stat1', 'stat2'), $this->facet->getStats()); + } + + public function testRemoveStat() + { + $this->facet->clearStats(); + $this->facet->addStats(array('stat1', 'stat2')); + $this->facet->removeStat('stat1'); + $this->assertEquals(array('stat2'), $this->facet->getstats()); + } + + public function testSetStats() + { + $this->facet->clearStats(); + $this->facet->addStats(array('stat1', 'stat2')); + $this->facet->setStats(array('stat3', 'stat4')); + $this->assertEquals(array('stat3', 'stat4'), $this->facet->getStats()); + } } diff --git a/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/RangeTest.php b/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/RangeTest.php index 72a5d7e52..f16004d97 100644 --- a/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/RangeTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Query/Component/Facet/RangeTest.php @@ -82,6 +82,13 @@ public function testGetType() ); } + public function testSetMinCount() + { + $this->facet->setMinCount(5); + + $this->assertEquals(5, $this->facet->getMinCount()); + } + public function testSetAndGetField() { $this->facet->setField('price'); diff --git a/tests/Solarium/Tests/QueryType/Select/Query/Component/Stats/FieldTest.php b/tests/Solarium/Tests/QueryType/Select/Query/Component/Stats/FieldTest.php index 36deeab75..f4734efaa 100644 --- a/tests/Solarium/Tests/QueryType/Select/Query/Component/Stats/FieldTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Query/Component/Stats/FieldTest.php @@ -49,6 +49,7 @@ public function testConfigMode() { $options = array( 'facet' => 'field1, field2', + 'pivot' => 'piv1' ); $this->field->setOptions($options); @@ -107,4 +108,51 @@ public function testSetFacets() $this->field->setFacets(array('facet3', 'facet4')); $this->assertEquals(array('facet3', 'facet4'), $this->field->getFacets()); } + + public function testAddPivot() + { + $expectedPivots = $this->field->getPivots(); + $expectedPivots[] = 'newpivot'; + $this->field->addPivot('newpivot'); + $this->assertEquals($expectedPivots, $this->field->getPivots()); + } + + public function testClearPivots() + { + $this->field->addPivot('newpivot'); + $this->field->clearPivots(); + $this->assertEquals(array(), $this->field->getPivots()); + } + + public function testAddPivots() + { + $pivots = array('pivot1', 'pivot2'); + + $this->field->clearPivots(); + $this->field->addPivots($pivots); + $this->assertEquals($pivots, $this->field->getPivots()); + } + + public function testAddPivotsAsStringWithTrim() + { + $this->field->clearPivots(); + $this->field->addPivots('pivot1, pivot2'); + $this->assertEquals(array('pivot1', 'pivot2'), $this->field->getPivots()); + } + + public function testRemovePivot() + { + $this->field->clearPivots(); + $this->field->addPivots(array('pivot1', 'pivot2')); + $this->field->removePivot('pivot1'); + $this->assertEquals(array('pivot2'), $this->field->getPivots()); + } + + public function testSetPivots() + { + $this->field->clearPivots(); + $this->field->addPivots(array('pivot1', 'pivot2')); + $this->field->setPivots(array('pivot3', 'pivot4')); + $this->assertEquals(array('pivot3', 'pivot4'), $this->field->getPivots()); + } } diff --git a/tests/Solarium/Tests/QueryType/Select/Query/QueryTest.php b/tests/Solarium/Tests/QueryType/Select/Query/QueryTest.php index 0430f0d53..9c547da88 100644 --- a/tests/Solarium/Tests/QueryType/Select/Query/QueryTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Query/QueryTest.php @@ -32,685 +32,11 @@ namespace Solarium\Tests\QueryType\Select\Query; use Solarium\QueryType\Select\Query\Query; -use Solarium\QueryType\Select\Query\FilterQuery; -use Solarium\Core\Client\Client; -use Solarium\QueryType\Select\Query\Component\MoreLikeThis; -class QueryTest extends \PHPUnit_Framework_TestCase +class QueryTest extends AbstractQueryTest { - /** - * @var Query - */ - protected $query; - public function setUp() { $this->query = new Query; } - - public function testGetType() - { - $this->assertEquals(Client::QUERY_SELECT, $this->query->getType()); - } - - public function testGetResponseParser() - { - $this->assertInstanceOf( - 'Solarium\QueryType\Select\ResponseParser\ResponseParser', - $this->query->getResponseParser() - ); - } - - public function testGetRequestBuilder() - { - $this->assertInstanceOf( - 'Solarium\QueryType\Select\RequestBuilder\RequestBuilder', - $this->query->getRequestBuilder() - ); - } - - public function testSetAndGetStart() - { - $this->query->setStart(234); - $this->assertEquals(234, $this->query->getStart()); - } - - public function testSetAndGetQueryWithTrim() - { - $this->query->setQuery(' *:* '); - $this->assertEquals('*:*', $this->query->getQuery()); - } - - public function testSetAndGetQueryWithBind() - { - $this->query->setQuery('id:%1%', array(678)); - $this->assertEquals('id:678', $this->query->getQuery()); - } - - public function testSetAndGetQueryDefaultOperator() - { - $value = Query::QUERY_OPERATOR_AND; - - $this->query->setQueryDefaultOperator($value); - $this->assertEquals($value, $this->query->getQueryDefaultOperator()); - } - - public function testSetAndGetQueryDefaultField() - { - $value = 'mydefault'; - - $this->query->setQueryDefaultField($value); - $this->assertEquals($value, $this->query->getQueryDefaultField()); - } - - public function testSetAndGetResultClass() - { - $this->query->setResultClass('MyResult'); - $this->assertEquals('MyResult', $this->query->getResultClass()); - } - - public function testSetAndGetDocumentClass() - { - $this->query->setDocumentClass('MyDocument'); - $this->assertEquals('MyDocument', $this->query->getDocumentClass()); - } - - public function testSetAndGetRows() - { - $this->query->setRows(100); - $this->assertEquals(100, $this->query->getRows()); - } - - public function testAddField() - { - $expectedFields = $this->query->getFields(); - $expectedFields[] = 'newfield'; - $this->query->addField('newfield'); - $this->assertEquals($expectedFields, $this->query->getFields()); - } - - public function testClearFields() - { - $this->query->addField('newfield'); - $this->query->clearFields(); - $this->assertEquals(array(), $this->query->getFields()); - } - - public function testAddFields() - { - $fields = array('field1', 'field2'); - - $this->query->clearFields(); - $this->query->addFields($fields); - $this->assertEquals($fields, $this->query->getFields()); - } - - public function testAddFieldsAsStringWithTrim() - { - $this->query->clearFields(); - $this->query->addFields('field1, field2'); - $this->assertEquals(array('field1', 'field2'), $this->query->getFields()); - } - - public function testRemoveField() - { - $this->query->clearFields(); - $this->query->addFields(array('field1', 'field2')); - $this->query->removeField('field1'); - $this->assertEquals(array('field2'), $this->query->getFields()); - } - - public function testSetFields() - { - $this->query->clearFields(); - $this->query->addFields(array('field1', 'field2')); - $this->query->setFields(array('field3', 'field4')); - $this->assertEquals(array('field3', 'field4'), $this->query->getFields()); - } - - public function testAddSort() - { - $this->query->addSort('field1', Query::SORT_DESC); - $this->assertEquals( - array('field1' => Query::SORT_DESC), - $this->query->getSorts() - ); - } - - public function testAddSorts() - { - $sorts = array( - 'field1' => Query::SORT_DESC, - 'field2' => Query::SORT_ASC, - ); - - $this->query->addSorts($sorts); - $this->assertEquals( - $sorts, - $this->query->getSorts() - ); - } - - public function testRemoveSort() - { - $sorts = array( - 'field1' => Query::SORT_DESC, - 'field2' => Query::SORT_ASC, - ); - - $this->query->addSorts($sorts); - $this->query->removeSort('field1'); - $this->assertEquals( - array('field2' => Query::SORT_ASC), - $this->query->getSorts() - ); - } - - public function testRemoveInvalidSort() - { - $sorts = array( - 'field1' => Query::SORT_DESC, - 'field2' => Query::SORT_ASC, - ); - - $this->query->addSorts($sorts); - $this->query->removeSort('invalidfield'); //continue silently - $this->assertEquals( - $sorts, - $this->query->getSorts() - ); - } - - public function testClearSorts() - { - $sorts = array( - 'field1' => Query::SORT_DESC, - 'field2' => Query::SORT_ASC, - ); - - $this->query->addSorts($sorts); - $this->query->clearSorts(); - $this->assertEquals( - array(), - $this->query->getSorts() - ); - } - - public function testSetSorts() - { - $sorts = array( - 'field1' => Query::SORT_DESC, - 'field2' => Query::SORT_ASC, - ); - - $this->query->addSorts($sorts); - $this->query->setSorts(array('field3' => Query::SORT_ASC)); - $this->assertEquals( - array('field3' => Query::SORT_ASC), - $this->query->getSorts() - ); - } - - public function testAddAndGetFilterQuery() - { - $fq = new FilterQuery; - $fq->setKey('fq1')->setQuery('category:1'); - $this->query->addFilterQuery($fq); - - $this->assertEquals( - $fq, - $this->query->getFilterQuery('fq1') - ); - } - - public function testAddAndGetFilterQueryWithKey() - { - $key = 'fq1'; - - $fq = $this->query->createFilterQuery($key, true); - $fq->setQuery('category:1'); - - $this->assertEquals( - $key, - $fq->getKey() - ); - - $this->assertEquals( - $fq, - $this->query->getFilterQuery('fq1') - ); - } - - public function testAddFilterQueryWithoutKey() - { - $fq = new FilterQuery; - $fq->setQuery('category:1'); - - $this->setExpectedException('Solarium\Exception\InvalidArgumentException'); - $this->query->addFilterQuery($fq); - } - - public function testAddFilterQueryWithUsedKey() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq1')->setQuery('category:2'); - - $this->query->addFilterQuery($fq1); - $this->setExpectedException('Solarium\Exception\InvalidArgumentException'); - $this->query->addFilterQuery($fq2); - } - - public function testGetInvalidFilterQuery() - { - $this->assertEquals( - null, - $this->query->getFilterQuery('invalidtag') - ); - } - - public function testAddFilterQueries() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries = array('fq1' => $fq1, 'fq2' => $fq2); - - $this->query->addFilterQueries($filterQueries); - $this->assertEquals( - $filterQueries, - $this->query->getFilterQueries() - ); - } - - public function testRemoveFilterQuery() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries = array($fq1, $fq2); - - $this->query->addFilterQueries($filterQueries); - $this->query->removeFilterQuery('fq1'); - $this->assertEquals( - array('fq2' => $fq2), - $this->query->getFilterQueries() - ); - } - - public function testRemoveFilterQueryWithObjectInput() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries = array($fq1, $fq2); - - $this->query->addFilterQueries($filterQueries); - $this->query->removeFilterQuery($fq1); - $this->assertEquals( - array('fq2' => $fq2), - $this->query->getFilterQueries() - ); - } - - public function testRemoveInvalidFilterQuery() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries = array('fq1' => $fq1, 'fq2' => $fq2); - - $this->query->addFilterQueries($filterQueries); - $this->query->removeFilterQuery('fq3'); //continue silently - $this->assertEquals( - $filterQueries, - $this->query->getFilterQueries() - ); - } - - public function testClearFilterQueries() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries = array($fq1, $fq2); - - $this->query->addFilterQueries($filterQueries); - $this->query->clearFilterQueries(); - $this->assertEquals( - array(), - $this->query->getFilterQueries() - ); - } - - public function testSetFilterQueries() - { - $fq1 = new FilterQuery; - $fq1->setKey('fq1')->setQuery('category:1'); - - $fq2 = new FilterQuery; - $fq2->setKey('fq2')->setQuery('category:2'); - - $filterQueries1 = array('fq1' => $fq1, 'fq2' => $fq2); - - $this->query->addFilterQueries($filterQueries1); - - $fq3 = new FilterQuery; - $fq3->setKey('fq3')->setQuery('category:3'); - - $fq4 = new FilterQuery; - $fq4->setKey('fq4')->setQuery('category:4'); - - $filterQueries2 = array('fq3' => $fq3, 'fq4' => $fq4); - - $this->query->setFilterQueries($filterQueries2); - - $this->assertEquals( - $filterQueries2, - $this->query->getFilterQueries() - ); - } - - public function testConfigMode() - { - $config = array( - 'query' => 'text:mykeyword', - 'sort' => array('score' => 'asc'), - 'fields' => array('id', 'title', 'category'), - 'rows' => 100, - 'start' => 200, - 'filterquery' => array( - array('key' => 'pub', 'tag' => array('pub'), 'query' => 'published:true'), - 'online' => array('tag' => 'onl', 'query' => 'online:true') - ), - 'component' => array( - 'facetset' => array( - 'facet' => array( - array('type' => 'field', 'key' => 'categories', 'field' => 'category'), - 'category13' => array('type' => 'query', 'query' => 'category:13') - ) - ), - ), - 'resultclass' => 'MyResultClass', - 'documentclass' => 'MyDocumentClass', - 'tag' => array('t1', 't2'), - ); - $query = new Query($config); - - $this->assertEquals($config['query'], $query->getQuery()); - $this->assertEquals($config['sort'], $query->getSorts()); - $this->assertEquals($config['fields'], $query->getFields()); - $this->assertEquals($config['rows'], $query->getRows()); - $this->assertEquals($config['start'], $query->getStart()); - $this->assertEquals($config['documentclass'], $query->getDocumentClass()); - $this->assertEquals($config['resultclass'], $query->getResultClass()); - $this->assertEquals('published:true', $query->getFilterQuery('pub')->getQuery()); - $this->assertEquals('online:true', $query->getFilterQuery('online')->getQuery()); - - $facets = $query->getFacetSet()->getFacets(); - $this->assertEquals( - 'category', - $facets['categories']->getField() - ); - $this->assertEquals( - 'category:13', - $facets['category13']->getQuery() - ); - - $components = $query->getComponents(); - $this->assertEquals(1, count($components)); - $this->assertThat( - array_pop($components), - $this->isInstanceOf('Solarium\QueryType\Select\Query\Component\FacetSet') - ); - $this->assertEquals(array('t1', 't2'), $query->getTags()); - } - - public function testConfigModeWithSingleValueTag() - { - $query = $query = new Query(array('tag' => 't1')); - $this->assertEquals(array('t1'), $query->getTags()); - } - - public function testSetAndGetComponents() - { - $mlt = new MoreLikeThis; - $this->query->setComponent('mlt', $mlt); - - $this->assertEquals( - array('mlt' => $mlt), - $this->query->getComponents() - ); - } - - public function testSetAndGetComponent() - { - $mlt = new MoreLikeThis; - $this->query->setComponent('mlt', $mlt); - - $this->assertEquals( - $mlt, - $this->query->getComponent('mlt') - ); - } - - public function testSetAndGetComponentQueryInstance() - { - $mlt = new MoreLikeThis; - $this->query->setComponent('mlt', $mlt); - - $this->assertEquals( - $this->query, - $this->query->getComponent('mlt')->getQueryInstance() - ); - } - - public function testGetInvalidComponent() - { - $this->assertEquals( - null, - $this->query->getComponent('invalid') - ); - } - - public function testGetInvalidComponentAutoload() - { - $this->setExpectedException('Solarium\Exception\OutOfBoundsException'); - $this->query->getComponent('invalid', true); - } - - public function testRemoveComponent() - { - $mlt = new MoreLikeThis; - $this->query->setComponent('mlt', $mlt); - - $this->assertEquals( - array('mlt' => $mlt), - $this->query->getComponents() - ); - - $this->query->removeComponent('mlt'); - - $this->assertEquals( - array(), - $this->query->getComponents() - ); - } - - public function testRemoveComponentWithObjectInput() - { - $mlt = new MoreLikeThis; - $this->query->setComponent('mlt', $mlt); - - $this->assertEquals( - array('mlt' => $mlt), - $this->query->getComponents() - ); - - $this->query->removeComponent($mlt); - - $this->assertEquals( - array(), - $this->query->getComponents() - ); - } - - public function testGetMoreLikeThis() - { - $mlt = $this->query->getMoreLikeThis(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\MoreLikeThis', - get_class($mlt) - ); - } - - public function testGetDisMax() - { - $dismax = $this->query->getDisMax(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\DisMax', - get_class($dismax) - ); - } - - public function testGetHighlighting() - { - $hlt = $this->query->getHighlighting(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\Highlighting\Highlighting', - get_class($hlt) - ); - } - - public function testGetGrouping() - { - $grouping = $this->query->getGrouping(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\Grouping', - get_class($grouping) - ); - } - - public function testRegisterComponentType() - { - $components = $this->query->getComponentTypes(); - $components['mykey'] = 'mycomponent'; - - $this->query->registerComponentType('mykey', 'mycomponent', 'mybuilder', 'myparser'); - - $this->assertEquals( - $components, - $this->query->getComponentTypes() - ); - } - - public function testCreateFilterQuery() - { - $options = array('optionA' => 1, 'optionB' => 2); - $fq = $this->query->createFilterQuery($options); - - // check class - $this->assertThat($fq, $this->isInstanceOf('Solarium\QueryType\Select\Query\FilterQuery')); - - // check option forwarding - $fqOptions = $fq->getOptions(); - $this->assertEquals( - $options['optionB'], - $fqOptions['optionB'] - ); - } - - public function testGetSpellcheck() - { - $spellcheck = $this->query->getSpellcheck(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\Spellcheck', - get_class($spellcheck) - ); - } - - public function testGetDistributedSearch() - { - $spellcheck = $this->query->getDistributedSearch(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\DistributedSearch', - get_class($spellcheck) - ); - } - - public function testGetStats() - { - $stats = $this->query->getStats(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\Stats\Stats', - get_class($stats) - ); - } - - public function testGetDebug() - { - $stats = $this->query->getDebug(); - - $this->assertEquals( - 'Solarium\QueryType\Select\Query\Component\Debug', - get_class($stats) - ); - } - - public function testAddTag() - { - $this->query->addTag('testtag'); - $this->assertEquals(array('testtag'), $this->query->getTags()); - } - - public function testAddTags() - { - $this->query->addTags(array('t1', 't2')); - $this->assertEquals(array('t1', 't2'), $this->query->getTags()); - } - - public function testRemoveTag() - { - $this->query->addTags(array('t1', 't2')); - $this->query->removeTag('t1'); - $this->assertEquals(array('t2'), $this->query->getTags()); - } - - public function testClearTags() - { - $this->query->addTags(array('t1', 't2')); - $this->query->clearTags(); - $this->assertEquals(array(), $this->query->getTags()); - } - - public function testSetTags() - { - $this->query->addTags(array('t1', 't2')); - $this->query->setTags(array('t3', 't4')); - $this->assertEquals(array('t3', 't4'), $this->query->getTags()); - } } diff --git a/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php index af5479155..041bd003f 100644 --- a/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php +++ b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php @@ -208,6 +208,30 @@ public function testBuildWithPivotFacet() urldecode($request->getUri()) ); } + + public function testBuildWithPivotStatFacet() + { + $facet = new FacetPivot( + array( + 'key' => 'f1', + 'fields' => 'cat,inStock', + 'stats' => 'piv1' + ) + ); + $this->component->addFacet($facet); + + $request = $this->builder->buildComponent($this->component, $this->request); + + $this->assertEquals( + null, + $request->getRawData() + ); + + $this->assertEquals( + '?facet=true&facet.pivot={!stats=piv1}cat,inStock', + urldecode($request->getUri()) + ); + } } class UnknownFacet extends FacetField diff --git a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/FacetSetTest.php b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/FacetSetTest.php index 83bb99e73..4f56d1106 100644 --- a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/FacetSetTest.php +++ b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/FacetSetTest.php @@ -201,6 +201,10 @@ public function testParseExtractFromResponse() 'pivot' => array( array('field' => 'price', 'value' => 1, 'count' => 12), array('field' => 'price', 'value' => 2, 'count' => 8), + ), + 'stats' => array( + 'min' => 4, + 'max' => 6, ) ) ), @@ -262,6 +266,13 @@ public function testParseExtractFromResponse() count($facets['cat,price']) ); + $pivots = $facets['cat,price']->getPivot(); + + $this->assertEquals( + 2, + count($pivots[0]->getStats()) + ); + $this->query = new Query; } diff --git a/tests/Solarium/Tests/QueryType/Select/Result/AbstractDocumentTest.php b/tests/Solarium/Tests/QueryType/Select/Result/AbstractDocumentTest.php new file mode 100644 index 000000000..eba87ab81 --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Select/Result/AbstractDocumentTest.php @@ -0,0 +1,152 @@ + 123, + 'name' => 'Test document', + 'categories' => array(1, 2, 3), + 'empty_field' => '', + ); + + public function testGetFields() + { + $this->assertEquals($this->fields, $this->doc->getFields()); + } + + public function testGetFieldAsProperty() + { + $this->assertEquals( + $this->fields['categories'], + $this->doc->categories + ); + + $this->assertEquals( + null, + $this->doc->invalidfieldname + ); + } + + public function testPropertyIsset() + { + $this->assertTrue( + isset($this->doc->categories) + ); + + $this->assertFalse( + isset($this->doc->invalidfieldname) + ); + } + + public function testPropertyEmpty() + { + $this->assertTrue( + empty($this->doc->empty_field) + ); + + $this->assertFalse( + empty($this->doc->categories) + ); + } + + public function testSetField() + { + $this->setExpectedException('Solarium\Exception\RuntimeException'); + $this->doc->newField = 'new value'; + } + + public function testIterator() + { + $fields = array(); + foreach ($this->doc as $key => $field) { + $fields[$key] = $field; + } + + $this->assertEquals($this->fields, $fields); + } + + public function testArrayGet() + { + $this->assertEquals( + $this->fields['categories'], + $this->doc['categories'] + ); + + $this->assertEquals( + null, + $this->doc['invalidfieldname'] + ); + } + + public function testArrayIsset() + { + $this->assertTrue( + isset($this->doc['categories']) + ); + + $this->assertFalse( + isset($this->doc['invalidfieldname']) + ); + } + + public function testArrayEmpty() + { + $this->assertTrue( + empty($this->doc['empty_field']) + ); + + $this->assertFalse( + empty($this->doc['categories']) + ); + } + + public function testArraySet() + { + $this->setExpectedException('Solarium\Exception\RuntimeException'); + $this->doc['newField'] = 'new value'; + } + + public function testArrayUnset() + { + $this->setExpectedException('Solarium\Exception\RuntimeException'); + unset($this->doc['newField']); + } + + public function testCount() + { + $this->assertEquals(count($this->fields), count($this->doc)); + } +} diff --git a/tests/Solarium/Tests/QueryType/Select/Result/AbstractResultTest.php b/tests/Solarium/Tests/QueryType/Select/Result/AbstractResultTest.php new file mode 100644 index 000000000..92f577aef --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Select/Result/AbstractResultTest.php @@ -0,0 +1,222 @@ +numFound = 11; + $this->maxScore = 0.91; + + $this->docs = array( + new Document(array('id'=>1, 'title'=>'doc1')), + new Document(array('id'=>1, 'title'=>'doc1')), + ); + + $this->facetSet = 'dummy-facetset-value'; + $this->moreLikeThis = 'dummy-facetset-value'; + $this->highlighting = 'dummy-highlighting-value'; + $this->grouping = 'dummy-grouping-value'; + $this->spellcheck = 'dummy-grouping-value'; + $this->stats = 'dummy-stats-value'; + $this->debug = 'dummy-debug-value'; + + $this->components = array( + Query::COMPONENT_FACETSET => $this->facetSet, + Query::COMPONENT_MORELIKETHIS => $this->moreLikeThis, + Query::COMPONENT_HIGHLIGHTING => $this->highlighting, + Query::COMPONENT_GROUPING => $this->grouping, + Query::COMPONENT_SPELLCHECK => $this->spellcheck, + Query::COMPONENT_STATS => $this->stats, + Query::COMPONENT_DEBUG => $this->debug, + ); + + $this->result = new SelectDummy(1, 12, $this->numFound, $this->maxScore, $this->docs, $this->components); + } + + public function testGetNumFound() + { + $this->assertEquals($this->numFound, $this->result->getNumFound()); + } + + public function testGetMaxScore() + { + $this->assertEquals($this->maxScore, $this->result->getMaxScore()); + } + + public function testGetDocuments() + { + $this->assertEquals($this->docs, $this->result->getDocuments()); + } + + public function testGetFacetSet() + { + $this->assertEquals($this->facetSet, $this->result->getFacetSet()); + } + + public function testCount() + { + $this->assertEquals(count($this->docs), count($this->result)); + } + + public function testGetComponents() + { + $this->assertEquals($this->components, $this->result->getComponents()); + } + + public function testGetComponent() + { + $this->assertEquals( + $this->components[Query::COMPONENT_MORELIKETHIS], + $this->result->getComponent(Query::COMPONENT_MORELIKETHIS) + ); + } + + public function testGetInvalidComponent() + { + $this->assertEquals( + null, + $this->result->getComponent('invalid') + ); + } + + public function testGetMoreLikeThis() + { + $this->assertEquals( + $this->components[Query::COMPONENT_MORELIKETHIS], + $this->result->getMoreLikeThis() + ); + } + + public function testGetHighlighting() + { + $this->assertEquals( + $this->components[Query::COMPONENT_HIGHLIGHTING], + $this->result->getHighlighting() + ); + } + + public function testGetGrouping() + { + $this->assertEquals( + $this->components[Query::COMPONENT_GROUPING], + $this->result->getGrouping() + ); + } + + public function testGetSpellcheck() + { + $this->assertEquals( + $this->components[Query::COMPONENT_SPELLCHECK], + $this->result->getSpellcheck() + ); + } + + public function testGetStats() + { + $this->assertEquals( + $this->components[Query::COMPONENT_STATS], + $this->result->getStats() + ); + } + + public function testGetDebug() + { + $this->assertEquals( + $this->components[Query::COMPONENT_DEBUG], + $this->result->getDebug() + ); + } + + public function testIterator() + { + $docs = array(); + foreach ($this->result as $key => $doc) { + $docs[$key] = $doc; + } + + $this->assertEquals($this->docs, $docs); + } + + public function testGetStatus() + { + $this->assertEquals( + 1, + $this->result->getStatus() + ); + } + + public function testGetQueryTime() + { + $this->assertEquals( + 12, + $this->result->getQueryTime() + ); + } +} + +class SelectDummy extends Result +{ + protected $parsed = true; + + public function __construct($status, $queryTime, $numfound, $maxscore, $docs, $components) + { + $this->numfound = $numfound; + $this->maxscore = $maxscore; + $this->documents = $docs; + $this->components = $components; + $this->queryTime = $queryTime; + $this->status = $status; + } +} diff --git a/tests/Solarium/Tests/QueryType/Select/Result/DocumentTest.php b/tests/Solarium/Tests/QueryType/Select/Result/DocumentTest.php index 8f2afdc21..6b99677f5 100644 --- a/tests/Solarium/Tests/QueryType/Select/Result/DocumentTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Result/DocumentTest.php @@ -33,102 +33,10 @@ use Solarium\QueryType\Select\Result\Document; -class DocumentTest extends \PHPUnit_Framework_TestCase +class DocumentTest extends AbstractDocumentTest { - protected $doc; - - protected $fields = array( - 'id' => 123, - 'name' => 'Test document', - 'categories' => array(1, 2, 3) - ); - protected function setUp() { $this->doc = new Document($this->fields); } - - public function testGetFields() - { - $this->assertEquals($this->fields, $this->doc->getFields()); - } - - public function testGetFieldAsProperty() - { - $this->assertEquals( - $this->fields['categories'], - $this->doc->categories - ); - } - - public function testGetInvalidFieldAsProperty() - { - $this->assertEquals( - null, - $this->doc->invalidfieldname - ); - } - - public function testSetField() - { - $this->setExpectedException('Solarium\Exception\RuntimeException'); - $this->doc->newField = 'new value'; - } - - public function testIterator() - { - $fields = array(); - foreach ($this->doc as $key => $field) { - $fields[$key] = $field; - } - - $this->assertEquals($this->fields, $fields); - } - - public function testArrayGet() - { - $this->assertEquals( - $this->fields['categories'], - $this->doc['categories'] - ); - } - - public function testArrayGetInvalidField() - { - $this->assertEquals( - null, - $this->doc['invalidfield'] - ); - } - - public function testArrayIsset() - { - $this->assertTrue( - isset($this->doc['categories']) - ); - } - - public function testArrayIssetInvalidField() - { - $this->assertFalse( - isset($this->doc['invalidfield']) - ); - } - - public function testArraySet() - { - $this->setExpectedException('Solarium\Exception\RuntimeException'); - $this->doc['newField'] = 'new value'; - } - - public function testArrayUnset() - { - $this->setExpectedException('Solarium\Exception\RuntimeException'); - unset($this->doc['newField']); - } - - public function testCount() - { - $this->assertEquals(count($this->fields), count($this->doc)); - } } diff --git a/tests/Solarium/Tests/QueryType/Select/Result/ResultTest.php b/tests/Solarium/Tests/QueryType/Select/Result/ResultTest.php index 00e6102e9..97028b3d3 100644 --- a/tests/Solarium/Tests/QueryType/Select/Result/ResultTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Result/ResultTest.php @@ -31,192 +31,10 @@ namespace Solarium\Tests\QueryType\Select\Result; -use Solarium\QueryType\Select\Result\Document; -use Solarium\QueryType\Select\Query\Query; -use Solarium\QueryType\Select\Result\Result; - -class ResultTest extends \PHPUnit_Framework_TestCase +class ResultTest extends AbstractResultTest { - /** - * @var SelectDummy - */ - protected $result; - - protected $numFound; - protected $maxScore; - protected $docs; - protected $components; - protected $facetSet; - protected $moreLikeThis; - protected $highlighting; - protected $grouping; - protected $stats; - protected $debug; - protected $spellcheck; - public function setUp() { - $this->numFound = 11; - $this->maxScore = 0.91; - - $this->docs = array( - new Document(array('id'=>1, 'title'=>'doc1')), - new Document(array('id'=>1, 'title'=>'doc1')), - ); - - $this->facetSet = 'dummy-facetset-value'; - $this->moreLikeThis = 'dummy-facetset-value'; - $this->highlighting = 'dummy-highlighting-value'; - $this->grouping = 'dummy-grouping-value'; - $this->spellcheck = 'dummy-grouping-value'; - $this->stats = 'dummy-stats-value'; - $this->debug = 'dummy-debug-value'; - - $this->components = array( - Query::COMPONENT_FACETSET => $this->facetSet, - Query::COMPONENT_MORELIKETHIS => $this->moreLikeThis, - Query::COMPONENT_HIGHLIGHTING => $this->highlighting, - Query::COMPONENT_GROUPING => $this->grouping, - Query::COMPONENT_SPELLCHECK => $this->spellcheck, - Query::COMPONENT_STATS => $this->stats, - Query::COMPONENT_DEBUG => $this->debug, - ); - - $this->result = new SelectDummy(1, 12, $this->numFound, $this->maxScore, $this->docs, $this->components); - } - - public function testGetNumFound() - { - $this->assertEquals($this->numFound, $this->result->getNumFound()); - } - - public function testGetMaxScore() - { - $this->assertEquals($this->maxScore, $this->result->getMaxScore()); - } - - public function testGetDocuments() - { - $this->assertEquals($this->docs, $this->result->getDocuments()); - } - - public function testGetFacetSet() - { - $this->assertEquals($this->facetSet, $this->result->getFacetSet()); - } - - public function testCount() - { - $this->assertEquals(count($this->docs), count($this->result)); - } - - public function testGetComponents() - { - $this->assertEquals($this->components, $this->result->getComponents()); - } - - public function testGetComponent() - { - $this->assertEquals( - $this->components[Query::COMPONENT_MORELIKETHIS], - $this->result->getComponent(Query::COMPONENT_MORELIKETHIS) - ); - } - - public function testGetInvalidComponent() - { - $this->assertEquals( - null, - $this->result->getComponent('invalid') - ); - } - - public function testGetMoreLikeThis() - { - $this->assertEquals( - $this->components[Query::COMPONENT_MORELIKETHIS], - $this->result->getMoreLikeThis() - ); - } - - public function testGetHighlighting() - { - $this->assertEquals( - $this->components[Query::COMPONENT_HIGHLIGHTING], - $this->result->getHighlighting() - ); - } - - public function testGetGrouping() - { - $this->assertEquals( - $this->components[Query::COMPONENT_GROUPING], - $this->result->getGrouping() - ); - } - - public function testGetSpellcheck() - { - $this->assertEquals( - $this->components[Query::COMPONENT_SPELLCHECK], - $this->result->getSpellcheck() - ); - } - - public function testGetStats() - { - $this->assertEquals( - $this->components[Query::COMPONENT_STATS], - $this->result->getStats() - ); - } - - public function testGetDebug() - { - $this->assertEquals( - $this->components[Query::COMPONENT_DEBUG], - $this->result->getDebug() - ); - } - - public function testIterator() - { - $docs = array(); - foreach ($this->result as $key => $doc) { - $docs[$key] = $doc; - } - - $this->assertEquals($this->docs, $docs); - } - - public function testGetStatus() - { - $this->assertEquals( - 1, - $this->result->getStatus() - ); - } - - public function testGetQueryTime() - { - $this->assertEquals( - 12, - $this->result->getQueryTime() - ); - } -} - -class SelectDummy extends Result -{ - protected $parsed = true; - - public function __construct($status, $queryTime, $numfound, $maxscore, $docs, $components) - { - $this->numfound = $numfound; - $this->maxscore = $maxscore; - $this->documents = $docs; - $this->components = $components; - $this->queryTime = $queryTime; - $this->status = $status; + parent::setUp(); } } diff --git a/tests/Solarium/Tests/QueryType/Update/AbstractResultTest.php b/tests/Solarium/Tests/QueryType/Update/AbstractResultTest.php new file mode 100644 index 000000000..d25896260 --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Update/AbstractResultTest.php @@ -0,0 +1,53 @@ +assertEquals( + 1, + $this->result->getStatus() + ); + } + + public function testGetQueryTime() + { + $this->assertEquals( + 12, + $this->result->getQueryTime() + ); + } +} diff --git a/tests/Solarium/Tests/QueryType/Update/ResultTest.php b/tests/Solarium/Tests/QueryType/Update/ResultTest.php index e15ec86b3..bd739d6c7 100644 --- a/tests/Solarium/Tests/QueryType/Update/ResultTest.php +++ b/tests/Solarium/Tests/QueryType/Update/ResultTest.php @@ -33,33 +33,12 @@ use Solarium\QueryType\Update\Result as UpdateResult; -class ResultTest extends \PHPUnit_Framework_TestCase +class ResultTest extends AbstractResultTest { - /** - * @var UpdateDummy - */ - protected $result; - public function setUp() { $this->result = new UpdateDummy(); } - - public function testGetStatus() - { - $this->assertEquals( - 1, - $this->result->getStatus() - ); - } - - public function testGetQueryTime() - { - $this->assertEquals( - 12, - $this->result->getQueryTime() - ); - } } class UpdateDummy extends UpdateResult