*/
-class MercurialProcessor
+class MercurialProcessor implements ProcessorInterface
{
private $level;
private static $cache;
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php
index 9d3f5590..66b80fbb 100644
--- a/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php
+++ b/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php
@@ -16,7 +16,7 @@ namespace Monolog\Processor;
*
* @author Andreas Hörnicke
*/
-class ProcessIdProcessor
+class ProcessIdProcessor implements ProcessorInterface
{
/**
* @param array $record
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php b/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php
new file mode 100644
index 00000000..7e64d4df
--- /dev/null
+++ b/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * An optional interface to allow labelling Monolog processors.
+ *
+ * @author Nicolas Grekas
+ */
+interface ProcessorInterface
+{
+ /**
+ * @return array The processed records
+ */
+ public function __invoke(array $records);
+}
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php
index c2686ce5..00885054 100644
--- a/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php
+++ b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php
@@ -11,6 +11,8 @@
namespace Monolog\Processor;
+use Monolog\Utils;
+
/**
* Processes a record's message according to PSR-3 rules
*
@@ -18,7 +20,7 @@ namespace Monolog\Processor;
*
* @author Jordi Boggiano
*/
-class PsrLogMessageProcessor
+class PsrLogMessageProcessor implements ProcessorInterface
{
/**
* @param array $record
@@ -35,7 +37,7 @@ class PsrLogMessageProcessor
if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) {
$replacements['{'.$key.'}'] = $val;
} elseif (is_object($val)) {
- $replacements['{'.$key.'}'] = '[object '.get_class($val).']';
+ $replacements['{'.$key.'}'] = '[object '.Utils::getClass($val).']';
} else {
$replacements['{'.$key.'}'] = '['.gettype($val).']';
}
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
index 7e2df2ac..615a4d99 100644
--- a/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
+++ b/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
@@ -16,7 +16,7 @@ namespace Monolog\Processor;
*
* @author Martijn Riemers
*/
-class TagProcessor
+class TagProcessor implements ProcessorInterface
{
private $tags;
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php
index 812707cd..d1f708cf 100644
--- a/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php
+++ b/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php
@@ -11,12 +11,14 @@
namespace Monolog\Processor;
+use Monolog\ResettableInterface;
+
/**
* Adds a unique identifier into records
*
* @author Simon Mönch
*/
-class UidProcessor
+class UidProcessor implements ProcessorInterface, ResettableInterface
{
private $uid;
@@ -26,7 +28,8 @@ class UidProcessor
throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32');
}
- $this->uid = substr(hash('md5', uniqid('', true)), 0, $length);
+
+ $this->uid = $this->generateUid($length);
}
public function __invoke(array $record)
@@ -43,4 +46,14 @@ class UidProcessor
{
return $this->uid;
}
+
+ public function reset()
+ {
+ $this->uid = $this->generateUid(strlen($this->uid));
+ }
+
+ private function generateUid($length)
+ {
+ return substr(hash('md5', uniqid('', true)), 0, $length);
+ }
}
diff --git a/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php
index ea1d8978..684188f6 100644
--- a/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php
+++ b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php
@@ -16,7 +16,7 @@ namespace Monolog\Processor;
*
* @author Jordi Boggiano
*/
-class WebProcessor
+class WebProcessor implements ProcessorInterface
{
/**
* @var array|\ArrayAccess
diff --git a/vendor/monolog/monolog/src/Monolog/ResettableInterface.php b/vendor/monolog/monolog/src/Monolog/ResettableInterface.php
new file mode 100644
index 00000000..635bc77d
--- /dev/null
+++ b/vendor/monolog/monolog/src/Monolog/ResettableInterface.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+/**
+ * Handler or Processor implementing this interface will be reset when Logger::reset() is called.
+ *
+ * Resetting ends a log cycle gets them back to their initial state.
+ *
+ * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
+ * state, and getting it back to a state in which it can receive log records again.
+ *
+ * This is useful in case you want to avoid logs leaking between two requests or jobs when you
+ * have a long running process like a worker or an application server serving multiple requests
+ * in one process.
+ *
+ * @author Grégoire Pineau
+ */
+interface ResettableInterface
+{
+ public function reset();
+}
diff --git a/vendor/monolog/monolog/src/Monolog/SignalHandler.php b/vendor/monolog/monolog/src/Monolog/SignalHandler.php
new file mode 100644
index 00000000..d87018fe
--- /dev/null
+++ b/vendor/monolog/monolog/src/Monolog/SignalHandler.php
@@ -0,0 +1,115 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use ReflectionExtension;
+
+/**
+ * Monolog POSIX signal handler
+ *
+ * @author Robert Gust-Bardon
+ */
+class SignalHandler
+{
+ private $logger;
+
+ private $previousSignalHandler = array();
+ private $signalLevelMap = array();
+ private $signalRestartSyscalls = array();
+
+ public function __construct(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+
+ public function registerSignalHandler($signo, $level = LogLevel::CRITICAL, $callPrevious = true, $restartSyscalls = true, $async = true)
+ {
+ if (!extension_loaded('pcntl') || !function_exists('pcntl_signal')) {
+ return $this;
+ }
+
+ if ($callPrevious) {
+ if (function_exists('pcntl_signal_get_handler')) {
+ $handler = pcntl_signal_get_handler($signo);
+ if ($handler === false) {
+ return $this;
+ }
+ $this->previousSignalHandler[$signo] = $handler;
+ } else {
+ $this->previousSignalHandler[$signo] = true;
+ }
+ } else {
+ unset($this->previousSignalHandler[$signo]);
+ }
+ $this->signalLevelMap[$signo] = $level;
+ $this->signalRestartSyscalls[$signo] = $restartSyscalls;
+
+ if (function_exists('pcntl_async_signals') && $async !== null) {
+ pcntl_async_signals($async);
+ }
+
+ pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls);
+
+ return $this;
+ }
+
+ public function handleSignal($signo, array $siginfo = null)
+ {
+ static $signals = array();
+
+ if (!$signals && extension_loaded('pcntl')) {
+ $pcntl = new ReflectionExtension('pcntl');
+ $constants = $pcntl->getConstants();
+ if (!$constants) {
+ // HHVM 3.24.2 returns an empty array.
+ $constants = get_defined_constants(true);
+ $constants = $constants['Core'];
+ }
+ foreach ($constants as $name => $value) {
+ if (substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && is_int($value)) {
+ $signals[$value] = $name;
+ }
+ }
+ unset($constants);
+ }
+
+ $level = isset($this->signalLevelMap[$signo]) ? $this->signalLevelMap[$signo] : LogLevel::CRITICAL;
+ $signal = isset($signals[$signo]) ? $signals[$signo] : $signo;
+ $context = isset($siginfo) ? $siginfo : array();
+ $this->logger->log($level, sprintf('Program received signal %s', $signal), $context);
+
+ if (!isset($this->previousSignalHandler[$signo])) {
+ return;
+ }
+
+ if ($this->previousSignalHandler[$signo] === true || $this->previousSignalHandler[$signo] === SIG_DFL) {
+ if (extension_loaded('pcntl') && function_exists('pcntl_signal') && function_exists('pcntl_sigprocmask') && function_exists('pcntl_signal_dispatch')
+ && extension_loaded('posix') && function_exists('posix_getpid') && function_exists('posix_kill')) {
+ $restartSyscalls = isset($this->signalRestartSyscalls[$signo]) ? $this->signalRestartSyscalls[$signo] : true;
+ pcntl_signal($signo, SIG_DFL, $restartSyscalls);
+ pcntl_sigprocmask(SIG_UNBLOCK, array($signo), $oldset);
+ posix_kill(posix_getpid(), $signo);
+ pcntl_signal_dispatch();
+ pcntl_sigprocmask(SIG_SETMASK, $oldset);
+ pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls);
+ }
+ } elseif (is_callable($this->previousSignalHandler[$signo])) {
+ if (PHP_VERSION_ID >= 70100) {
+ $this->previousSignalHandler[$signo]($signo, $siginfo);
+ } else {
+ $this->previousSignalHandler[$signo]($signo);
+ }
+ }
+ }
+}
diff --git a/vendor/monolog/monolog/src/Monolog/Utils.php b/vendor/monolog/monolog/src/Monolog/Utils.php
new file mode 100644
index 00000000..180a159d
--- /dev/null
+++ b/vendor/monolog/monolog/src/Monolog/Utils.php
@@ -0,0 +1,159 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+class Utils
+{
+ /**
+ * @internal
+ */
+ public static function getClass($object)
+ {
+ $class = \get_class($object);
+
+ return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
+ }
+
+ /**
+ * Return the JSON representation of a value
+ *
+ * @param mixed $data
+ * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
+ * @param bool $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null
+ * @throws \RuntimeException if encoding fails and errors are not ignored
+ * @return string
+ */
+ public static function jsonEncode($data, $encodeFlags = null, $ignoreErrors = false)
+ {
+ if (null === $encodeFlags && version_compare(PHP_VERSION, '5.4.0', '>=')) {
+ $encodeFlags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
+ }
+
+ if ($ignoreErrors) {
+ $json = @json_encode($data, $encodeFlags);
+ if (false === $json) {
+ return 'null';
+ }
+
+ return $json;
+ }
+
+ $json = json_encode($data, $encodeFlags);
+ if (false === $json) {
+ $json = self::handleJsonError(json_last_error(), $data);
+ }
+
+ return $json;
+ }
+
+ /**
+ * Handle a json_encode failure.
+ *
+ * If the failure is due to invalid string encoding, try to clean the
+ * input and encode again. If the second encoding attempt fails, the
+ * inital error is not encoding related or the input can't be cleaned then
+ * raise a descriptive exception.
+ *
+ * @param int $code return code of json_last_error function
+ * @param mixed $data data that was meant to be encoded
+ * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
+ * @throws \RuntimeException if failure can't be corrected
+ * @return string JSON encoded data after error correction
+ */
+ public static function handleJsonError($code, $data, $encodeFlags = null)
+ {
+ if ($code !== JSON_ERROR_UTF8) {
+ self::throwEncodeError($code, $data);
+ }
+
+ if (is_string($data)) {
+ self::detectAndCleanUtf8($data);
+ } elseif (is_array($data)) {
+ array_walk_recursive($data, array('Monolog\Utils', 'detectAndCleanUtf8'));
+ } else {
+ self::throwEncodeError($code, $data);
+ }
+
+ if (null === $encodeFlags && version_compare(PHP_VERSION, '5.4.0', '>=')) {
+ $encodeFlags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
+ }
+
+ $json = json_encode($data, $encodeFlags);
+
+ if ($json === false) {
+ self::throwEncodeError(json_last_error(), $data);
+ }
+
+ return $json;
+ }
+
+ /**
+ * Throws an exception according to a given code with a customized message
+ *
+ * @param int $code return code of json_last_error function
+ * @param mixed $data data that was meant to be encoded
+ * @throws \RuntimeException
+ */
+ private static function throwEncodeError($code, $data)
+ {
+ switch ($code) {
+ case JSON_ERROR_DEPTH:
+ $msg = 'Maximum stack depth exceeded';
+ break;
+ case JSON_ERROR_STATE_MISMATCH:
+ $msg = 'Underflow or the modes mismatch';
+ break;
+ case JSON_ERROR_CTRL_CHAR:
+ $msg = 'Unexpected control character found';
+ break;
+ case JSON_ERROR_UTF8:
+ $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ break;
+ default:
+ $msg = 'Unknown error';
+ }
+
+ throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true));
+ }
+
+ /**
+ * Detect invalid UTF-8 string characters and convert to valid UTF-8.
+ *
+ * Valid UTF-8 input will be left unmodified, but strings containing
+ * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed
+ * original encoding of ISO-8859-15. This conversion may result in
+ * incorrect output if the actual encoding was not ISO-8859-15, but it
+ * will be clean UTF-8 output and will not rely on expensive and fragile
+ * detection algorithms.
+ *
+ * Function converts the input in place in the passed variable so that it
+ * can be used as a callback for array_walk_recursive.
+ *
+ * @param mixed &$data Input to check and convert if needed
+ * @private
+ */
+ public static function detectAndCleanUtf8(&$data)
+ {
+ if (is_string($data) && !preg_match('//u', $data)) {
+ $data = preg_replace_callback(
+ '/[\x80-\xFF]+/',
+ function ($m) { return utf8_encode($m[0]); },
+ $data
+ );
+ $data = str_replace(
+ array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'),
+ array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'),
+ $data
+ );
+ }
+ }
+}
diff --git a/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php
deleted file mode 100644
index a9a3f301..00000000
--- a/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php
+++ /dev/null
@@ -1,31 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-use Monolog\Handler\TestHandler;
-
-class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
-{
- public function testHandleError()
- {
- $logger = new Logger('test', array($handler = new TestHandler));
- $errHandler = new ErrorHandler($logger);
-
- $errHandler->registerErrorHandler(array(E_USER_NOTICE => Logger::EMERGENCY), false);
- trigger_error('Foo', E_USER_ERROR);
- $this->assertCount(1, $handler->getRecords());
- $this->assertTrue($handler->hasErrorRecords());
- trigger_error('Foo', E_USER_NOTICE);
- $this->assertCount(2, $handler->getRecords());
- $this->assertTrue($handler->hasEmergencyRecords());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php
deleted file mode 100644
index 71c42046..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php
+++ /dev/null
@@ -1,158 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @covers Monolog\Formatter\ChromePHPFormatter::format
- */
- public function testDefaultFormat()
- {
- $formatter = new ChromePHPFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('ip' => '127.0.0.1'),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'meh',
- array(
- 'message' => 'log',
- 'context' => array('from' => 'logger'),
- 'extra' => array('ip' => '127.0.0.1'),
- ),
- 'unknown',
- 'error',
- ),
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\ChromePHPFormatter::format
- */
- public function testFormatWithFileAndLine()
- {
- $formatter = new ChromePHPFormatter();
- $record = array(
- 'level' => Logger::CRITICAL,
- 'level_name' => 'CRITICAL',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'meh',
- array(
- 'message' => 'log',
- 'context' => array('from' => 'logger'),
- 'extra' => array('ip' => '127.0.0.1'),
- ),
- 'test : 14',
- 'error',
- ),
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\ChromePHPFormatter::format
- */
- public function testFormatWithoutContext()
- {
- $formatter = new ChromePHPFormatter();
- $record = array(
- 'level' => Logger::DEBUG,
- 'level_name' => 'DEBUG',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'meh',
- 'log',
- 'unknown',
- 'log',
- ),
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\ChromePHPFormatter::formatBatch
- */
- public function testBatchFormatThrowException()
- {
- $formatter = new ChromePHPFormatter();
- $records = array(
- array(
- 'level' => Logger::INFO,
- 'level_name' => 'INFO',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- ),
- array(
- 'level' => Logger::WARNING,
- 'level_name' => 'WARNING',
- 'channel' => 'foo',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log2',
- ),
- );
-
- $this->assertEquals(
- array(
- array(
- 'meh',
- 'log',
- 'unknown',
- 'info',
- ),
- array(
- 'foo',
- 'log2',
- 'unknown',
- 'warn',
- ),
- ),
- $formatter->formatBatch($records)
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php
deleted file mode 100644
index 90cc48dd..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-class ElasticaFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function setUp()
- {
- if (!class_exists("Elastica\Document")) {
- $this->markTestSkipped("ruflin/elastica not installed");
- }
- }
-
- /**
- * @covers Monolog\Formatter\ElasticaFormatter::__construct
- * @covers Monolog\Formatter\ElasticaFormatter::format
- * @covers Monolog\Formatter\ElasticaFormatter::getDocument
- */
- public function testFormat()
- {
- // test log message
- $msg = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- // expected values
- $expected = $msg;
- $expected['datetime'] = '1970-01-01T00:00:00.000000+00:00';
- $expected['context'] = array(
- 'class' => '[object] (stdClass: {})',
- 'foo' => 7,
- 0 => 'bar',
- );
-
- // format log message
- $formatter = new ElasticaFormatter('my_index', 'doc_type');
- $doc = $formatter->format($msg);
- $this->assertInstanceOf('Elastica\Document', $doc);
-
- // Document parameters
- $params = $doc->getParams();
- $this->assertEquals('my_index', $params['_index']);
- $this->assertEquals('doc_type', $params['_type']);
-
- // Document data values
- $data = $doc->getData();
- foreach (array_keys($expected) as $key) {
- $this->assertEquals($expected[$key], $data[$key]);
- }
- }
-
- /**
- * @covers Monolog\Formatter\ElasticaFormatter::getIndex
- * @covers Monolog\Formatter\ElasticaFormatter::getType
- */
- public function testGetters()
- {
- $formatter = new ElasticaFormatter('my_index', 'doc_type');
- $this->assertEquals('my_index', $formatter->getIndex());
- $this->assertEquals('doc_type', $formatter->getType());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php
deleted file mode 100644
index 1b2fd97a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php
+++ /dev/null
@@ -1,55 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class FlowdockFormatterTest extends TestCase
-{
- /**
- * @covers Monolog\Formatter\FlowdockFormatter::format
- */
- public function testFormat()
- {
- $formatter = new FlowdockFormatter('test_source', 'source@test.com');
- $record = $this->getRecord();
-
- $expected = array(
- 'source' => 'test_source',
- 'from_address' => 'source@test.com',
- 'subject' => 'in test_source: WARNING - test',
- 'content' => 'test',
- 'tags' => array('#logs', '#warning', '#test'),
- 'project' => 'test_source',
- );
- $formatted = $formatter->format($record);
-
- $this->assertEquals($expected, $formatted['flowdock']);
- }
-
- /**
- * @ covers Monolog\Formatter\FlowdockFormatter::formatBatch
- */
- public function testFormatBatch()
- {
- $formatter = new FlowdockFormatter('test_source', 'source@test.com');
- $records = array(
- $this->getRecord(Logger::WARNING),
- $this->getRecord(Logger::DEBUG),
- );
- $formatted = $formatter->formatBatch($records);
-
- $this->assertArrayHasKey('flowdock', $formatted[0]);
- $this->assertArrayHasKey('flowdock', $formatted[1]);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/FluentdFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/FluentdFormatterTest.php
deleted file mode 100644
index 622b2bae..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/FluentdFormatterTest.php
+++ /dev/null
@@ -1,62 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class FluentdFormatterTest extends TestCase
-{
- /**
- * @covers Monolog\Formatter\FluentdFormatter::__construct
- * @covers Monolog\Formatter\FluentdFormatter::isUsingLevelsInTag
- */
- public function testConstruct()
- {
- $formatter = new FluentdFormatter();
- $this->assertEquals(false, $formatter->isUsingLevelsInTag());
- $formatter = new FluentdFormatter(false);
- $this->assertEquals(false, $formatter->isUsingLevelsInTag());
- $formatter = new FluentdFormatter(true);
- $this->assertEquals(true, $formatter->isUsingLevelsInTag());
- }
-
- /**
- * @covers Monolog\Formatter\FluentdFormatter::format
- */
- public function testFormat()
- {
- $record = $this->getRecord(Logger::WARNING);
- $record['datetime'] = new \DateTime("@0");
-
- $formatter = new FluentdFormatter();
- $this->assertEquals(
- '["test",0,{"message":"test","extra":[],"level":300,"level_name":"WARNING"}]',
- $formatter->format($record)
- );
- }
-
- /**
- * @covers Monolog\Formatter\FluentdFormatter::format
- */
- public function testFormatWithTag()
- {
- $record = $this->getRecord(Logger::ERROR);
- $record['datetime'] = new \DateTime("@0");
-
- $formatter = new FluentdFormatter(true);
- $this->assertEquals(
- '["test.error",0,{"message":"test","extra":[]}]',
- $formatter->format($record)
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php
deleted file mode 100644
index 4a247616..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php
+++ /dev/null
@@ -1,258 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function setUp()
- {
- if (!class_exists('\Gelf\Message')) {
- $this->markTestSkipped("graylog2/gelf-php or mlehner/gelf-php is not installed");
- }
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- */
- public function testDefaultFormatter()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
- $this->assertEquals(0, $message->getTimestamp());
- $this->assertEquals('log', $message->getShortMessage());
- $this->assertEquals('meh', $message->getFacility());
- $this->assertEquals(null, $message->getLine());
- $this->assertEquals(null, $message->getFile());
- $this->assertEquals($this->isLegacy() ? 3 : 'error', $message->getLevel());
- $this->assertNotEmpty($message->getHost());
-
- $formatter = new GelfMessageFormatter('mysystem');
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
- $this->assertEquals('mysystem', $message->getHost());
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- */
- public function testFormatWithFileAndLine()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('file' => 'test', 'line' => 14),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
- $this->assertEquals('test', $message->getFile());
- $this->assertEquals(14, $message->getLine());
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- * @expectedException InvalidArgumentException
- */
- public function testFormatInvalidFails()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- );
-
- $formatter->format($record);
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- */
- public function testFormatWithContext()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
-
- $message_array = $message->toArray();
-
- $this->assertArrayHasKey('_ctxt_from', $message_array);
- $this->assertEquals('logger', $message_array['_ctxt_from']);
-
- // Test with extraPrefix
- $formatter = new GelfMessageFormatter(null, null, 'CTX');
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
-
- $message_array = $message->toArray();
-
- $this->assertArrayHasKey('_CTXfrom', $message_array);
- $this->assertEquals('logger', $message_array['_CTXfrom']);
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- */
- public function testFormatWithContextContainingException()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger', 'exception' => array(
- 'class' => '\Exception',
- 'file' => '/some/file/in/dir.php:56',
- 'trace' => array('/some/file/1.php:23', '/some/file/2.php:3'),
- )),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
-
- $this->assertEquals("/some/file/in/dir.php", $message->getFile());
- $this->assertEquals("56", $message->getLine());
- }
-
- /**
- * @covers Monolog\Formatter\GelfMessageFormatter::format
- */
- public function testFormatWithExtra()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
-
- $message_array = $message->toArray();
-
- $this->assertArrayHasKey('_key', $message_array);
- $this->assertEquals('pair', $message_array['_key']);
-
- // Test with extraPrefix
- $formatter = new GelfMessageFormatter(null, 'EXT');
- $message = $formatter->format($record);
-
- $this->assertInstanceOf('Gelf\Message', $message);
-
- $message_array = $message->toArray();
-
- $this->assertArrayHasKey('_EXTkey', $message_array);
- $this->assertEquals('pair', $message_array['_EXTkey']);
- }
-
- public function testFormatWithLargeData()
- {
- $formatter = new GelfMessageFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('exception' => str_repeat(' ', 32767)),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => str_repeat(' ', 32767)),
- 'message' => 'log'
- );
- $message = $formatter->format($record);
- $messageArray = $message->toArray();
-
- // 200 for padding + metadata
- $length = 200;
-
- foreach ($messageArray as $key => $value) {
- if (!in_array($key, array('level', 'timestamp'))) {
- $length += strlen($value);
- }
- }
-
- $this->assertLessThanOrEqual(65792, $length, 'The message length is no longer than the maximum allowed length');
- }
-
- public function testFormatWithUnlimitedLength()
- {
- $formatter = new GelfMessageFormatter('LONG_SYSTEM_NAME', null, 'ctxt_', PHP_INT_MAX);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('exception' => str_repeat(' ', 32767 * 2)),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => str_repeat(' ', 32767 * 2)),
- 'message' => 'log'
- );
- $message = $formatter->format($record);
- $messageArray = $message->toArray();
-
- // 200 for padding + metadata
- $length = 200;
-
- foreach ($messageArray as $key => $value) {
- if (!in_array($key, array('level', 'timestamp'))) {
- $length += strlen($value);
- }
- }
-
- $this->assertGreaterThanOrEqual(131289, $length, 'The message should not be truncated');
- }
-
- private function isLegacy()
- {
- return interface_exists('\Gelf\IMessagePublisher');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php
deleted file mode 100644
index c9445f36..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php
+++ /dev/null
@@ -1,183 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class JsonFormatterTest extends TestCase
-{
- /**
- * @covers Monolog\Formatter\JsonFormatter::__construct
- * @covers Monolog\Formatter\JsonFormatter::getBatchMode
- * @covers Monolog\Formatter\JsonFormatter::isAppendingNewlines
- */
- public function testConstruct()
- {
- $formatter = new JsonFormatter();
- $this->assertEquals(JsonFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
- $this->assertEquals(true, $formatter->isAppendingNewlines());
- $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES, false);
- $this->assertEquals(JsonFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
- $this->assertEquals(false, $formatter->isAppendingNewlines());
- }
-
- /**
- * @covers Monolog\Formatter\JsonFormatter::format
- */
- public function testFormat()
- {
- $formatter = new JsonFormatter();
- $record = $this->getRecord();
- $this->assertEquals(json_encode($record)."\n", $formatter->format($record));
-
- $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
- $record = $this->getRecord();
- $this->assertEquals(json_encode($record), $formatter->format($record));
- }
-
- /**
- * @covers Monolog\Formatter\JsonFormatter::formatBatch
- * @covers Monolog\Formatter\JsonFormatter::formatBatchJson
- */
- public function testFormatBatch()
- {
- $formatter = new JsonFormatter();
- $records = array(
- $this->getRecord(Logger::WARNING),
- $this->getRecord(Logger::DEBUG),
- );
- $this->assertEquals(json_encode($records), $formatter->formatBatch($records));
- }
-
- /**
- * @covers Monolog\Formatter\JsonFormatter::formatBatch
- * @covers Monolog\Formatter\JsonFormatter::formatBatchNewlines
- */
- public function testFormatBatchNewlines()
- {
- $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES);
- $records = $expected = array(
- $this->getRecord(Logger::WARNING),
- $this->getRecord(Logger::DEBUG),
- );
- array_walk($expected, function (&$value, $key) {
- $value = json_encode($value);
- });
- $this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records));
- }
-
- public function testDefFormatWithException()
- {
- $formatter = new JsonFormatter();
- $exception = new \RuntimeException('Foo');
- $formattedException = $this->formatException($exception);
-
- $message = $this->formatRecordWithExceptionInContext($formatter, $exception);
-
- $this->assertContextContainsFormattedException($formattedException, $message);
- }
-
- public function testDefFormatWithPreviousException()
- {
- $formatter = new JsonFormatter();
- $exception = new \RuntimeException('Foo', 0, new \LogicException('Wut?'));
- $formattedPrevException = $this->formatException($exception->getPrevious());
- $formattedException = $this->formatException($exception, $formattedPrevException);
-
- $message = $this->formatRecordWithExceptionInContext($formatter, $exception);
-
- $this->assertContextContainsFormattedException($formattedException, $message);
- }
-
- public function testDefFormatWithThrowable()
- {
- if (!class_exists('Error') || !is_subclass_of('Error', 'Throwable')) {
- $this->markTestSkipped('Requires PHP >=7');
- }
-
- $formatter = new JsonFormatter();
- $throwable = new \Error('Foo');
- $formattedThrowable = $this->formatException($throwable);
-
- $message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
-
- $this->assertContextContainsFormattedException($formattedThrowable, $message);
- }
-
- /**
- * @param string $expected
- * @param string $actual
- *
- * @internal param string $exception
- */
- private function assertContextContainsFormattedException($expected, $actual)
- {
- $this->assertEquals(
- '{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":[],"message":"foobar"}'."\n",
- $actual
- );
- }
-
- /**
- * @param JsonFormatter $formatter
- * @param \Exception|\Throwable $exception
- *
- * @return string
- */
- private function formatRecordWithExceptionInContext(JsonFormatter $formatter, $exception)
- {
- $message = $formatter->format(array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'core',
- 'context' => array('exception' => $exception),
- 'datetime' => null,
- 'extra' => array(),
- 'message' => 'foobar',
- ));
- return $message;
- }
-
- /**
- * @param \Exception|\Throwable $exception
- *
- * @return string
- */
- private function formatExceptionFilePathWithLine($exception)
- {
- $options = 0;
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
- $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
- }
- $path = substr(json_encode($exception->getFile(), $options), 1, -1);
- return $path . ':' . $exception->getLine();
- }
-
- /**
- * @param \Exception|\Throwable $exception
- *
- * @param null|string $previous
- *
- * @return string
- */
- private function formatException($exception, $previous = null)
- {
- $formattedException =
- '{"class":"' . get_class($exception) .
- '","message":"' . $exception->getMessage() .
- '","code":' . $exception->getCode() .
- ',"file":"' . $this->formatExceptionFilePathWithLine($exception) .
- ($previous ? '","previous":' . $previous : '"') .
- '}';
- return $formattedException;
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php
deleted file mode 100644
index 310d93ca..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php
+++ /dev/null
@@ -1,222 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-/**
- * @covers Monolog\Formatter\LineFormatter
- */
-class LineFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function testDefFormatWithString()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'WARNING',
- 'channel' => 'log',
- 'context' => array(),
- 'message' => 'foo',
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ));
- $this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
- }
-
- public function testDefFormatWithArrayContext()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'message' => 'foo',
- 'datetime' => new \DateTime,
- 'extra' => array(),
- 'context' => array(
- 'foo' => 'bar',
- 'baz' => 'qux',
- 'bool' => false,
- 'null' => null,
- ),
- ));
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foo {"foo":"bar","baz":"qux","bool":false,"null":null} []'."\n", $message);
- }
-
- public function testDefFormatExtras()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array('ip' => '127.0.0.1'),
- 'message' => 'log',
- ));
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] {"ip":"127.0.0.1"}'."\n", $message);
- }
-
- public function testFormatExtras()
- {
- $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra.file% %extra%\n", 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array('ip' => '127.0.0.1', 'file' => 'test'),
- 'message' => 'log',
- ));
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] test {"ip":"127.0.0.1"}'."\n", $message);
- }
-
- public function testContextAndExtraOptionallyNotShownIfEmpty()
- {
- $formatter = new LineFormatter(null, 'Y-m-d', false, true);
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- 'message' => 'log',
- ));
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log '."\n", $message);
- }
-
- public function testContextAndExtraReplacement()
- {
- $formatter = new LineFormatter('%context.foo% => %extra.foo%');
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('foo' => 'bar'),
- 'datetime' => new \DateTime,
- 'extra' => array('foo' => 'xbar'),
- 'message' => 'log',
- ));
- $this->assertEquals('bar => xbar', $message);
- }
-
- public function testDefFormatWithObject()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
- 'message' => 'foobar',
- ));
-
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: bar)","baz":[],"res":"[resource] (stream)"}'."\n", $message);
- }
-
- public function testDefFormatWithException()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'core',
- 'context' => array('exception' => new \RuntimeException('Foo')),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- 'message' => 'foobar',
- ));
-
- $path = str_replace('\\/', '/', json_encode(__FILE__));
-
- $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).')"} []'."\n", $message);
- }
-
- public function testDefFormatWithPreviousException()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $previous = new \LogicException('Wut?');
- $message = $formatter->format(array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'core',
- 'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- 'message' => 'foobar',
- ));
-
- $path = str_replace('\\/', '/', json_encode(__FILE__));
-
- $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).', LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message);
- }
-
- public function testBatchFormat()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->formatBatch(array(
- array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'test',
- 'message' => 'bar',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ),
- array(
- 'level_name' => 'WARNING',
- 'channel' => 'log',
- 'message' => 'foo',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ),
- ));
- $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
- }
-
- public function testFormatShouldStripInlineLineBreaks()
- {
- $formatter = new LineFormatter(null, 'Y-m-d');
- $message = $formatter->format(
- array(
- 'message' => "foo\nbar",
- 'context' => array(),
- 'extra' => array(),
- )
- );
-
- $this->assertRegExp('/foo bar/', $message);
- }
-
- public function testFormatShouldNotStripInlineLineBreaksWhenFlagIsSet()
- {
- $formatter = new LineFormatter(null, 'Y-m-d', true);
- $message = $formatter->format(
- array(
- 'message' => "foo\nbar",
- 'context' => array(),
- 'extra' => array(),
- )
- );
-
- $this->assertRegExp('/foo\nbar/', $message);
- }
-}
-
-class TestFoo
-{
- public $foo = 'foo';
-}
-
-class TestBar
-{
- public function __toString()
- {
- return 'bar';
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php
deleted file mode 100644
index 6d59b3f3..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\TestCase;
-
-class LogglyFormatterTest extends TestCase
-{
- /**
- * @covers Monolog\Formatter\LogglyFormatter::__construct
- */
- public function testConstruct()
- {
- $formatter = new LogglyFormatter();
- $this->assertEquals(LogglyFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
- $formatter = new LogglyFormatter(LogglyFormatter::BATCH_MODE_JSON);
- $this->assertEquals(LogglyFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
- }
-
- /**
- * @covers Monolog\Formatter\LogglyFormatter::format
- */
- public function testFormat()
- {
- $formatter = new LogglyFormatter();
- $record = $this->getRecord();
- $formatted_decoded = json_decode($formatter->format($record), true);
- $this->assertArrayHasKey("timestamp", $formatted_decoded);
- $this->assertEquals(new \DateTime($formatted_decoded["timestamp"]), $record["datetime"]);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php
deleted file mode 100644
index 9f6b1cc4..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php
+++ /dev/null
@@ -1,333 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-class LogstashFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function tearDown()
- {
- \PHPUnit_Framework_Error_Warning::$enabled = true;
-
- return parent::tearDown();
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testDefaultFormatter()
- {
- $formatter = new LogstashFormatter('test', 'hostname');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
- $this->assertEquals('log', $message['@message']);
- $this->assertEquals('meh', $message['@fields']['channel']);
- $this->assertContains('meh', $message['@tags']);
- $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
- $this->assertEquals('test', $message['@type']);
- $this->assertEquals('hostname', $message['@source']);
-
- $formatter = new LogstashFormatter('mysystem');
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals('mysystem', $message['@type']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithFileAndLine()
- {
- $formatter = new LogstashFormatter('test');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('file' => 'test', 'line' => 14),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals('test', $message['@fields']['file']);
- $this->assertEquals(14, $message['@fields']['line']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithContext()
- {
- $formatter = new LogstashFormatter('test');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $message_array = $message['@fields'];
-
- $this->assertArrayHasKey('ctxt_from', $message_array);
- $this->assertEquals('logger', $message_array['ctxt_from']);
-
- // Test with extraPrefix
- $formatter = new LogstashFormatter('test', null, null, 'CTX');
- $message = json_decode($formatter->format($record), true);
-
- $message_array = $message['@fields'];
-
- $this->assertArrayHasKey('CTXfrom', $message_array);
- $this->assertEquals('logger', $message_array['CTXfrom']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithExtra()
- {
- $formatter = new LogstashFormatter('test');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $message_array = $message['@fields'];
-
- $this->assertArrayHasKey('key', $message_array);
- $this->assertEquals('pair', $message_array['key']);
-
- // Test with extraPrefix
- $formatter = new LogstashFormatter('test', null, 'EXT');
- $message = json_decode($formatter->format($record), true);
-
- $message_array = $message['@fields'];
-
- $this->assertArrayHasKey('EXTkey', $message_array);
- $this->assertEquals('pair', $message_array['EXTkey']);
- }
-
- public function testFormatWithApplicationName()
- {
- $formatter = new LogstashFormatter('app', 'test');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('@type', $message);
- $this->assertEquals('app', $message['@type']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testDefaultFormatterV1()
- {
- $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
- $this->assertEquals("1", $message['@version']);
- $this->assertEquals('log', $message['message']);
- $this->assertEquals('meh', $message['channel']);
- $this->assertEquals('ERROR', $message['level']);
- $this->assertEquals('test', $message['type']);
- $this->assertEquals('hostname', $message['host']);
-
- $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1);
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals('mysystem', $message['type']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithFileAndLineV1()
- {
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('file' => 'test', 'line' => 14),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals('test', $message['file']);
- $this->assertEquals(14, $message['line']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithContextV1()
- {
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('ctxt_from', $message);
- $this->assertEquals('logger', $message['ctxt_from']);
-
- // Test with extraPrefix
- $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1);
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('CTXfrom', $message);
- $this->assertEquals('logger', $message['CTXfrom']);
- }
-
- /**
- * @covers Monolog\Formatter\LogstashFormatter::format
- */
- public function testFormatWithExtraV1()
- {
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('key', $message);
- $this->assertEquals('pair', $message['key']);
-
- // Test with extraPrefix
- $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1);
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('EXTkey', $message);
- $this->assertEquals('pair', $message['EXTkey']);
- }
-
- public function testFormatWithApplicationNameV1()
- {
- $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1);
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('key' => 'pair'),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertArrayHasKey('type', $message);
- $this->assertEquals('app', $message['type']);
- }
-
- public function testFormatWithLatin9Data()
- {
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
- // Ignore the warning that will be emitted by PHP <5.5.0
- \PHPUnit_Framework_Error_Warning::$enabled = false;
- }
- $formatter = new LogstashFormatter('test', 'hostname');
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => '¯\_(ツ)_/¯',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(
- 'user_agent' => "\xD6WN; FBCR/OrangeEspa\xF1a; Vers\xE3o/4.0; F\xE4rist",
- ),
- 'message' => 'log',
- );
-
- $message = json_decode($formatter->format($record), true);
-
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
- $this->assertEquals('log', $message['@message']);
- $this->assertEquals('¯\_(ツ)_/¯', $message['@fields']['channel']);
- $this->assertContains('¯\_(ツ)_/¯', $message['@tags']);
- $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
- $this->assertEquals('test', $message['@type']);
- $this->assertEquals('hostname', $message['@source']);
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
- $this->assertEquals('ÖWN; FBCR/OrangeEspaña; Versão/4.0; Färist', $message['@fields']['user_agent']);
- } else {
- // PHP <5.5 does not return false for an element encoding failure,
- // instead it emits a warning (possibly) and nulls the value.
- $this->assertEquals(null, $message['@fields']['user_agent']);
- }
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php
deleted file mode 100644
index 52e699e0..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php
+++ /dev/null
@@ -1,262 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-/**
- * @author Florian Plattner
- */
-class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function setUp()
- {
- if (!class_exists('MongoDate')) {
- $this->markTestSkipped('mongo extension not installed');
- }
- }
-
- public function constructArgumentProvider()
- {
- return array(
- array(1, true, 1, true),
- array(0, false, 0, false),
- );
- }
-
- /**
- * @param $traceDepth
- * @param $traceAsString
- * @param $expectedTraceDepth
- * @param $expectedTraceAsString
- *
- * @dataProvider constructArgumentProvider
- */
- public function testConstruct($traceDepth, $traceAsString, $expectedTraceDepth, $expectedTraceAsString)
- {
- $formatter = new MongoDBFormatter($traceDepth, $traceAsString);
-
- $reflTrace = new \ReflectionProperty($formatter, 'exceptionTraceAsString');
- $reflTrace->setAccessible(true);
- $this->assertEquals($expectedTraceAsString, $reflTrace->getValue($formatter));
-
- $reflDepth = new\ReflectionProperty($formatter, 'maxNestingLevel');
- $reflDepth->setAccessible(true);
- $this->assertEquals($expectedTraceDepth, $reflDepth->getValue($formatter));
- }
-
- public function testSimpleFormat()
- {
- $record = array(
- 'message' => 'some log message',
- 'context' => array(),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter();
- $formattedRecord = $formatter->format($record);
-
- $this->assertCount(7, $formattedRecord);
- $this->assertEquals('some log message', $formattedRecord['message']);
- $this->assertEquals(array(), $formattedRecord['context']);
- $this->assertEquals(Logger::WARNING, $formattedRecord['level']);
- $this->assertEquals(Logger::getLevelName(Logger::WARNING), $formattedRecord['level_name']);
- $this->assertEquals('test', $formattedRecord['channel']);
- $this->assertInstanceOf('\MongoDate', $formattedRecord['datetime']);
- $this->assertEquals('0.00000000 1391212800', $formattedRecord['datetime']->__toString());
- $this->assertEquals(array(), $formattedRecord['extra']);
- }
-
- public function testRecursiveFormat()
- {
- $someObject = new \stdClass();
- $someObject->foo = 'something';
- $someObject->bar = 'stuff';
-
- $record = array(
- 'message' => 'some log message',
- 'context' => array(
- 'stuff' => new \DateTime('2014-02-01 02:31:33'),
- 'some_object' => $someObject,
- 'context_string' => 'some string',
- 'context_int' => 123456,
- 'except' => new \Exception('exception message', 987),
- ),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter();
- $formattedRecord = $formatter->format($record);
-
- $this->assertCount(5, $formattedRecord['context']);
- $this->assertInstanceOf('\MongoDate', $formattedRecord['context']['stuff']);
- $this->assertEquals('0.00000000 1391221893', $formattedRecord['context']['stuff']->__toString());
- $this->assertEquals(
- array(
- 'foo' => 'something',
- 'bar' => 'stuff',
- 'class' => 'stdClass',
- ),
- $formattedRecord['context']['some_object']
- );
- $this->assertEquals('some string', $formattedRecord['context']['context_string']);
- $this->assertEquals(123456, $formattedRecord['context']['context_int']);
-
- $this->assertCount(5, $formattedRecord['context']['except']);
- $this->assertEquals('exception message', $formattedRecord['context']['except']['message']);
- $this->assertEquals(987, $formattedRecord['context']['except']['code']);
- $this->assertInternalType('string', $formattedRecord['context']['except']['file']);
- $this->assertInternalType('integer', $formattedRecord['context']['except']['code']);
- $this->assertInternalType('string', $formattedRecord['context']['except']['trace']);
- $this->assertEquals('Exception', $formattedRecord['context']['except']['class']);
- }
-
- public function testFormatDepthArray()
- {
- $record = array(
- 'message' => 'some log message',
- 'context' => array(
- 'nest2' => array(
- 'property' => 'anything',
- 'nest3' => array(
- 'nest4' => 'value',
- 'property' => 'nothing',
- ),
- ),
- ),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter(2);
- $formattedResult = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'nest2' => array(
- 'property' => 'anything',
- 'nest3' => '[...]',
- ),
- ),
- $formattedResult['context']
- );
- }
-
- public function testFormatDepthArrayInfiniteNesting()
- {
- $record = array(
- 'message' => 'some log message',
- 'context' => array(
- 'nest2' => array(
- 'property' => 'something',
- 'nest3' => array(
- 'property' => 'anything',
- 'nest4' => array(
- 'property' => 'nothing',
- ),
- ),
- ),
- ),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter(0);
- $formattedResult = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'nest2' => array(
- 'property' => 'something',
- 'nest3' => array(
- 'property' => 'anything',
- 'nest4' => array(
- 'property' => 'nothing',
- ),
- ),
- ),
- ),
- $formattedResult['context']
- );
- }
-
- public function testFormatDepthObjects()
- {
- $someObject = new \stdClass();
- $someObject->property = 'anything';
- $someObject->nest3 = new \stdClass();
- $someObject->nest3->property = 'nothing';
- $someObject->nest3->nest4 = 'invisible';
-
- $record = array(
- 'message' => 'some log message',
- 'context' => array(
- 'nest2' => $someObject,
- ),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter(2, true);
- $formattedResult = $formatter->format($record);
-
- $this->assertEquals(
- array(
- 'nest2' => array(
- 'property' => 'anything',
- 'nest3' => '[...]',
- 'class' => 'stdClass',
- ),
- ),
- $formattedResult['context']
- );
- }
-
- public function testFormatDepthException()
- {
- $record = array(
- 'message' => 'some log message',
- 'context' => array(
- 'nest2' => new \Exception('exception message', 987),
- ),
- 'level' => Logger::WARNING,
- 'level_name' => Logger::getLevelName(Logger::WARNING),
- 'channel' => 'test',
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
- 'extra' => array(),
- );
-
- $formatter = new MongoDBFormatter(2, false);
- $formattedRecord = $formatter->format($record);
-
- $this->assertEquals('exception message', $formattedRecord['context']['nest2']['message']);
- $this->assertEquals(987, $formattedRecord['context']['nest2']['code']);
- $this->assertEquals('[...]', $formattedRecord['context']['nest2']['trace']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php
deleted file mode 100644
index 57bcdf98..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php
+++ /dev/null
@@ -1,423 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-/**
- * @covers Monolog\Formatter\NormalizerFormatter
- */
-class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase
-{
- public function tearDown()
- {
- \PHPUnit_Framework_Error_Warning::$enabled = true;
-
- return parent::tearDown();
- }
-
- public function testFormat()
- {
- $formatter = new NormalizerFormatter('Y-m-d');
- $formatted = $formatter->format(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'message' => 'foo',
- 'datetime' => new \DateTime,
- 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
- 'context' => array(
- 'foo' => 'bar',
- 'baz' => 'qux',
- 'inf' => INF,
- '-inf' => -INF,
- 'nan' => acos(4),
- ),
- ));
-
- $this->assertEquals(array(
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'message' => 'foo',
- 'datetime' => date('Y-m-d'),
- 'extra' => array(
- 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})',
- 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)',
- 'baz' => array(),
- 'res' => '[resource] (stream)',
- ),
- 'context' => array(
- 'foo' => 'bar',
- 'baz' => 'qux',
- 'inf' => 'INF',
- '-inf' => '-INF',
- 'nan' => 'NaN',
- ),
- ), $formatted);
- }
-
- public function testFormatExceptions()
- {
- $formatter = new NormalizerFormatter('Y-m-d');
- $e = new \LogicException('bar');
- $e2 = new \RuntimeException('foo', 0, $e);
- $formatted = $formatter->format(array(
- 'exception' => $e2,
- ));
-
- $this->assertGreaterThan(5, count($formatted['exception']['trace']));
- $this->assertTrue(isset($formatted['exception']['previous']));
- unset($formatted['exception']['trace'], $formatted['exception']['previous']);
-
- $this->assertEquals(array(
- 'exception' => array(
- 'class' => get_class($e2),
- 'message' => $e2->getMessage(),
- 'code' => $e2->getCode(),
- 'file' => $e2->getFile().':'.$e2->getLine(),
- ),
- ), $formatted);
- }
-
- public function testFormatSoapFaultException()
- {
- if (!class_exists('SoapFault')) {
- $this->markTestSkipped('Requires the soap extension');
- }
-
- $formatter = new NormalizerFormatter('Y-m-d');
- $e = new \SoapFault('foo', 'bar', 'hello', 'world');
- $formatted = $formatter->format(array(
- 'exception' => $e,
- ));
-
- unset($formatted['exception']['trace']);
-
- $this->assertEquals(array(
- 'exception' => array(
- 'class' => 'SoapFault',
- 'message' => 'bar',
- 'code' => 0,
- 'file' => $e->getFile().':'.$e->getLine(),
- 'faultcode' => 'foo',
- 'faultactor' => 'hello',
- 'detail' => 'world',
- ),
- ), $formatted);
- }
-
- public function testFormatToStringExceptionHandle()
- {
- $formatter = new NormalizerFormatter('Y-m-d');
- $this->setExpectedException('RuntimeException', 'Could not convert to string');
- $formatter->format(array(
- 'myObject' => new TestToStringError(),
- ));
- }
-
- public function testBatchFormat()
- {
- $formatter = new NormalizerFormatter('Y-m-d');
- $formatted = $formatter->formatBatch(array(
- array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'test',
- 'message' => 'bar',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ),
- array(
- 'level_name' => 'WARNING',
- 'channel' => 'log',
- 'message' => 'foo',
- 'context' => array(),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ),
- ));
- $this->assertEquals(array(
- array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'test',
- 'message' => 'bar',
- 'context' => array(),
- 'datetime' => date('Y-m-d'),
- 'extra' => array(),
- ),
- array(
- 'level_name' => 'WARNING',
- 'channel' => 'log',
- 'message' => 'foo',
- 'context' => array(),
- 'datetime' => date('Y-m-d'),
- 'extra' => array(),
- ),
- ), $formatted);
- }
-
- /**
- * Test issue #137
- */
- public function testIgnoresRecursiveObjectReferences()
- {
- // set up the recursion
- $foo = new \stdClass();
- $bar = new \stdClass();
-
- $foo->bar = $bar;
- $bar->foo = $foo;
-
- // set an error handler to assert that the error is not raised anymore
- $that = $this;
- set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
- if (error_reporting() & $level) {
- restore_error_handler();
- $that->fail("$message should not be raised");
- }
- });
-
- $formatter = new NormalizerFormatter();
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
- $reflMethod->setAccessible(true);
- $res = $reflMethod->invoke($formatter, array($foo, $bar), true);
-
- restore_error_handler();
-
- $this->assertEquals(@json_encode(array($foo, $bar)), $res);
- }
-
- public function testIgnoresInvalidTypes()
- {
- // set up the recursion
- $resource = fopen(__FILE__, 'r');
-
- // set an error handler to assert that the error is not raised anymore
- $that = $this;
- set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
- if (error_reporting() & $level) {
- restore_error_handler();
- $that->fail("$message should not be raised");
- }
- });
-
- $formatter = new NormalizerFormatter();
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
- $reflMethod->setAccessible(true);
- $res = $reflMethod->invoke($formatter, array($resource), true);
-
- restore_error_handler();
-
- $this->assertEquals(@json_encode(array($resource)), $res);
- }
-
- public function testNormalizeHandleLargeArrays()
- {
- $formatter = new NormalizerFormatter();
- $largeArray = range(1, 2000);
-
- $res = $formatter->format(array(
- 'level_name' => 'CRITICAL',
- 'channel' => 'test',
- 'message' => 'bar',
- 'context' => array($largeArray),
- 'datetime' => new \DateTime,
- 'extra' => array(),
- ));
-
- $this->assertCount(1000, $res['context'][0]);
- $this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']);
- }
-
- /**
- * @expectedException RuntimeException
- */
- public function testThrowsOnInvalidEncoding()
- {
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
- // Ignore the warning that will be emitted by PHP <5.5.0
- \PHPUnit_Framework_Error_Warning::$enabled = false;
- }
- $formatter = new NormalizerFormatter();
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
- $reflMethod->setAccessible(true);
-
- // send an invalid unicode sequence as a object that can't be cleaned
- $record = new \stdClass;
- $record->message = "\xB1\x31";
- $res = $reflMethod->invoke($formatter, $record);
- if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') {
- throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely');
- }
- }
-
- public function testConvertsInvalidEncodingAsLatin9()
- {
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
- // Ignore the warning that will be emitted by PHP <5.5.0
- \PHPUnit_Framework_Error_Warning::$enabled = false;
- }
- $formatter = new NormalizerFormatter();
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
- $reflMethod->setAccessible(true);
-
- $res = $reflMethod->invoke($formatter, array('message' => "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE"));
-
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
- $this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res);
- } else {
- // PHP <5.5 does not return false for an element encoding failure,
- // instead it emits a warning (possibly) and nulls the value.
- $this->assertSame('{"message":null}', $res);
- }
- }
-
- /**
- * @param mixed $in Input
- * @param mixed $expect Expected output
- * @covers Monolog\Formatter\NormalizerFormatter::detectAndCleanUtf8
- * @dataProvider providesDetectAndCleanUtf8
- */
- public function testDetectAndCleanUtf8($in, $expect)
- {
- $formatter = new NormalizerFormatter();
- $formatter->detectAndCleanUtf8($in);
- $this->assertSame($expect, $in);
- }
-
- public function providesDetectAndCleanUtf8()
- {
- $obj = new \stdClass;
-
- return array(
- 'null' => array(null, null),
- 'int' => array(123, 123),
- 'float' => array(123.45, 123.45),
- 'bool false' => array(false, false),
- 'bool true' => array(true, true),
- 'ascii string' => array('abcdef', 'abcdef'),
- 'latin9 string' => array("\xB1\x31\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xFF", '±1€ŠšŽžŒœŸÿ'),
- 'unicode string' => array('¤¦¨´¸¼½¾€ŠšŽžŒœŸ', '¤¦¨´¸¼½¾€ŠšŽžŒœŸ'),
- 'empty array' => array(array(), array()),
- 'array' => array(array('abcdef'), array('abcdef')),
- 'object' => array($obj, $obj),
- );
- }
-
- /**
- * @param int $code
- * @param string $msg
- * @dataProvider providesHandleJsonErrorFailure
- */
- public function testHandleJsonErrorFailure($code, $msg)
- {
- $formatter = new NormalizerFormatter();
- $reflMethod = new \ReflectionMethod($formatter, 'handleJsonError');
- $reflMethod->setAccessible(true);
-
- $this->setExpectedException('RuntimeException', $msg);
- $reflMethod->invoke($formatter, $code, 'faked');
- }
-
- public function providesHandleJsonErrorFailure()
- {
- return array(
- 'depth' => array(JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'),
- 'state' => array(JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'),
- 'ctrl' => array(JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'),
- 'default' => array(-1, 'Unknown error'),
- );
- }
-
- public function testExceptionTraceWithArgs()
- {
- if (defined('HHVM_VERSION')) {
- $this->markTestSkipped('Not supported in HHVM since it detects errors differently');
- }
-
- // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered
- // and no file or line are included in the trace because it's treated as internal function
- set_error_handler(function ($errno, $errstr, $errfile, $errline) {
- throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
- });
-
- try {
- // This will contain $resource and $wrappedResource as arguments in the trace item
- $resource = fopen('php://memory', 'rw+');
- fwrite($resource, 'test_resource');
- $wrappedResource = new TestFooNorm;
- $wrappedResource->foo = $resource;
- // Just do something stupid with a resource/wrapped resource as argument
- array_keys($wrappedResource);
- } catch (\Exception $e) {
- restore_error_handler();
- }
-
- $formatter = new NormalizerFormatter();
- $record = array('context' => array('exception' => $e));
- $result = $formatter->format($record);
-
- $this->assertRegExp(
- '%"resource":"\[resource\] \(stream\)"%',
- $result['context']['exception']['trace'][0]
- );
-
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
- $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \)"%';
- } else {
- $pattern = '%\\\\"foo\\\\":null%';
- }
-
- // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
- $this->assertRegExp(
- $pattern,
- $result['context']['exception']['trace'][0]
- );
- }
-}
-
-class TestFooNorm
-{
- public $foo = 'foo';
-}
-
-class TestBarNorm
-{
- public function __toString()
- {
- return 'bar';
- }
-}
-
-class TestStreamFoo
-{
- public $foo;
- public $resource;
-
- public function __construct($resource)
- {
- $this->resource = $resource;
- $this->foo = 'BAR';
- }
-
- public function __toString()
- {
- fseek($this->resource, 0);
-
- return $this->foo . ' - ' . (string) stream_get_contents($this->resource);
- }
-}
-
-class TestToStringError
-{
- public function __toString()
- {
- throw new \RuntimeException('Could not convert to string');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php
deleted file mode 100644
index b1c8fd49..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php
+++ /dev/null
@@ -1,110 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-class ScalarFormatterTest extends \PHPUnit_Framework_TestCase
-{
- private $formatter;
-
- public function setUp()
- {
- $this->formatter = new ScalarFormatter();
- }
-
- public function buildTrace(\Exception $e)
- {
- $data = array();
- $trace = $e->getTrace();
- foreach ($trace as $frame) {
- if (isset($frame['file'])) {
- $data[] = $frame['file'].':'.$frame['line'];
- } else {
- $data[] = json_encode($frame);
- }
- }
-
- return $data;
- }
-
- public function encodeJson($data)
- {
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
- return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
- }
-
- return json_encode($data);
- }
-
- public function testFormat()
- {
- $exception = new \Exception('foo');
- $formatted = $this->formatter->format(array(
- 'foo' => 'string',
- 'bar' => 1,
- 'baz' => false,
- 'bam' => array(1, 2, 3),
- 'bat' => array('foo' => 'bar'),
- 'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'),
- 'ban' => $exception,
- ));
-
- $this->assertSame(array(
- 'foo' => 'string',
- 'bar' => 1,
- 'baz' => false,
- 'bam' => $this->encodeJson(array(1, 2, 3)),
- 'bat' => $this->encodeJson(array('foo' => 'bar')),
- 'bap' => '1970-01-01 00:00:00',
- 'ban' => $this->encodeJson(array(
- 'class' => get_class($exception),
- 'message' => $exception->getMessage(),
- 'code' => $exception->getCode(),
- 'file' => $exception->getFile() . ':' . $exception->getLine(),
- 'trace' => $this->buildTrace($exception),
- )),
- ), $formatted);
- }
-
- public function testFormatWithErrorContext()
- {
- $context = array('file' => 'foo', 'line' => 1);
- $formatted = $this->formatter->format(array(
- 'context' => $context,
- ));
-
- $this->assertSame(array(
- 'context' => $this->encodeJson($context),
- ), $formatted);
- }
-
- public function testFormatWithExceptionContext()
- {
- $exception = new \Exception('foo');
- $formatted = $this->formatter->format(array(
- 'context' => array(
- 'exception' => $exception,
- ),
- ));
-
- $this->assertSame(array(
- 'context' => $this->encodeJson(array(
- 'exception' => array(
- 'class' => get_class($exception),
- 'message' => $exception->getMessage(),
- 'code' => $exception->getCode(),
- 'file' => $exception->getFile() . ':' . $exception->getLine(),
- 'trace' => $this->buildTrace($exception),
- ),
- )),
- ), $formatted);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php
deleted file mode 100644
index 52f15a36..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php
+++ /dev/null
@@ -1,142 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Formatter;
-
-use Monolog\Logger;
-
-class WildfireFormatterTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @covers Monolog\Formatter\WildfireFormatter::format
- */
- public function testDefaultFormat()
- {
- $wildfire = new WildfireFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('ip' => '127.0.0.1'),
- 'message' => 'log',
- );
-
- $message = $wildfire->format($record);
-
- $this->assertEquals(
- '125|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},'
- .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\WildfireFormatter::format
- */
- public function testFormatWithFileAndLine()
- {
- $wildfire = new WildfireFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('from' => 'logger'),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
- 'message' => 'log',
- );
-
- $message = $wildfire->format($record);
-
- $this->assertEquals(
- '129|[{"Type":"ERROR","File":"test","Line":14,"Label":"meh"},'
- .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\WildfireFormatter::format
- */
- public function testFormatWithoutContext()
- {
- $wildfire = new WildfireFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $message = $wildfire->format($record);
-
- $this->assertEquals(
- '58|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},"log"]|',
- $message
- );
- }
-
- /**
- * @covers Monolog\Formatter\WildfireFormatter::formatBatch
- * @expectedException BadMethodCallException
- */
- public function testBatchFormatThrowException()
- {
- $wildfire = new WildfireFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array(),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $wildfire->formatBatch(array($record));
- }
-
- /**
- * @covers Monolog\Formatter\WildfireFormatter::format
- */
- public function testTableFormat()
- {
- $wildfire = new WildfireFormatter();
- $record = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'table-channel',
- 'context' => array(
- WildfireFormatter::TABLE => array(
- array('col1', 'col2', 'col3'),
- array('val1', 'val2', 'val3'),
- array('foo1', 'foo2', 'foo3'),
- array('bar1', 'bar2', 'bar3'),
- ),
- ),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'table-message',
- );
-
- $message = $wildfire->format($record);
-
- $this->assertEquals(
- '171|[{"Type":"TABLE","File":"","Line":"","Label":"table-channel: table-message"},[["col1","col2","col3"],["val1","val2","val3"],["foo1","foo2","foo3"],["bar1","bar2","bar3"]]]|',
- $message
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php
deleted file mode 100644
index 568eb9da..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php
+++ /dev/null
@@ -1,115 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Processor\WebProcessor;
-
-class AbstractHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\AbstractHandler::__construct
- * @covers Monolog\Handler\AbstractHandler::getLevel
- * @covers Monolog\Handler\AbstractHandler::setLevel
- * @covers Monolog\Handler\AbstractHandler::getBubble
- * @covers Monolog\Handler\AbstractHandler::setBubble
- * @covers Monolog\Handler\AbstractHandler::getFormatter
- * @covers Monolog\Handler\AbstractHandler::setFormatter
- */
- public function testConstructAndGetSet()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
- $this->assertEquals(Logger::WARNING, $handler->getLevel());
- $this->assertEquals(false, $handler->getBubble());
-
- $handler->setLevel(Logger::ERROR);
- $handler->setBubble(true);
- $handler->setFormatter($formatter = new LineFormatter);
- $this->assertEquals(Logger::ERROR, $handler->getLevel());
- $this->assertEquals(true, $handler->getBubble());
- $this->assertSame($formatter, $handler->getFormatter());
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::handleBatch
- */
- public function testHandleBatch()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
- $handler->expects($this->exactly(2))
- ->method('handle');
- $handler->handleBatch(array($this->getRecord(), $this->getRecord()));
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::isHandling
- */
- public function testIsHandling()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
- $this->assertTrue($handler->isHandling($this->getRecord()));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::__construct
- */
- public function testHandlesPsrStyleLevels()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array('warning', false));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
- $handler->setLevel('debug');
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::getFormatter
- * @covers Monolog\Handler\AbstractHandler::getDefaultFormatter
- */
- public function testGetFormatterInitializesDefault()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
- $this->assertInstanceOf('Monolog\Formatter\LineFormatter', $handler->getFormatter());
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::pushProcessor
- * @covers Monolog\Handler\AbstractHandler::popProcessor
- * @expectedException LogicException
- */
- public function testPushPopProcessor()
- {
- $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
- $processor1 = new WebProcessor;
- $processor2 = new WebProcessor;
-
- $logger->pushProcessor($processor1);
- $logger->pushProcessor($processor2);
-
- $this->assertEquals($processor2, $logger->popProcessor());
- $this->assertEquals($processor1, $logger->popProcessor());
- $logger->popProcessor();
- }
-
- /**
- * @covers Monolog\Handler\AbstractHandler::pushProcessor
- * @expectedException InvalidArgumentException
- */
- public function testPushProcessorWithNonCallable()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
-
- $handler->pushProcessor(new \stdClass());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php
deleted file mode 100644
index 24d4f63c..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php
+++ /dev/null
@@ -1,80 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Processor\WebProcessor;
-
-class AbstractProcessingHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\AbstractProcessingHandler::handle
- */
- public function testHandleLowerLevelMessage()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, true));
- $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\AbstractProcessingHandler::handle
- */
- public function testHandleBubbling()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, true));
- $this->assertFalse($handler->handle($this->getRecord()));
- }
-
- /**
- * @covers Monolog\Handler\AbstractProcessingHandler::handle
- */
- public function testHandleNotBubbling()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, false));
- $this->assertTrue($handler->handle($this->getRecord()));
- }
-
- /**
- * @covers Monolog\Handler\AbstractProcessingHandler::handle
- */
- public function testHandleIsFalseWhenNotHandled()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, false));
- $this->assertTrue($handler->handle($this->getRecord()));
- $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\AbstractProcessingHandler::processRecord
- */
- public function testProcessRecord()
- {
- $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler');
- $handler->pushProcessor(new WebProcessor(array(
- 'REQUEST_URI' => '',
- 'REQUEST_METHOD' => '',
- 'REMOTE_ADDR' => '',
- 'SERVER_NAME' => '',
- 'UNIQUE_ID' => '',
- )));
- $handledRecord = null;
- $handler->expects($this->once())
- ->method('write')
- ->will($this->returnCallback(function ($record) use (&$handledRecord) {
- $handledRecord = $record;
- }))
- ;
- $handler->handle($this->getRecord());
- $this->assertEquals(6, count($handledRecord['extra']));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php
deleted file mode 100644
index 8e0e7237..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php
+++ /dev/null
@@ -1,136 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use PhpAmqpLib\Message\AMQPMessage;
-use PhpAmqpLib\Connection\AMQPConnection;
-
-/**
- * @covers Monolog\Handler\RotatingFileHandler
- */
-class AmqpHandlerTest extends TestCase
-{
- public function testHandleAmqpExt()
- {
- if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) {
- $this->markTestSkipped("amqp-php not installed");
- }
-
- if (!class_exists('AMQPChannel')) {
- $this->markTestSkipped("Please update AMQP to version >= 1.0");
- }
-
- $messages = array();
-
- $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false);
- $exchange->expects($this->once())
- ->method('setName')
- ->with('log')
- ;
- $exchange->expects($this->any())
- ->method('publish')
- ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) {
- $messages[] = array($message, $routing_key, $flags, $attributes);
- }))
- ;
-
- $handler = new AmqpHandler($exchange, 'log');
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $expected = array(
- array(
- 'message' => 'test',
- 'context' => array(
- 'data' => array(),
- 'foo' => 34,
- ),
- 'level' => 300,
- 'level_name' => 'WARNING',
- 'channel' => 'test',
- 'extra' => array(),
- ),
- 'warn.test',
- 0,
- array(
- 'delivery_mode' => 2,
- 'content_type' => 'application/json',
- ),
- );
-
- $handler->handle($record);
-
- $this->assertCount(1, $messages);
- $messages[0][0] = json_decode($messages[0][0], true);
- unset($messages[0][0]['datetime']);
- $this->assertEquals($expected, $messages[0]);
- }
-
- public function testHandlePhpAmqpLib()
- {
- if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) {
- $this->markTestSkipped("php-amqplib not installed");
- }
-
- $messages = array();
-
- $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false);
-
- $exchange->expects($this->any())
- ->method('basic_publish')
- ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) {
- $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket);
- }))
- ;
-
- $handler = new AmqpHandler($exchange, 'log');
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $expected = array(
- array(
- 'message' => 'test',
- 'context' => array(
- 'data' => array(),
- 'foo' => 34,
- ),
- 'level' => 300,
- 'level_name' => 'WARNING',
- 'channel' => 'test',
- 'extra' => array(),
- ),
- 'log',
- 'warn.test',
- false,
- false,
- null,
- array(
- 'delivery_mode' => 2,
- 'content_type' => 'application/json',
- ),
- );
-
- $handler->handle($record);
-
- $this->assertCount(1, $messages);
-
- /* @var $msg AMQPMessage */
- $msg = $messages[0][0];
- $messages[0][0] = json_decode($msg->body, true);
- $messages[0][] = $msg->get_properties();
- unset($messages[0][0]['datetime']);
-
- $this->assertEquals($expected, $messages[0]);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php
deleted file mode 100644
index ffb1d746..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php
+++ /dev/null
@@ -1,130 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\BrowserConsoleHandlerTest
- */
-class BrowserConsoleHandlerTest extends TestCase
-{
- protected function setUp()
- {
- BrowserConsoleHandler::reset();
- }
-
- protected function generateScript()
- {
- $reflMethod = new \ReflectionMethod('Monolog\Handler\BrowserConsoleHandler', 'generateScript');
- $reflMethod->setAccessible(true);
-
- return $reflMethod->invoke(null);
- }
-
- public function testStyling()
- {
- $handler = new BrowserConsoleHandler();
- $handler->setFormatter($this->getIdentityFormatter());
-
- $handler->handle($this->getRecord(Logger::DEBUG, 'foo[[bar]]{color: red}'));
-
- $expected = <<assertEquals($expected, $this->generateScript());
- }
-
- public function testEscaping()
- {
- $handler = new BrowserConsoleHandler();
- $handler->setFormatter($this->getIdentityFormatter());
-
- $handler->handle($this->getRecord(Logger::DEBUG, "[foo] [[\"bar\n[baz]\"]]{color: red}"));
-
- $expected = <<assertEquals($expected, $this->generateScript());
- }
-
- public function testAutolabel()
- {
- $handler = new BrowserConsoleHandler();
- $handler->setFormatter($this->getIdentityFormatter());
-
- $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
- $handler->handle($this->getRecord(Logger::DEBUG, '[[bar]]{macro: autolabel}'));
- $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
-
- $expected = <<assertEquals($expected, $this->generateScript());
- }
-
- public function testContext()
- {
- $handler = new BrowserConsoleHandler();
- $handler->setFormatter($this->getIdentityFormatter());
-
- $handler->handle($this->getRecord(Logger::DEBUG, 'test', array('foo' => 'bar')));
-
- $expected = <<assertEquals($expected, $this->generateScript());
- }
-
- public function testConcurrentHandlers()
- {
- $handler1 = new BrowserConsoleHandler();
- $handler1->setFormatter($this->getIdentityFormatter());
-
- $handler2 = new BrowserConsoleHandler();
- $handler2->setFormatter($this->getIdentityFormatter());
-
- $handler1->handle($this->getRecord(Logger::DEBUG, 'test1'));
- $handler2->handle($this->getRecord(Logger::DEBUG, 'test2'));
- $handler1->handle($this->getRecord(Logger::DEBUG, 'test3'));
- $handler2->handle($this->getRecord(Logger::DEBUG, 'test4'));
-
- $expected = <<assertEquals($expected, $this->generateScript());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php
deleted file mode 100644
index da8b3c39..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php
+++ /dev/null
@@ -1,158 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class BufferHandlerTest extends TestCase
-{
- private $shutdownCheckHandler;
-
- /**
- * @covers Monolog\Handler\BufferHandler::__construct
- * @covers Monolog\Handler\BufferHandler::handle
- * @covers Monolog\Handler\BufferHandler::close
- */
- public function testHandleBuffers()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertFalse($test->hasDebugRecords());
- $this->assertFalse($test->hasInfoRecords());
- $handler->close();
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::close
- * @covers Monolog\Handler\BufferHandler::flush
- */
- public function testPropagatesRecordsAtEndOfRequest()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test);
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->shutdownCheckHandler = $test;
- register_shutdown_function(array($this, 'checkPropagation'));
- }
-
- public function checkPropagation()
- {
- if (!$this->shutdownCheckHandler->hasWarningRecords() || !$this->shutdownCheckHandler->hasDebugRecords()) {
- echo '!!! BufferHandlerTest::testPropagatesRecordsAtEndOfRequest failed to verify that the messages have been propagated' . PHP_EOL;
- exit(1);
- }
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::handle
- */
- public function testHandleBufferLimit()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test, 2);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->close();
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertFalse($test->hasDebugRecords());
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::handle
- */
- public function testHandleBufferLimitWithFlushOnOverflow()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test, 3, Logger::DEBUG, true, true);
-
- // send two records
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
- $this->assertCount(0, $test->getRecords());
-
- // overflow
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertTrue($test->hasDebugRecords());
- $this->assertCount(3, $test->getRecords());
-
- // should buffer again
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertCount(3, $test->getRecords());
-
- $handler->close();
- $this->assertCount(5, $test->getRecords());
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::handle
- */
- public function testHandleLevel()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test, 0, Logger::INFO);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->close();
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertFalse($test->hasDebugRecords());
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::flush
- */
- public function testFlush()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test, 0);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->flush();
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue($test->hasDebugRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\BufferHandler::handle
- */
- public function testHandleUsesProcessors()
- {
- $test = new TestHandler();
- $handler = new BufferHandler($test);
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->flush();
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php
deleted file mode 100644
index 0449f8b1..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php
+++ /dev/null
@@ -1,156 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\ChromePHPHandler
- */
-class ChromePHPHandlerTest extends TestCase
-{
- protected function setUp()
- {
- TestChromePHPHandler::reset();
- $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; Chrome/1.0';
- }
-
- /**
- * @dataProvider agentsProvider
- */
- public function testHeaders($agent)
- {
- $_SERVER['HTTP_USER_AGENT'] = $agent;
-
- $handler = new TestChromePHPHandler();
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING));
-
- $expected = array(
- 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
- 'version' => ChromePHPHandler::VERSION,
- 'columns' => array('label', 'log', 'backtrace', 'type'),
- 'rows' => array(
- 'test',
- 'test',
- ),
- 'request_uri' => '',
- )))),
- );
-
- $this->assertEquals($expected, $handler->getHeaders());
- }
-
- public static function agentsProvider()
- {
- return array(
- array('Monolog Test; Chrome/1.0'),
- array('Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'),
- array('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36'),
- array('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome Safari/537.36'),
- );
- }
-
- public function testHeadersOverflow()
- {
- $handler = new TestChromePHPHandler();
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 150 * 1024)));
-
- // overflow chrome headers limit
- $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 100 * 1024)));
-
- $expected = array(
- 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
- 'version' => ChromePHPHandler::VERSION,
- 'columns' => array('label', 'log', 'backtrace', 'type'),
- 'rows' => array(
- array(
- 'test',
- 'test',
- 'unknown',
- 'log',
- ),
- array(
- 'test',
- str_repeat('a', 150 * 1024),
- 'unknown',
- 'warn',
- ),
- array(
- 'monolog',
- 'Incomplete logs, chrome header size limit reached',
- 'unknown',
- 'warn',
- ),
- ),
- 'request_uri' => '',
- )))),
- );
-
- $this->assertEquals($expected, $handler->getHeaders());
- }
-
- public function testConcurrentHandlers()
- {
- $handler = new TestChromePHPHandler();
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING));
-
- $handler2 = new TestChromePHPHandler();
- $handler2->setFormatter($this->getIdentityFormatter());
- $handler2->handle($this->getRecord(Logger::DEBUG));
- $handler2->handle($this->getRecord(Logger::WARNING));
-
- $expected = array(
- 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
- 'version' => ChromePHPHandler::VERSION,
- 'columns' => array('label', 'log', 'backtrace', 'type'),
- 'rows' => array(
- 'test',
- 'test',
- 'test',
- 'test',
- ),
- 'request_uri' => '',
- )))),
- );
-
- $this->assertEquals($expected, $handler2->getHeaders());
- }
-}
-
-class TestChromePHPHandler extends ChromePHPHandler
-{
- protected $headers = array();
-
- public static function reset()
- {
- self::$initialized = false;
- self::$overflowed = false;
- self::$sendHeaders = true;
- self::$json['rows'] = array();
- }
-
- protected function sendHeader($header, $content)
- {
- $this->headers[$header] = $content;
- }
-
- public function getHeaders()
- {
- return $this->headers;
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php
deleted file mode 100644
index 9fc4b388..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php
+++ /dev/null
@@ -1,31 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class CouchDBHandlerTest extends TestCase
-{
- public function testHandle()
- {
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $handler = new CouchDBHandler();
-
- try {
- $handler->handle($record);
- } catch (\RuntimeException $e) {
- $this->markTestSkipped('Could not connect to couchdb server on http://localhost:5984');
- }
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/DeduplicationHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/DeduplicationHandlerTest.php
deleted file mode 100644
index e2aff868..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/DeduplicationHandlerTest.php
+++ /dev/null
@@ -1,165 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class DeduplicationHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\DeduplicationHandler::flush
- */
- public function testFlushPassthruIfAllRecordsUnderTrigger()
- {
- $test = new TestHandler();
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
-
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
-
- $handler->flush();
-
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue($test->hasDebugRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\DeduplicationHandler::flush
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
- */
- public function testFlushPassthruIfEmptyLog()
- {
- $test = new TestHandler();
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
-
- $handler->handle($this->getRecord(Logger::ERROR, 'Foo:bar'));
- $handler->handle($this->getRecord(Logger::CRITICAL, "Foo\nbar"));
-
- $handler->flush();
-
- $this->assertTrue($test->hasErrorRecords());
- $this->assertTrue($test->hasCriticalRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\DeduplicationHandler::flush
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
- * @depends testFlushPassthruIfEmptyLog
- */
- public function testFlushSkipsIfLogExists()
- {
- $test = new TestHandler();
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
-
- $handler->handle($this->getRecord(Logger::ERROR, 'Foo:bar'));
- $handler->handle($this->getRecord(Logger::CRITICAL, "Foo\nbar"));
-
- $handler->flush();
-
- $this->assertFalse($test->hasErrorRecords());
- $this->assertFalse($test->hasCriticalRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\DeduplicationHandler::flush
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
- * @depends testFlushPassthruIfEmptyLog
- */
- public function testFlushPassthruIfLogTooOld()
- {
- $test = new TestHandler();
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
-
- $record = $this->getRecord(Logger::ERROR);
- $record['datetime']->modify('+62seconds');
- $handler->handle($record);
- $record = $this->getRecord(Logger::CRITICAL);
- $record['datetime']->modify('+62seconds');
- $handler->handle($record);
-
- $handler->flush();
-
- $this->assertTrue($test->hasErrorRecords());
- $this->assertTrue($test->hasCriticalRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\DeduplicationHandler::flush
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
- * @covers Monolog\Handler\DeduplicationHandler::collectLogs
- */
- public function testGcOldLogs()
- {
- $test = new TestHandler();
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
-
- // handle two records from yesterday, and one recent
- $record = $this->getRecord(Logger::ERROR);
- $record['datetime']->modify('-1day -10seconds');
- $handler->handle($record);
- $record2 = $this->getRecord(Logger::CRITICAL);
- $record2['datetime']->modify('-1day -10seconds');
- $handler->handle($record2);
- $record3 = $this->getRecord(Logger::CRITICAL);
- $record3['datetime']->modify('-30seconds');
- $handler->handle($record3);
-
- // log is written as none of them are duplicate
- $handler->flush();
- $this->assertSame(
- $record['datetime']->getTimestamp() . ":ERROR:test\n" .
- $record2['datetime']->getTimestamp() . ":CRITICAL:test\n" .
- $record3['datetime']->getTimestamp() . ":CRITICAL:test\n",
- file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
- );
- $this->assertTrue($test->hasErrorRecords());
- $this->assertTrue($test->hasCriticalRecords());
- $this->assertFalse($test->hasWarningRecords());
-
- // clear test handler
- $test->clear();
- $this->assertFalse($test->hasErrorRecords());
- $this->assertFalse($test->hasCriticalRecords());
-
- // log new records, duplicate log gets GC'd at the end of this flush call
- $handler->handle($record = $this->getRecord(Logger::ERROR));
- $handler->handle($record2 = $this->getRecord(Logger::CRITICAL));
- $handler->flush();
-
- // log should now contain the new errors and the previous one that was recent enough
- $this->assertSame(
- $record3['datetime']->getTimestamp() . ":CRITICAL:test\n" .
- $record['datetime']->getTimestamp() . ":ERROR:test\n" .
- $record2['datetime']->getTimestamp() . ":CRITICAL:test\n",
- file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
- );
- $this->assertTrue($test->hasErrorRecords());
- $this->assertTrue($test->hasCriticalRecords());
- $this->assertFalse($test->hasWarningRecords());
- }
-
- public static function tearDownAfterClass()
- {
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php
deleted file mode 100644
index d67da90a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php
+++ /dev/null
@@ -1,52 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class DoctrineCouchDBHandlerTest extends TestCase
-{
- protected function setup()
- {
- if (!class_exists('Doctrine\CouchDB\CouchDBClient')) {
- $this->markTestSkipped('The "doctrine/couchdb" package is not installed');
- }
- }
-
- public function testHandle()
- {
- $client = $this->getMockBuilder('Doctrine\\CouchDB\\CouchDBClient')
- ->setMethods(array('postDocument'))
- ->disableOriginalConstructor()
- ->getMock();
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $expected = array(
- 'message' => 'test',
- 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
- 'level' => Logger::WARNING,
- 'level_name' => 'WARNING',
- 'channel' => 'test',
- 'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
- 'extra' => array(),
- );
-
- $client->expects($this->once())
- ->method('postDocument')
- ->with($expected);
-
- $handler = new DoctrineCouchDBHandler($client);
- $handler->handle($record);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php
deleted file mode 100644
index 2e6c348d..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-
-class DynamoDbHandlerTest extends TestCase
-{
- private $client;
-
- public function setUp()
- {
- if (!class_exists('Aws\DynamoDb\DynamoDbClient')) {
- $this->markTestSkipped('aws/aws-sdk-php not installed');
- }
-
- $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient')
- ->setMethods(array('formatAttributes', '__call'))
- ->disableOriginalConstructor()->getMock();
- }
-
- public function testConstruct()
- {
- $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo'));
- }
-
- public function testInterface()
- {
- $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo'));
- }
-
- public function testGetFormatter()
- {
- $handler = new DynamoDbHandler($this->client, 'foo');
- $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter());
- }
-
- public function testHandle()
- {
- $record = $this->getRecord();
- $formatter = $this->getMock('Monolog\Formatter\FormatterInterface');
- $formatted = array('foo' => 1, 'bar' => 2);
- $handler = new DynamoDbHandler($this->client, 'foo');
- $handler->setFormatter($formatter);
-
- $isV3 = defined('Aws\Sdk::VERSION') && version_compare(\Aws\Sdk::VERSION, '3.0', '>=');
- if ($isV3) {
- $expFormatted = array('foo' => array('N' => 1), 'bar' => array('N' => 2));
- } else {
- $expFormatted = $formatted;
- }
-
- $formatter
- ->expects($this->once())
- ->method('format')
- ->with($record)
- ->will($this->returnValue($formatted));
- $this->client
- ->expects($isV3 ? $this->never() : $this->once())
- ->method('formatAttributes')
- ->with($this->isType('array'))
- ->will($this->returnValue($formatted));
- $this->client
- ->expects($this->once())
- ->method('__call')
- ->with('putItem', array(array(
- 'TableName' => 'foo',
- 'Item' => $expFormatted,
- )));
-
- $handler->handle($record);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php
deleted file mode 100644
index 1687074b..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php
+++ /dev/null
@@ -1,239 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Formatter\ElasticaFormatter;
-use Monolog\Formatter\NormalizerFormatter;
-use Monolog\TestCase;
-use Monolog\Logger;
-use Elastica\Client;
-use Elastica\Request;
-use Elastica\Response;
-
-class ElasticSearchHandlerTest extends TestCase
-{
- /**
- * @var Client mock
- */
- protected $client;
-
- /**
- * @var array Default handler options
- */
- protected $options = array(
- 'index' => 'my_index',
- 'type' => 'doc_type',
- );
-
- public function setUp()
- {
- // Elastica lib required
- if (!class_exists("Elastica\Client")) {
- $this->markTestSkipped("ruflin/elastica not installed");
- }
-
- // base mock Elastica Client object
- $this->client = $this->getMockBuilder('Elastica\Client')
- ->setMethods(array('addDocuments'))
- ->disableOriginalConstructor()
- ->getMock();
- }
-
- /**
- * @covers Monolog\Handler\ElasticSearchHandler::write
- * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
- * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
- * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
- */
- public function testHandle()
- {
- // log message
- $msg = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- // format expected result
- $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']);
- $expected = array($formatter->format($msg));
-
- // setup ES client mock
- $this->client->expects($this->any())
- ->method('addDocuments')
- ->with($expected);
-
- // perform tests
- $handler = new ElasticSearchHandler($this->client, $this->options);
- $handler->handle($msg);
- $handler->handleBatch(array($msg));
- }
-
- /**
- * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
- */
- public function testSetFormatter()
- {
- $handler = new ElasticSearchHandler($this->client);
- $formatter = new ElasticaFormatter('index_new', 'type_new');
- $handler->setFormatter($formatter);
- $this->assertInstanceOf('Monolog\Formatter\ElasticaFormatter', $handler->getFormatter());
- $this->assertEquals('index_new', $handler->getFormatter()->getIndex());
- $this->assertEquals('type_new', $handler->getFormatter()->getType());
- }
-
- /**
- * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
- * @expectedException InvalidArgumentException
- * @expectedExceptionMessage ElasticSearchHandler is only compatible with ElasticaFormatter
- */
- public function testSetFormatterInvalid()
- {
- $handler = new ElasticSearchHandler($this->client);
- $formatter = new NormalizerFormatter();
- $handler->setFormatter($formatter);
- }
-
- /**
- * @covers Monolog\Handler\ElasticSearchHandler::__construct
- * @covers Monolog\Handler\ElasticSearchHandler::getOptions
- */
- public function testOptions()
- {
- $expected = array(
- 'index' => $this->options['index'],
- 'type' => $this->options['type'],
- 'ignore_error' => false,
- );
- $handler = new ElasticSearchHandler($this->client, $this->options);
- $this->assertEquals($expected, $handler->getOptions());
- }
-
- /**
- * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
- * @dataProvider providerTestConnectionErrors
- */
- public function testConnectionErrors($ignore, $expectedError)
- {
- $clientOpts = array('host' => '127.0.0.1', 'port' => 1);
- $client = new Client($clientOpts);
- $handlerOpts = array('ignore_error' => $ignore);
- $handler = new ElasticSearchHandler($client, $handlerOpts);
-
- if ($expectedError) {
- $this->setExpectedException($expectedError[0], $expectedError[1]);
- $handler->handle($this->getRecord());
- } else {
- $this->assertFalse($handler->handle($this->getRecord()));
- }
- }
-
- /**
- * @return array
- */
- public function providerTestConnectionErrors()
- {
- return array(
- array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')),
- array(true, false),
- );
- }
-
- /**
- * Integration test using localhost Elastic Search server
- *
- * @covers Monolog\Handler\ElasticSearchHandler::__construct
- * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
- * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
- * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
- */
- public function testHandleIntegration()
- {
- $msg = array(
- 'level' => Logger::ERROR,
- 'level_name' => 'ERROR',
- 'channel' => 'meh',
- 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
- 'datetime' => new \DateTime("@0"),
- 'extra' => array(),
- 'message' => 'log',
- );
-
- $expected = $msg;
- $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601);
- $expected['context'] = array(
- 'class' => '[object] (stdClass: {})',
- 'foo' => 7,
- 0 => 'bar',
- );
-
- $client = new Client();
- $handler = new ElasticSearchHandler($client, $this->options);
- try {
- $handler->handleBatch(array($msg));
- } catch (\RuntimeException $e) {
- $this->markTestSkipped("Cannot connect to Elastic Search server on localhost");
- }
-
- // check document id from ES server response
- $documentId = $this->getCreatedDocId($client->getLastResponse());
- $this->assertNotEmpty($documentId, 'No elastic document id received');
-
- // retrieve document source from ES and validate
- $document = $this->getDocSourceFromElastic(
- $client,
- $this->options['index'],
- $this->options['type'],
- $documentId
- );
- $this->assertEquals($expected, $document);
-
- // remove test index from ES
- $client->request("/{$this->options['index']}", Request::DELETE);
- }
-
- /**
- * Return last created document id from ES response
- * @param Response $response Elastica Response object
- * @return string|null
- */
- protected function getCreatedDocId(Response $response)
- {
- $data = $response->getData();
- if (!empty($data['items'][0]['create']['_id'])) {
- return $data['items'][0]['create']['_id'];
- }
- }
-
- /**
- * Retrieve document by id from Elasticsearch
- * @param Client $client Elastica client
- * @param string $index
- * @param string $type
- * @param string $documentId
- * @return array
- */
- protected function getDocSourceFromElastic(Client $client, $index, $type, $documentId)
- {
- $resp = $client->request("/{$index}/{$type}/{$documentId}", Request::GET);
- $data = $resp->getData();
- if (!empty($data['_source'])) {
- return $data['_source'];
- }
-
- return array();
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php
deleted file mode 100644
index 99785cbb..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php
+++ /dev/null
@@ -1,66 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-
-function error_log()
-{
- $GLOBALS['error_log'][] = func_get_args();
-}
-
-class ErrorLogHandlerTest extends TestCase
-{
- protected function setUp()
- {
- $GLOBALS['error_log'] = array();
- }
-
- /**
- * @covers Monolog\Handler\ErrorLogHandler::__construct
- * @expectedException InvalidArgumentException
- * @expectedExceptionMessage The given message type "42" is not supported
- */
- public function testShouldNotAcceptAnInvalidTypeOnContructor()
- {
- new ErrorLogHandler(42);
- }
-
- /**
- * @covers Monolog\Handler\ErrorLogHandler::write
- */
- public function testShouldLogMessagesUsingErrorLogFuncion()
- {
- $type = ErrorLogHandler::OPERATING_SYSTEM;
- $handler = new ErrorLogHandler($type);
- $handler->setFormatter(new LineFormatter('%channel%.%level_name%: %message% %context% %extra%', null, true));
- $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
-
- $this->assertSame("test.ERROR: Foo\nBar\r\n\r\nBaz [] []", $GLOBALS['error_log'][0][0]);
- $this->assertSame($GLOBALS['error_log'][0][1], $type);
-
- $handler = new ErrorLogHandler($type, Logger::DEBUG, true, true);
- $handler->setFormatter(new LineFormatter(null, null, true));
- $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
-
- $this->assertStringMatchesFormat('[%s] test.ERROR: Foo', $GLOBALS['error_log'][1][0]);
- $this->assertSame($GLOBALS['error_log'][1][1], $type);
-
- $this->assertStringMatchesFormat('Bar', $GLOBALS['error_log'][2][0]);
- $this->assertSame($GLOBALS['error_log'][2][1], $type);
-
- $this->assertStringMatchesFormat('Baz [] []', $GLOBALS['error_log'][3][0]);
- $this->assertSame($GLOBALS['error_log'][3][1], $type);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php
deleted file mode 100644
index 31b7686a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php
+++ /dev/null
@@ -1,170 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class FilterHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\FilterHandler::isHandling
- */
- public function testIsHandling()
- {
- $test = new TestHandler();
- $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::INFO)));
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::NOTICE)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::WARNING)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::ERROR)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::CRITICAL)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::ALERT)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::EMERGENCY)));
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::handle
- * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
- * @covers Monolog\Handler\FilterHandler::isHandling
- */
- public function testHandleProcessOnlyNeededLevels()
- {
- $test = new TestHandler();
- $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
-
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
-
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertTrue($test->hasInfoRecords());
- $handler->handle($this->getRecord(Logger::NOTICE));
- $this->assertTrue($test->hasNoticeRecords());
-
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertFalse($test->hasWarningRecords());
- $handler->handle($this->getRecord(Logger::ERROR));
- $this->assertFalse($test->hasErrorRecords());
- $handler->handle($this->getRecord(Logger::CRITICAL));
- $this->assertFalse($test->hasCriticalRecords());
- $handler->handle($this->getRecord(Logger::ALERT));
- $this->assertFalse($test->hasAlertRecords());
- $handler->handle($this->getRecord(Logger::EMERGENCY));
- $this->assertFalse($test->hasEmergencyRecords());
-
- $test = new TestHandler();
- $handler = new FilterHandler($test, array(Logger::INFO, Logger::ERROR));
-
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertTrue($test->hasInfoRecords());
- $handler->handle($this->getRecord(Logger::NOTICE));
- $this->assertFalse($test->hasNoticeRecords());
- $handler->handle($this->getRecord(Logger::ERROR));
- $this->assertTrue($test->hasErrorRecords());
- $handler->handle($this->getRecord(Logger::CRITICAL));
- $this->assertFalse($test->hasCriticalRecords());
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
- * @covers Monolog\Handler\FilterHandler::getAcceptedLevels
- */
- public function testAcceptedLevelApi()
- {
- $test = new TestHandler();
- $handler = new FilterHandler($test);
-
- $levels = array(Logger::INFO, Logger::ERROR);
- $handler->setAcceptedLevels($levels);
- $this->assertSame($levels, $handler->getAcceptedLevels());
-
- $handler->setAcceptedLevels(array('info', 'error'));
- $this->assertSame($levels, $handler->getAcceptedLevels());
-
- $levels = array(Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY);
- $handler->setAcceptedLevels(Logger::CRITICAL, Logger::EMERGENCY);
- $this->assertSame($levels, $handler->getAcceptedLevels());
-
- $handler->setAcceptedLevels('critical', 'emergency');
- $this->assertSame($levels, $handler->getAcceptedLevels());
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::handle
- */
- public function testHandleUsesProcessors()
- {
- $test = new TestHandler();
- $handler = new FilterHandler($test, Logger::DEBUG, Logger::EMERGENCY);
- $handler->pushProcessor(
- function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- }
- );
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::handle
- */
- public function testHandleRespectsBubble()
- {
- $test = new TestHandler();
-
- $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, false);
- $this->assertTrue($handler->handle($this->getRecord(Logger::INFO)));
- $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
-
- $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, true);
- $this->assertFalse($handler->handle($this->getRecord(Logger::INFO)));
- $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::handle
- */
- public function testHandleWithCallback()
- {
- $test = new TestHandler();
- $handler = new FilterHandler(
- function ($record, $handler) use ($test) {
- return $test;
- }, Logger::INFO, Logger::NOTICE, false
- );
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertFalse($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\FilterHandler::handle
- * @expectedException \RuntimeException
- */
- public function testHandleWithBadCallbackThrowsException()
- {
- $handler = new FilterHandler(
- function ($record, $handler) {
- return 'foo';
- }
- );
- $handler->handle($this->getRecord(Logger::WARNING));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php
deleted file mode 100644
index b92bf437..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php
+++ /dev/null
@@ -1,279 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
-use Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy;
-use Psr\Log\LogLevel;
-
-class FingersCrossedHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleBuffers()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertFalse($test->hasDebugRecords());
- $this->assertFalse($test->hasInfoRecords());
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->close();
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 3);
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleStopsBufferingAfterTrigger()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test);
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->close();
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasDebugRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- * @covers Monolog\Handler\FingersCrossedHandler::reset
- */
- public function testHandleRestartBufferingAfterReset()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test);
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->reset();
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->close();
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasDebugRecords());
- $this->assertFalse($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleRestartBufferingAfterBeingTriggeredWhenStopBufferingIsDisabled()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, Logger::WARNING, 0, false, false);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->close();
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasDebugRecords());
- $this->assertFalse($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleBufferLimit()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, Logger::WARNING, 2);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertFalse($test->hasDebugRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleWithCallback()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) {
- return $test;
- });
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertFalse($test->hasDebugRecords());
- $this->assertFalse($test->hasInfoRecords());
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 3);
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- * @expectedException RuntimeException
- */
- public function testHandleWithBadCallbackThrowsException()
- {
- $handler = new FingersCrossedHandler(function ($record, $handler) {
- return 'foo';
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::isHandling
- */
- public function testIsHandlingAlways()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, Logger::ERROR);
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
- */
- public function testErrorLevelActivationStrategy()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
- */
- public function testErrorLevelActivationStrategyWithPsrLevel()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning'));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testOverrideActivationStrategy()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning'));
- $handler->handle($this->getRecord(Logger::DEBUG));
- $this->assertFalse($test->hasDebugRecords());
- $handler->activate();
- $this->assertTrue($test->hasDebugRecords());
- $handler->handle($this->getRecord(Logger::INFO));
- $this->assertTrue($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
- */
- public function testChannelLevelActivationStrategy()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG)));
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertFalse($test->hasWarningRecords());
- $record = $this->getRecord(Logger::DEBUG);
- $record['channel'] = 'othertest';
- $handler->handle($record);
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
- */
- public function testChannelLevelActivationStrategyWithPsrLevels()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', array('othertest' => 'debug')));
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertFalse($test->hasWarningRecords());
- $record = $this->getRecord(Logger::DEBUG);
- $record['channel'] = 'othertest';
- $handler->handle($record);
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasWarningRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::handle
- * @covers Monolog\Handler\FingersCrossedHandler::activate
- */
- public function testHandleUsesProcessors()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, Logger::INFO);
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::close
- */
- public function testPassthruOnClose()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, Logger::INFO);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->close();
- $this->assertFalse($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- }
-
- /**
- * @covers Monolog\Handler\FingersCrossedHandler::close
- */
- public function testPsrLevelPassthruOnClose()
- {
- $test = new TestHandler();
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, LogLevel::INFO);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- $handler->close();
- $this->assertFalse($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php
deleted file mode 100644
index 0eb10a63..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php
+++ /dev/null
@@ -1,96 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\FirePHPHandler
- */
-class FirePHPHandlerTest extends TestCase
-{
- public function setUp()
- {
- TestFirePHPHandler::reset();
- $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; FirePHP/1.0';
- }
-
- public function testHeaders()
- {
- $handler = new TestFirePHPHandler;
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING));
-
- $expected = array(
- 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
- 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
- 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
- 'X-Wf-1-1-1-1' => 'test',
- 'X-Wf-1-1-1-2' => 'test',
- );
-
- $this->assertEquals($expected, $handler->getHeaders());
- }
-
- public function testConcurrentHandlers()
- {
- $handler = new TestFirePHPHandler;
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::WARNING));
-
- $handler2 = new TestFirePHPHandler;
- $handler2->setFormatter($this->getIdentityFormatter());
- $handler2->handle($this->getRecord(Logger::DEBUG));
- $handler2->handle($this->getRecord(Logger::WARNING));
-
- $expected = array(
- 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
- 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
- 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
- 'X-Wf-1-1-1-1' => 'test',
- 'X-Wf-1-1-1-2' => 'test',
- );
-
- $expected2 = array(
- 'X-Wf-1-1-1-3' => 'test',
- 'X-Wf-1-1-1-4' => 'test',
- );
-
- $this->assertEquals($expected, $handler->getHeaders());
- $this->assertEquals($expected2, $handler2->getHeaders());
- }
-}
-
-class TestFirePHPHandler extends FirePHPHandler
-{
- protected $headers = array();
-
- public static function reset()
- {
- self::$initialized = false;
- self::$sendHeaders = true;
- self::$messageIndex = 1;
- }
-
- protected function sendHeader($header, $content)
- {
- $this->headers[$header] = $content;
- }
-
- public function getHeaders()
- {
- return $this->headers;
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep b/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php
deleted file mode 100644
index 91cdd312..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php
+++ /dev/null
@@ -1,85 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Formatter\LineFormatter;
-use Monolog\Logger;
-use Monolog\TestCase;
-
-/**
- * @coversDefaultClass \Monolog\Handler\FleepHookHandler
- */
-class FleepHookHandlerTest extends TestCase
-{
- /**
- * Default token to use in tests
- */
- const TOKEN = '123abc';
-
- /**
- * @var FleepHookHandler
- */
- private $handler;
-
- public function setUp()
- {
- parent::setUp();
-
- if (!extension_loaded('openssl')) {
- $this->markTestSkipped('This test requires openssl extension to run');
- }
-
- // Create instances of the handler and logger for convenience
- $this->handler = new FleepHookHandler(self::TOKEN);
- }
-
- /**
- * @covers ::__construct
- */
- public function testConstructorSetsExpectedDefaults()
- {
- $this->assertEquals(Logger::DEBUG, $this->handler->getLevel());
- $this->assertEquals(true, $this->handler->getBubble());
- }
-
- /**
- * @covers ::getDefaultFormatter
- */
- public function testHandlerUsesLineFormatterWhichIgnoresEmptyArrays()
- {
- $record = array(
- 'message' => 'msg',
- 'context' => array(),
- 'level' => Logger::DEBUG,
- 'level_name' => Logger::getLevelName(Logger::DEBUG),
- 'channel' => 'channel',
- 'datetime' => new \DateTime(),
- 'extra' => array(),
- );
-
- $expectedFormatter = new LineFormatter(null, null, true, true);
- $expected = $expectedFormatter->format($record);
-
- $handlerFormatter = $this->handler->getFormatter();
- $actual = $handlerFormatter->format($record);
-
- $this->assertEquals($expected, $actual, 'Empty context and extra arrays should not be rendered');
- }
-
- /**
- * @covers ::__construct
- */
- public function testConnectionStringisConstructedCorrectly()
- {
- $this->assertEquals('ssl://' . FleepHookHandler::FLEEP_HOST . ':443', $this->handler->getConnectionString());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php
deleted file mode 100644
index 4b120d51..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php
+++ /dev/null
@@ -1,88 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Formatter\FlowdockFormatter;
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @author Dominik Liebler
- * @see https://www.hipchat.com/docs/api
- */
-class FlowdockHandlerTest extends TestCase
-{
- /**
- * @var resource
- */
- private $res;
-
- /**
- * @var FlowdockHandler
- */
- private $handler;
-
- public function setUp()
- {
- if (!extension_loaded('openssl')) {
- $this->markTestSkipped('This test requires openssl to run');
- }
- }
-
- public function testWriteHeader()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v1\/messages\/team_inbox\/.* HTTP\/1.1\\r\\nHost: api.flowdock.com\\r\\nContent-Type: application\/json\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- /**
- * @depends testWriteHeader
- */
- public function testWriteContent($content)
- {
- $this->assertRegexp('/"source":"test_source"/', $content);
- $this->assertRegexp('/"from_address":"source@test\.com"/', $content);
- }
-
- private function createHandler($token = 'myToken')
- {
- $constructorArgs = array($token, Logger::DEBUG);
- $this->res = fopen('php://memory', 'a');
- $this->handler = $this->getMock(
- '\Monolog\Handler\FlowdockHandler',
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
- $constructorArgs
- );
-
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
-
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- $this->handler->expects($this->any())
- ->method('closeSocket')
- ->will($this->returnValue(true));
-
- $this->handler->setFormatter(new FlowdockFormatter('test_source', 'source@test.com'));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php
deleted file mode 100644
index 9d007b13..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Gelf\Message;
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\GelfMessageFormatter;
-
-class GelfHandlerLegacyTest extends TestCase
-{
- public function setUp()
- {
- if (!class_exists('Gelf\MessagePublisher') || !class_exists('Gelf\Message')) {
- $this->markTestSkipped("mlehner/gelf-php not installed");
- }
-
- require_once __DIR__ . '/GelfMockMessagePublisher.php';
- }
-
- /**
- * @covers Monolog\Handler\GelfHandler::__construct
- */
- public function testConstruct()
- {
- $handler = new GelfHandler($this->getMessagePublisher());
- $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
- }
-
- protected function getHandler($messagePublisher)
- {
- $handler = new GelfHandler($messagePublisher);
-
- return $handler;
- }
-
- protected function getMessagePublisher()
- {
- return new GelfMockMessagePublisher('localhost');
- }
-
- public function testDebug()
- {
- $messagePublisher = $this->getMessagePublisher();
- $handler = $this->getHandler($messagePublisher);
-
- $record = $this->getRecord(Logger::DEBUG, "A test debug message");
- $handler->handle($record);
-
- $this->assertEquals(7, $messagePublisher->lastMessage->getLevel());
- $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
- $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
- $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
- }
-
- public function testWarning()
- {
- $messagePublisher = $this->getMessagePublisher();
- $handler = $this->getHandler($messagePublisher);
-
- $record = $this->getRecord(Logger::WARNING, "A test warning message");
- $handler->handle($record);
-
- $this->assertEquals(4, $messagePublisher->lastMessage->getLevel());
- $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
- $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
- $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
- }
-
- public function testInjectedGelfMessageFormatter()
- {
- $messagePublisher = $this->getMessagePublisher();
- $handler = $this->getHandler($messagePublisher);
-
- $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
-
- $record = $this->getRecord(Logger::WARNING, "A test warning message");
- $record['extra']['blarg'] = 'yep';
- $record['context']['from'] = 'logger';
- $handler->handle($record);
-
- $this->assertEquals('mysystem', $messagePublisher->lastMessage->getHost());
- $this->assertArrayHasKey('_EXTblarg', $messagePublisher->lastMessage->toArray());
- $this->assertArrayHasKey('_CTXfrom', $messagePublisher->lastMessage->toArray());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php
deleted file mode 100644
index 8cdd64f4..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php
+++ /dev/null
@@ -1,117 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Gelf\Message;
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\GelfMessageFormatter;
-
-class GelfHandlerTest extends TestCase
-{
- public function setUp()
- {
- if (!class_exists('Gelf\Publisher') || !class_exists('Gelf\Message')) {
- $this->markTestSkipped("graylog2/gelf-php not installed");
- }
- }
-
- /**
- * @covers Monolog\Handler\GelfHandler::__construct
- */
- public function testConstruct()
- {
- $handler = new GelfHandler($this->getMessagePublisher());
- $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
- }
-
- protected function getHandler($messagePublisher)
- {
- $handler = new GelfHandler($messagePublisher);
-
- return $handler;
- }
-
- protected function getMessagePublisher()
- {
- return $this->getMock('Gelf\Publisher', array('publish'), array(), '', false);
- }
-
- public function testDebug()
- {
- $record = $this->getRecord(Logger::DEBUG, "A test debug message");
- $expectedMessage = new Message();
- $expectedMessage
- ->setLevel(7)
- ->setFacility("test")
- ->setShortMessage($record['message'])
- ->setTimestamp($record['datetime'])
- ;
-
- $messagePublisher = $this->getMessagePublisher();
- $messagePublisher->expects($this->once())
- ->method('publish')
- ->with($expectedMessage);
-
- $handler = $this->getHandler($messagePublisher);
-
- $handler->handle($record);
- }
-
- public function testWarning()
- {
- $record = $this->getRecord(Logger::WARNING, "A test warning message");
- $expectedMessage = new Message();
- $expectedMessage
- ->setLevel(4)
- ->setFacility("test")
- ->setShortMessage($record['message'])
- ->setTimestamp($record['datetime'])
- ;
-
- $messagePublisher = $this->getMessagePublisher();
- $messagePublisher->expects($this->once())
- ->method('publish')
- ->with($expectedMessage);
-
- $handler = $this->getHandler($messagePublisher);
-
- $handler->handle($record);
- }
-
- public function testInjectedGelfMessageFormatter()
- {
- $record = $this->getRecord(Logger::WARNING, "A test warning message");
- $record['extra']['blarg'] = 'yep';
- $record['context']['from'] = 'logger';
-
- $expectedMessage = new Message();
- $expectedMessage
- ->setLevel(4)
- ->setFacility("test")
- ->setHost("mysystem")
- ->setShortMessage($record['message'])
- ->setTimestamp($record['datetime'])
- ->setAdditional("EXTblarg", 'yep')
- ->setAdditional("CTXfrom", 'logger')
- ;
-
- $messagePublisher = $this->getMessagePublisher();
- $messagePublisher->expects($this->once())
- ->method('publish')
- ->with($expectedMessage);
-
- $handler = $this->getHandler($messagePublisher);
- $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
- $handler->handle($record);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php
deleted file mode 100644
index 873d92fb..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php
+++ /dev/null
@@ -1,25 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Gelf\MessagePublisher;
-use Gelf\Message;
-
-class GelfMockMessagePublisher extends MessagePublisher
-{
- public function publish(Message $message)
- {
- $this->lastMessage = $message;
- }
-
- public $lastMessage = null;
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php
deleted file mode 100644
index a1b86176..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php
+++ /dev/null
@@ -1,112 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class GroupHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\GroupHandler::__construct
- * @expectedException InvalidArgumentException
- */
- public function testConstructorOnlyTakesHandler()
- {
- new GroupHandler(array(new TestHandler(), "foo"));
- }
-
- /**
- * @covers Monolog\Handler\GroupHandler::__construct
- * @covers Monolog\Handler\GroupHandler::handle
- */
- public function testHandle()
- {
- $testHandlers = array(new TestHandler(), new TestHandler());
- $handler = new GroupHandler($testHandlers);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- foreach ($testHandlers as $test) {
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- }
- }
-
- /**
- * @covers Monolog\Handler\GroupHandler::handleBatch
- */
- public function testHandleBatch()
- {
- $testHandlers = array(new TestHandler(), new TestHandler());
- $handler = new GroupHandler($testHandlers);
- $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
- foreach ($testHandlers as $test) {
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- }
- }
-
- /**
- * @covers Monolog\Handler\GroupHandler::isHandling
- */
- public function testIsHandling()
- {
- $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING));
- $handler = new GroupHandler($testHandlers);
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR)));
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\GroupHandler::handle
- */
- public function testHandleUsesProcessors()
- {
- $test = new TestHandler();
- $handler = new GroupHandler(array($test));
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-
- /**
- * @covers Monolog\Handler\GroupHandler::handle
- */
- public function testHandleBatchUsesProcessors()
- {
- $testHandlers = array(new TestHandler(), new TestHandler());
- $handler = new GroupHandler($testHandlers);
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
- foreach ($testHandlers as $test) {
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- $this->assertTrue($records[1]['extra']['foo']);
- }
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/HandlerWrapperTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/HandlerWrapperTest.php
deleted file mode 100644
index d8d0452c..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/HandlerWrapperTest.php
+++ /dev/null
@@ -1,130 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-
-/**
- * @author Alexey Karapetov
- */
-class HandlerWrapperTest extends TestCase
-{
- /**
- * @var HandlerWrapper
- */
- private $wrapper;
-
- private $handler;
-
- public function setUp()
- {
- parent::setUp();
- $this->handler = $this->getMock('Monolog\\Handler\\HandlerInterface');
- $this->wrapper = new HandlerWrapper($this->handler);
- }
-
- /**
- * @return array
- */
- public function trueFalseDataProvider()
- {
- return array(
- array(true),
- array(false),
- );
- }
-
- /**
- * @param $result
- * @dataProvider trueFalseDataProvider
- */
- public function testIsHandling($result)
- {
- $record = $this->getRecord();
- $this->handler->expects($this->once())
- ->method('isHandling')
- ->with($record)
- ->willReturn($result);
-
- $this->assertEquals($result, $this->wrapper->isHandling($record));
- }
-
- /**
- * @param $result
- * @dataProvider trueFalseDataProvider
- */
- public function testHandle($result)
- {
- $record = $this->getRecord();
- $this->handler->expects($this->once())
- ->method('handle')
- ->with($record)
- ->willReturn($result);
-
- $this->assertEquals($result, $this->wrapper->handle($record));
- }
-
- /**
- * @param $result
- * @dataProvider trueFalseDataProvider
- */
- public function testHandleBatch($result)
- {
- $records = $this->getMultipleRecords();
- $this->handler->expects($this->once())
- ->method('handleBatch')
- ->with($records)
- ->willReturn($result);
-
- $this->assertEquals($result, $this->wrapper->handleBatch($records));
- }
-
- public function testPushProcessor()
- {
- $processor = function () {};
- $this->handler->expects($this->once())
- ->method('pushProcessor')
- ->with($processor);
-
- $this->assertEquals($this->wrapper, $this->wrapper->pushProcessor($processor));
- }
-
- public function testPopProcessor()
- {
- $processor = function () {};
- $this->handler->expects($this->once())
- ->method('popProcessor')
- ->willReturn($processor);
-
- $this->assertEquals($processor, $this->wrapper->popProcessor());
- }
-
- public function testSetFormatter()
- {
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $this->handler->expects($this->once())
- ->method('setFormatter')
- ->with($formatter);
-
- $this->assertEquals($this->wrapper, $this->wrapper->setFormatter($formatter));
- }
-
- public function testGetFormatter()
- {
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $this->handler->expects($this->once())
- ->method('getFormatter')
- ->willReturn($formatter);
-
- $this->assertEquals($formatter, $this->wrapper->getFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php
deleted file mode 100644
index 52dc9dac..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php
+++ /dev/null
@@ -1,279 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @author Rafael Dohms
- * @see https://www.hipchat.com/docs/api
- */
-class HipChatHandlerTest extends TestCase
-{
- private $res;
- /** @var HipChatHandler */
- private $handler;
-
- public function testWriteHeader()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: api.hipchat.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- public function testWriteCustomHostHeader()
- {
- $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- public function testWriteV2()
- {
- $this->createHandler('myToken', 'room1', 'Monolog', false, 'hipchat.foo.bar', 'v2');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- public function testWriteV2Notify()
- {
- $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar', 'v2');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- public function testRoomSpaces()
- {
- $this->createHandler('myToken', 'room name', 'Monolog', false, 'hipchat.foo.bar', 'v2');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/v2\/room\/room%20name\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- /**
- * @depends testWriteHeader
- */
- public function testWriteContent($content)
- {
- $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content);
- }
-
- public function testWriteContentV1WithoutName()
- {
- $this->createHandler('myToken', 'room1', null, false, 'hipchat.foo.bar', 'v1');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=$/', $content);
-
- return $content;
- }
-
- /**
- * @depends testWriteCustomHostHeader
- */
- public function testWriteContentNotify($content)
- {
- $this->assertRegexp('/notify=1&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content);
- }
-
- /**
- * @depends testWriteV2
- */
- public function testWriteContentV2($content)
- {
- $this->assertRegexp('/notify=false&message=test1&message_format=text&color=red&from=Monolog$/', $content);
- }
-
- /**
- * @depends testWriteV2Notify
- */
- public function testWriteContentV2Notify($content)
- {
- $this->assertRegexp('/notify=true&message=test1&message_format=text&color=red&from=Monolog$/', $content);
- }
-
- public function testWriteContentV2WithoutName()
- {
- $this->createHandler('myToken', 'room1', null, false, 'hipchat.foo.bar', 'v2');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/notify=false&message=test1&message_format=text&color=red$/', $content);
-
- return $content;
- }
-
- public function testWriteWithComplexMessage()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
- }
-
- public function testWriteTruncatesLongMessage()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, str_repeat('abcde', 2000)));
- fseek($this->res, 0);
- $content = fread($this->res, 12000);
-
- $this->assertRegexp('/message='.str_repeat('abcde', 1900).'\+%5Btruncated%5D/', $content);
- }
-
- /**
- * @dataProvider provideLevelColors
- */
- public function testWriteWithErrorLevelsAndColors($level, $expectedColor)
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord($level, 'Backup of database "example" finished in 16 minutes.'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/color='.$expectedColor.'/', $content);
- }
-
- public function provideLevelColors()
- {
- return array(
- array(Logger::DEBUG, 'gray'),
- array(Logger::INFO, 'green'),
- array(Logger::WARNING, 'yellow'),
- array(Logger::ERROR, 'red'),
- array(Logger::CRITICAL, 'red'),
- array(Logger::ALERT, 'red'),
- array(Logger::EMERGENCY,'red'),
- array(Logger::NOTICE, 'green'),
- );
- }
-
- /**
- * @dataProvider provideBatchRecords
- */
- public function testHandleBatch($records, $expectedColor)
- {
- $this->createHandler();
-
- $this->handler->handleBatch($records);
-
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/color='.$expectedColor.'/', $content);
- }
-
- public function provideBatchRecords()
- {
- return array(
- array(
- array(
- array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
- array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime()),
- ),
- 'red',
- ),
- array(
- array(
- array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
- ),
- 'yellow',
- ),
- array(
- array(
- array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
- ),
- 'green',
- ),
- array(
- array(
- array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
- ),
- 'gray',
- ),
- );
- }
-
- private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false, $host = 'api.hipchat.com', $version = 'v1')
- {
- $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host, $version);
- $this->res = fopen('php://memory', 'a');
- $this->handler = $this->getMock(
- '\Monolog\Handler\HipChatHandler',
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
- $constructorArgs
- );
-
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
-
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- $this->handler->expects($this->any())
- ->method('closeSocket')
- ->will($this->returnValue(true));
-
- $this->handler->setFormatter($this->getIdentityFormatter());
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testCreateWithTooLongName()
- {
- $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere');
- }
-
- public function testCreateWithTooLongNameV2()
- {
- // creating a handler with too long of a name but using the v2 api doesn't matter.
- $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere', false, Logger::CRITICAL, true, true, 'test', 'api.hipchat.com', 'v2');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php
deleted file mode 100644
index b2deb40a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php
+++ /dev/null
@@ -1,84 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @author Robert Kaufmann III
- */
-class LogEntriesHandlerTest extends TestCase
-{
- /**
- * @var resource
- */
- private $res;
-
- /**
- * @var LogEntriesHandler
- */
- private $handler;
-
- public function testWriteContent()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test'));
-
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content);
- }
-
- public function testWriteBatchContent()
- {
- $records = array(
- $this->getRecord(),
- $this->getRecord(),
- $this->getRecord(),
- );
- $this->createHandler();
- $this->handler->handleBatch($records);
-
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content);
- }
-
- private function createHandler()
- {
- $useSSL = extension_loaded('openssl');
- $args = array('testToken', $useSSL, Logger::DEBUG, true);
- $this->res = fopen('php://memory', 'a');
- $this->handler = $this->getMock(
- '\Monolog\Handler\LogEntriesHandler',
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
- $args
- );
-
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
-
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- $this->handler->expects($this->any())
- ->method('closeSocket')
- ->will($this->returnValue(true));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php
deleted file mode 100644
index 6754f3d6..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class MailHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\MailHandler::handleBatch
- */
- public function testHandleBatch()
- {
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter->expects($this->once())
- ->method('formatBatch'); // Each record is formatted
-
- $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
- $handler->expects($this->once())
- ->method('send');
- $handler->expects($this->never())
- ->method('write'); // write is for individual records
-
- $handler->setFormatter($formatter);
-
- $handler->handleBatch($this->getMultipleRecords());
- }
-
- /**
- * @covers Monolog\Handler\MailHandler::handleBatch
- */
- public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel()
- {
- $records = array(
- $this->getRecord(Logger::DEBUG, 'debug message 1'),
- $this->getRecord(Logger::DEBUG, 'debug message 2'),
- $this->getRecord(Logger::INFO, 'information'),
- );
-
- $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
- $handler->expects($this->never())
- ->method('send');
- $handler->setLevel(Logger::ERROR);
-
- $handler->handleBatch($records);
- }
-
- /**
- * @covers Monolog\Handler\MailHandler::write
- */
- public function testHandle()
- {
- $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
-
- $record = $this->getRecord();
- $records = array($record);
- $records[0]['formatted'] = '['.$record['datetime']->format('Y-m-d H:i:s').'] test.WARNING: test [] []'."\n";
-
- $handler->expects($this->once())
- ->method('send')
- ->with($records[0]['formatted'], $records);
-
- $handler->handle($record);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php b/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php
deleted file mode 100644
index a0833225..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Raven_Client;
-
-class MockRavenClient extends Raven_Client
-{
- public function capture($data, $stack, $vars = null)
- {
- $data = array_merge($this->get_user_data(), $data);
- $this->lastData = $data;
- $this->lastStack = $stack;
- }
-
- public $lastData;
- public $lastStack;
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php
deleted file mode 100644
index 0fdef63a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php
+++ /dev/null
@@ -1,65 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class MongoDBHandlerTest extends TestCase
-{
- /**
- * @expectedException InvalidArgumentException
- */
- public function testConstructorShouldThrowExceptionForInvalidMongo()
- {
- new MongoDBHandler(new \stdClass(), 'DB', 'Collection');
- }
-
- public function testHandle()
- {
- $mongo = $this->getMock('Mongo', array('selectCollection'), array(), '', false);
- $collection = $this->getMock('stdClass', array('save'));
-
- $mongo->expects($this->once())
- ->method('selectCollection')
- ->with('DB', 'Collection')
- ->will($this->returnValue($collection));
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $expected = array(
- 'message' => 'test',
- 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
- 'level' => Logger::WARNING,
- 'level_name' => 'WARNING',
- 'channel' => 'test',
- 'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
- 'extra' => array(),
- );
-
- $collection->expects($this->once())
- ->method('save')
- ->with($expected);
-
- $handler = new MongoDBHandler($mongo, 'DB', 'Collection');
- $handler->handle($record);
- }
-}
-
-if (!class_exists('Mongo')) {
- class Mongo
- {
- public function selectCollection()
- {
- }
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php
deleted file mode 100644
index ddf545db..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php
+++ /dev/null
@@ -1,111 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use InvalidArgumentException;
-
-function mail($to, $subject, $message, $additional_headers = null, $additional_parameters = null)
-{
- $GLOBALS['mail'][] = func_get_args();
-}
-
-class NativeMailerHandlerTest extends TestCase
-{
- protected function setUp()
- {
- $GLOBALS['mail'] = array();
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testConstructorHeaderInjection()
- {
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', "receiver@example.org\r\nFrom: faked@attacker.org");
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testSetterHeaderInjection()
- {
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
- $mailer->addHeader("Content-Type: text/html\r\nFrom: faked@attacker.org");
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testSetterArrayHeaderInjection()
- {
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
- $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org"));
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testSetterContentTypeInjection()
- {
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
- $mailer->setContentType("text/html\r\nFrom: faked@attacker.org");
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testSetterEncodingInjection()
- {
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
- $mailer->setEncoding("utf-8\r\nFrom: faked@attacker.org");
- }
-
- public function testSend()
- {
- $to = 'spammer@example.org';
- $subject = 'dear victim';
- $from = 'receiver@example.org';
-
- $mailer = new NativeMailerHandler($to, $subject, $from);
- $mailer->handleBatch(array());
-
- // batch is empty, nothing sent
- $this->assertEmpty($GLOBALS['mail']);
-
- // non-empty batch
- $mailer->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
- $this->assertNotEmpty($GLOBALS['mail']);
- $this->assertInternalType('array', $GLOBALS['mail']);
- $this->assertArrayHasKey('0', $GLOBALS['mail']);
- $params = $GLOBALS['mail'][0];
- $this->assertCount(5, $params);
- $this->assertSame($to, $params[0]);
- $this->assertSame($subject, $params[1]);
- $this->assertStringEndsWith(" test.ERROR: Foo Bar Baz [] []\n", $params[2]);
- $this->assertSame("From: $from\r\nContent-type: text/plain; charset=utf-8\r\n", $params[3]);
- $this->assertSame('', $params[4]);
- }
-
- public function testMessageSubjectFormatting()
- {
- $mailer = new NativeMailerHandler('to@example.org', 'Alert: %level_name% %message%', 'from@example.org');
- $mailer->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
- $this->assertNotEmpty($GLOBALS['mail']);
- $this->assertInternalType('array', $GLOBALS['mail']);
- $this->assertArrayHasKey('0', $GLOBALS['mail']);
- $params = $GLOBALS['mail'][0];
- $this->assertCount(5, $params);
- $this->assertSame('Alert: ERROR Foo Bar Baz', $params[1]);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php
deleted file mode 100644
index 4d3a615f..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php
+++ /dev/null
@@ -1,200 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Formatter\LineFormatter;
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class NewRelicHandlerTest extends TestCase
-{
- public static $appname;
- public static $customParameters;
- public static $transactionName;
-
- public function setUp()
- {
- self::$appname = null;
- self::$customParameters = array();
- self::$transactionName = null;
- }
-
- /**
- * @expectedException Monolog\Handler\MissingExtensionException
- */
- public function testThehandlerThrowsAnExceptionIfTheNRExtensionIsNotLoaded()
- {
- $handler = new StubNewRelicHandlerWithoutExtension();
- $handler->handle($this->getRecord(Logger::ERROR));
- }
-
- public function testThehandlerCanHandleTheRecord()
- {
- $handler = new StubNewRelicHandler();
- $handler->handle($this->getRecord(Logger::ERROR));
- }
-
- public function testThehandlerCanAddContextParamsToTheNewRelicTrace()
- {
- $handler = new StubNewRelicHandler();
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('a' => 'b')));
- $this->assertEquals(array('context_a' => 'b'), self::$customParameters);
- }
-
- public function testThehandlerCanAddExplodedContextParamsToTheNewRelicTrace()
- {
- $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true);
- $handler->handle($this->getRecord(
- Logger::ERROR,
- 'log message',
- array('a' => array('key1' => 'value1', 'key2' => 'value2'))
- ));
- $this->assertEquals(
- array('context_a_key1' => 'value1', 'context_a_key2' => 'value2'),
- self::$customParameters
- );
- }
-
- public function testThehandlerCanAddExtraParamsToTheNewRelicTrace()
- {
- $record = $this->getRecord(Logger::ERROR, 'log message');
- $record['extra'] = array('c' => 'd');
-
- $handler = new StubNewRelicHandler();
- $handler->handle($record);
-
- $this->assertEquals(array('extra_c' => 'd'), self::$customParameters);
- }
-
- public function testThehandlerCanAddExplodedExtraParamsToTheNewRelicTrace()
- {
- $record = $this->getRecord(Logger::ERROR, 'log message');
- $record['extra'] = array('c' => array('key1' => 'value1', 'key2' => 'value2'));
-
- $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true);
- $handler->handle($record);
-
- $this->assertEquals(
- array('extra_c_key1' => 'value1', 'extra_c_key2' => 'value2'),
- self::$customParameters
- );
- }
-
- public function testThehandlerCanAddExtraContextAndParamsToTheNewRelicTrace()
- {
- $record = $this->getRecord(Logger::ERROR, 'log message', array('a' => 'b'));
- $record['extra'] = array('c' => 'd');
-
- $handler = new StubNewRelicHandler();
- $handler->handle($record);
-
- $expected = array(
- 'context_a' => 'b',
- 'extra_c' => 'd',
- );
-
- $this->assertEquals($expected, self::$customParameters);
- }
-
- public function testThehandlerCanHandleTheRecordsFormattedUsingTheLineFormatter()
- {
- $handler = new StubNewRelicHandler();
- $handler->setFormatter(new LineFormatter());
- $handler->handle($this->getRecord(Logger::ERROR));
- }
-
- public function testTheAppNameIsNullByDefault()
- {
- $handler = new StubNewRelicHandler();
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
-
- $this->assertEquals(null, self::$appname);
- }
-
- public function testTheAppNameCanBeInjectedFromtheConstructor()
- {
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName');
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
-
- $this->assertEquals('myAppName', self::$appname);
- }
-
- public function testTheAppNameCanBeOverriddenFromEachLog()
- {
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName');
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('appname' => 'logAppName')));
-
- $this->assertEquals('logAppName', self::$appname);
- }
-
- public function testTheTransactionNameIsNullByDefault()
- {
- $handler = new StubNewRelicHandler();
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
-
- $this->assertEquals(null, self::$transactionName);
- }
-
- public function testTheTransactionNameCanBeInjectedFromTheConstructor()
- {
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction');
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
-
- $this->assertEquals('myTransaction', self::$transactionName);
- }
-
- public function testTheTransactionNameCanBeOverriddenFromEachLog()
- {
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction');
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('transaction_name' => 'logTransactName')));
-
- $this->assertEquals('logTransactName', self::$transactionName);
- }
-}
-
-class StubNewRelicHandlerWithoutExtension extends NewRelicHandler
-{
- protected function isNewRelicEnabled()
- {
- return false;
- }
-}
-
-class StubNewRelicHandler extends NewRelicHandler
-{
- protected function isNewRelicEnabled()
- {
- return true;
- }
-}
-
-function newrelic_notice_error()
-{
- return true;
-}
-
-function newrelic_set_appname($appname)
-{
- return NewRelicHandlerTest::$appname = $appname;
-}
-
-function newrelic_name_transaction($transactionName)
-{
- return NewRelicHandlerTest::$transactionName = $transactionName;
-}
-
-function newrelic_add_custom_parameter($key, $value)
-{
- NewRelicHandlerTest::$customParameters[$key] = $value;
-
- return true;
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php
deleted file mode 100644
index 292df78c..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\NullHandler::handle
- */
-class NullHandlerTest extends TestCase
-{
- public function testHandle()
- {
- $handler = new NullHandler();
- $this->assertTrue($handler->handle($this->getRecord()));
- }
-
- public function testHandleLowerLevelRecord()
- {
- $handler = new NullHandler(Logger::WARNING);
- $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php
deleted file mode 100644
index 152573ef..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php
+++ /dev/null
@@ -1,273 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Exception;
-use Monolog\ErrorHandler;
-use Monolog\Logger;
-use Monolog\TestCase;
-use PhpConsole\Connector;
-use PhpConsole\Dispatcher\Debug as DebugDispatcher;
-use PhpConsole\Dispatcher\Errors as ErrorDispatcher;
-use PhpConsole\Handler;
-use PHPUnit_Framework_MockObject_MockObject;
-
-/**
- * @covers Monolog\Handler\PHPConsoleHandler
- * @author Sergey Barbushin https://www.linkedin.com/in/barbushin
- */
-class PHPConsoleHandlerTest extends TestCase
-{
- /** @var Connector|PHPUnit_Framework_MockObject_MockObject */
- protected $connector;
- /** @var DebugDispatcher|PHPUnit_Framework_MockObject_MockObject */
- protected $debugDispatcher;
- /** @var ErrorDispatcher|PHPUnit_Framework_MockObject_MockObject */
- protected $errorDispatcher;
-
- protected function setUp()
- {
- if (!class_exists('PhpConsole\Connector')) {
- $this->markTestSkipped('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
- }
- $this->connector = $this->initConnectorMock();
-
- $this->debugDispatcher = $this->initDebugDispatcherMock($this->connector);
- $this->connector->setDebugDispatcher($this->debugDispatcher);
-
- $this->errorDispatcher = $this->initErrorDispatcherMock($this->connector);
- $this->connector->setErrorsDispatcher($this->errorDispatcher);
- }
-
- protected function initDebugDispatcherMock(Connector $connector)
- {
- return $this->getMockBuilder('PhpConsole\Dispatcher\Debug')
- ->disableOriginalConstructor()
- ->setMethods(array('dispatchDebug'))
- ->setConstructorArgs(array($connector, $connector->getDumper()))
- ->getMock();
- }
-
- protected function initErrorDispatcherMock(Connector $connector)
- {
- return $this->getMockBuilder('PhpConsole\Dispatcher\Errors')
- ->disableOriginalConstructor()
- ->setMethods(array('dispatchError', 'dispatchException'))
- ->setConstructorArgs(array($connector, $connector->getDumper()))
- ->getMock();
- }
-
- protected function initConnectorMock()
- {
- $connector = $this->getMockBuilder('PhpConsole\Connector')
- ->disableOriginalConstructor()
- ->setMethods(array(
- 'sendMessage',
- 'onShutDown',
- 'isActiveClient',
- 'setSourcesBasePath',
- 'setServerEncoding',
- 'setPassword',
- 'enableSslOnlyMode',
- 'setAllowedIpMasks',
- 'setHeadersLimit',
- 'startEvalRequestsListener',
- ))
- ->getMock();
-
- $connector->expects($this->any())
- ->method('isActiveClient')
- ->will($this->returnValue(true));
-
- return $connector;
- }
-
- protected function getHandlerDefaultOption($name)
- {
- $handler = new PHPConsoleHandler(array(), $this->connector);
- $options = $handler->getOptions();
-
- return $options[$name];
- }
-
- protected function initLogger($handlerOptions = array(), $level = Logger::DEBUG)
- {
- return new Logger('test', array(
- new PHPConsoleHandler($handlerOptions, $this->connector, $level),
- ));
- }
-
- public function testInitWithDefaultConnector()
- {
- $handler = new PHPConsoleHandler();
- $this->assertEquals(spl_object_hash(Connector::getInstance()), spl_object_hash($handler->getConnector()));
- }
-
- public function testInitWithCustomConnector()
- {
- $handler = new PHPConsoleHandler(array(), $this->connector);
- $this->assertEquals(spl_object_hash($this->connector), spl_object_hash($handler->getConnector()));
- }
-
- public function testDebug()
- {
- $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with($this->equalTo('test'));
- $this->initLogger()->addDebug('test');
- }
-
- public function testDebugContextInMessage()
- {
- $message = 'test';
- $tag = 'tag';
- $context = array($tag, 'custom' => mt_rand());
- $expectedMessage = $message . ' ' . json_encode(array_slice($context, 1));
- $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with(
- $this->equalTo($expectedMessage),
- $this->equalTo($tag)
- );
- $this->initLogger()->addDebug($message, $context);
- }
-
- public function testDebugTags($tagsContextKeys = null)
- {
- $expectedTags = mt_rand();
- $logger = $this->initLogger($tagsContextKeys ? array('debugTagsKeysInContext' => $tagsContextKeys) : array());
- if (!$tagsContextKeys) {
- $tagsContextKeys = $this->getHandlerDefaultOption('debugTagsKeysInContext');
- }
- foreach ($tagsContextKeys as $key) {
- $debugDispatcher = $this->initDebugDispatcherMock($this->connector);
- $debugDispatcher->expects($this->once())->method('dispatchDebug')->with(
- $this->anything(),
- $this->equalTo($expectedTags)
- );
- $this->connector->setDebugDispatcher($debugDispatcher);
- $logger->addDebug('test', array($key => $expectedTags));
- }
- }
-
- public function testError($classesPartialsTraceIgnore = null)
- {
- $code = E_USER_NOTICE;
- $message = 'message';
- $file = __FILE__;
- $line = __LINE__;
- $this->errorDispatcher->expects($this->once())->method('dispatchError')->with(
- $this->equalTo($code),
- $this->equalTo($message),
- $this->equalTo($file),
- $this->equalTo($line),
- $classesPartialsTraceIgnore ?: $this->equalTo($this->getHandlerDefaultOption('classesPartialsTraceIgnore'))
- );
- $errorHandler = ErrorHandler::register($this->initLogger($classesPartialsTraceIgnore ? array('classesPartialsTraceIgnore' => $classesPartialsTraceIgnore) : array()), false);
- $errorHandler->registerErrorHandler(array(), false, E_USER_WARNING);
- $errorHandler->handleError($code, $message, $file, $line);
- }
-
- public function testException()
- {
- $e = new Exception();
- $this->errorDispatcher->expects($this->once())->method('dispatchException')->with(
- $this->equalTo($e)
- );
- $handler = $this->initLogger();
- $handler->log(
- \Psr\Log\LogLevel::ERROR,
- sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
- array('exception' => $e)
- );
- }
-
- /**
- * @expectedException Exception
- */
- public function testWrongOptionsThrowsException()
- {
- new PHPConsoleHandler(array('xxx' => 1));
- }
-
- public function testOptionEnabled()
- {
- $this->debugDispatcher->expects($this->never())->method('dispatchDebug');
- $this->initLogger(array('enabled' => false))->addDebug('test');
- }
-
- public function testOptionClassesPartialsTraceIgnore()
- {
- $this->testError(array('Class', 'Namespace\\'));
- }
-
- public function testOptionDebugTagsKeysInContext()
- {
- $this->testDebugTags(array('key1', 'key2'));
- }
-
- public function testOptionUseOwnErrorsAndExceptionsHandler()
- {
- $this->initLogger(array('useOwnErrorsHandler' => true, 'useOwnExceptionsHandler' => true));
- $this->assertEquals(array(Handler::getInstance(), 'handleError'), set_error_handler(function () {
- }));
- $this->assertEquals(array(Handler::getInstance(), 'handleException'), set_exception_handler(function () {
- }));
- }
-
- public static function provideConnectorMethodsOptionsSets()
- {
- return array(
- array('sourcesBasePath', 'setSourcesBasePath', __DIR__),
- array('serverEncoding', 'setServerEncoding', 'cp1251'),
- array('password', 'setPassword', '******'),
- array('enableSslOnlyMode', 'enableSslOnlyMode', true, false),
- array('ipMasks', 'setAllowedIpMasks', array('127.0.0.*')),
- array('headersLimit', 'setHeadersLimit', 2500),
- array('enableEvalListener', 'startEvalRequestsListener', true, false),
- );
- }
-
- /**
- * @dataProvider provideConnectorMethodsOptionsSets
- */
- public function testOptionCallsConnectorMethod($option, $method, $value, $isArgument = true)
- {
- $expectCall = $this->connector->expects($this->once())->method($method);
- if ($isArgument) {
- $expectCall->with($value);
- }
- new PHPConsoleHandler(array($option => $value), $this->connector);
- }
-
- public function testOptionDetectDumpTraceAndSource()
- {
- new PHPConsoleHandler(array('detectDumpTraceAndSource' => true), $this->connector);
- $this->assertTrue($this->connector->getDebugDispatcher()->detectTraceAndSource);
- }
-
- public static function provideDumperOptionsValues()
- {
- return array(
- array('dumperLevelLimit', 'levelLimit', 1001),
- array('dumperItemsCountLimit', 'itemsCountLimit', 1002),
- array('dumperItemSizeLimit', 'itemSizeLimit', 1003),
- array('dumperDumpSizeLimit', 'dumpSizeLimit', 1004),
- array('dumperDetectCallbacks', 'detectCallbacks', true),
- );
- }
-
- /**
- * @dataProvider provideDumperOptionsValues
- */
- public function testDumperOptions($option, $dumperProperty, $value)
- {
- new PHPConsoleHandler(array($option => $value), $this->connector);
- $this->assertEquals($value, $this->connector->getDumper()->$dumperProperty);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php
deleted file mode 100644
index 64eaab16..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\PsrHandler::handle
- */
-class PsrHandlerTest extends TestCase
-{
- public function logLevelProvider()
- {
- $levels = array();
- $monologLogger = new Logger('');
-
- foreach ($monologLogger->getLevels() as $levelName => $level) {
- $levels[] = array($levelName, $level);
- }
-
- return $levels;
- }
-
- /**
- * @dataProvider logLevelProvider
- */
- public function testHandlesAllLevels($levelName, $level)
- {
- $message = 'Hello, world! ' . $level;
- $context = array('foo' => 'bar', 'level' => $level);
-
- $psrLogger = $this->getMock('Psr\Log\NullLogger');
- $psrLogger->expects($this->once())
- ->method('log')
- ->with(strtolower($levelName), $message, $context);
-
- $handler = new PsrHandler($psrLogger);
- $handler->handle(array('level' => $level, 'level_name' => $levelName, 'message' => $message, 'context' => $context));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php
deleted file mode 100644
index 56df474a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php
+++ /dev/null
@@ -1,141 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * Almost all examples (expected header, titles, messages) taken from
- * https://www.pushover.net/api
- * @author Sebastian Göttschkes
- * @see https://www.pushover.net/api
- */
-class PushoverHandlerTest extends TestCase
-{
- private $res;
- private $handler;
-
- public function testWriteHeader()
- {
- $this->createHandler();
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/1\/messages.json HTTP\/1.1\\r\\nHost: api.pushover.net\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
-
- return $content;
- }
-
- /**
- * @depends testWriteHeader
- */
- public function testWriteContent($content)
- {
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}$/', $content);
- }
-
- public function testWriteWithComplexTitle()
- {
- $this->createHandler('myToken', 'myUser', 'Backup finished - SQL1');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/title=Backup\+finished\+-\+SQL1/', $content);
- }
-
- public function testWriteWithComplexMessage()
- {
- $this->createHandler();
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
- }
-
- public function testWriteWithTooLongMessage()
- {
- $message = str_pad('test', 520, 'a');
- $this->createHandler();
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
- $this->handler->handle($this->getRecord(Logger::CRITICAL, $message));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $expectedMessage = substr($message, 0, 505);
-
- $this->assertRegexp('/message=' . $expectedMessage . '&title/', $content);
- }
-
- public function testWriteWithHighPriority()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}&priority=1$/', $content);
- }
-
- public function testWriteWithEmergencyPriority()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
- }
-
- public function testWriteToMultipleUsers()
- {
- $this->createHandler('myToken', array('userA', 'userB'));
- $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/token=myToken&user=userA&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200POST/', $content);
- $this->assertRegexp('/token=myToken&user=userB&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
- }
-
- private function createHandler($token = 'myToken', $user = 'myUser', $title = 'Monolog')
- {
- $constructorArgs = array($token, $user, $title);
- $this->res = fopen('php://memory', 'a');
- $this->handler = $this->getMock(
- '\Monolog\Handler\PushoverHandler',
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
- $constructorArgs
- );
-
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
-
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- $this->handler->expects($this->any())
- ->method('closeSocket')
- ->will($this->returnValue(true));
-
- $this->handler->setFormatter($this->getIdentityFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php
deleted file mode 100644
index 26d212b9..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php
+++ /dev/null
@@ -1,255 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-
-class RavenHandlerTest extends TestCase
-{
- public function setUp()
- {
- if (!class_exists('Raven_Client')) {
- $this->markTestSkipped('raven/raven not installed');
- }
-
- require_once __DIR__ . '/MockRavenClient.php';
- }
-
- /**
- * @covers Monolog\Handler\RavenHandler::__construct
- */
- public function testConstruct()
- {
- $handler = new RavenHandler($this->getRavenClient());
- $this->assertInstanceOf('Monolog\Handler\RavenHandler', $handler);
- }
-
- protected function getHandler($ravenClient)
- {
- $handler = new RavenHandler($ravenClient);
-
- return $handler;
- }
-
- protected function getRavenClient()
- {
- $dsn = 'http://43f6017361224d098402974103bfc53d:a6a0538fc2934ba2bed32e08741b2cd3@marca.python.live.cheggnet.com:9000/1';
-
- return new MockRavenClient($dsn);
- }
-
- public function testDebug()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $record = $this->getRecord(Logger::DEBUG, 'A test debug message');
- $handler->handle($record);
-
- $this->assertEquals($ravenClient::DEBUG, $ravenClient->lastData['level']);
- $this->assertContains($record['message'], $ravenClient->lastData['message']);
- }
-
- public function testWarning()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $record = $this->getRecord(Logger::WARNING, 'A test warning message');
- $handler->handle($record);
-
- $this->assertEquals($ravenClient::WARNING, $ravenClient->lastData['level']);
- $this->assertContains($record['message'], $ravenClient->lastData['message']);
- }
-
- public function testTag()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $tags = array(1, 2, 'foo');
- $record = $this->getRecord(Logger::INFO, 'test', array('tags' => $tags));
- $handler->handle($record);
-
- $this->assertEquals($tags, $ravenClient->lastData['tags']);
- }
-
- public function testExtraParameters()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $checksum = '098f6bcd4621d373cade4e832627b4f6';
- $release = '05a671c66aefea124cc08b76ea6d30bb';
- $eventId = '31423';
- $record = $this->getRecord(Logger::INFO, 'test', array('checksum' => $checksum, 'release' => $release, 'event_id' => $eventId));
- $handler->handle($record);
-
- $this->assertEquals($checksum, $ravenClient->lastData['checksum']);
- $this->assertEquals($release, $ravenClient->lastData['release']);
- $this->assertEquals($eventId, $ravenClient->lastData['event_id']);
- }
-
- public function testFingerprint()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $fingerprint = array('{{ default }}', 'other value');
- $record = $this->getRecord(Logger::INFO, 'test', array('fingerprint' => $fingerprint));
- $handler->handle($record);
-
- $this->assertEquals($fingerprint, $ravenClient->lastData['fingerprint']);
- }
-
- public function testUserContext()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $recordWithNoContext = $this->getRecord(Logger::INFO, 'test with default user context');
- // set user context 'externally'
-
- $user = array(
- 'id' => '123',
- 'email' => 'test@test.com',
- );
-
- $recordWithContext = $this->getRecord(Logger::INFO, 'test', array('user' => $user));
-
- $ravenClient->user_context(array('id' => 'test_user_id'));
- // handle context
- $handler->handle($recordWithContext);
- $this->assertEquals($user, $ravenClient->lastData['user']);
-
- // check to see if its reset
- $handler->handle($recordWithNoContext);
- $this->assertInternalType('array', $ravenClient->context->user);
- $this->assertSame('test_user_id', $ravenClient->context->user['id']);
-
- // handle with null context
- $ravenClient->user_context(null);
- $handler->handle($recordWithContext);
- $this->assertEquals($user, $ravenClient->lastData['user']);
-
- // check to see if its reset
- $handler->handle($recordWithNoContext);
- $this->assertNull($ravenClient->context->user);
- }
-
- public function testException()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- try {
- $this->methodThatThrowsAnException();
- } catch (\Exception $e) {
- $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('exception' => $e));
- $handler->handle($record);
- }
-
- $this->assertEquals($record['message'], $ravenClient->lastData['message']);
- }
-
- public function testHandleBatch()
- {
- $records = $this->getMultipleRecords();
- $records[] = $this->getRecord(Logger::WARNING, 'warning');
- $records[] = $this->getRecord(Logger::WARNING, 'warning');
-
- $logFormatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $logFormatter->expects($this->once())->method('formatBatch');
-
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter->expects($this->once())->method('format')->with($this->callback(function ($record) {
- return $record['level'] == 400;
- }));
-
- $handler = $this->getHandler($this->getRavenClient());
- $handler->setBatchFormatter($logFormatter);
- $handler->setFormatter($formatter);
- $handler->handleBatch($records);
- }
-
- public function testHandleBatchDoNothingIfRecordsAreBelowLevel()
- {
- $records = array(
- $this->getRecord(Logger::DEBUG, 'debug message 1'),
- $this->getRecord(Logger::DEBUG, 'debug message 2'),
- $this->getRecord(Logger::INFO, 'information'),
- );
-
- $handler = $this->getMock('Monolog\Handler\RavenHandler', null, array($this->getRavenClient()));
- $handler->expects($this->never())->method('handle');
- $handler->setLevel(Logger::ERROR);
- $handler->handleBatch($records);
- }
-
- public function testHandleBatchPicksProperMessage()
- {
- $records = array(
- $this->getRecord(Logger::DEBUG, 'debug message 1'),
- $this->getRecord(Logger::DEBUG, 'debug message 2'),
- $this->getRecord(Logger::INFO, 'information 1'),
- $this->getRecord(Logger::ERROR, 'error 1'),
- $this->getRecord(Logger::WARNING, 'warning'),
- $this->getRecord(Logger::ERROR, 'error 2'),
- $this->getRecord(Logger::INFO, 'information 2'),
- );
-
- $logFormatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $logFormatter->expects($this->once())->method('formatBatch');
-
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter->expects($this->once())->method('format')->with($this->callback(function ($record) use ($records) {
- return $record['message'] == 'error 1';
- }));
-
- $handler = $this->getHandler($this->getRavenClient());
- $handler->setBatchFormatter($logFormatter);
- $handler->setFormatter($formatter);
- $handler->handleBatch($records);
- }
-
- public function testGetSetBatchFormatter()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
-
- $handler->setBatchFormatter($formatter = new LineFormatter());
- $this->assertSame($formatter, $handler->getBatchFormatter());
- }
-
- public function testRelease()
- {
- $ravenClient = $this->getRavenClient();
- $handler = $this->getHandler($ravenClient);
- $release = 'v42.42.42';
- $handler->setRelease($release);
- $record = $this->getRecord(Logger::INFO, 'test');
- $handler->handle($record);
- $this->assertEquals($release, $ravenClient->lastData['release']);
-
- $localRelease = 'v41.41.41';
- $record = $this->getRecord(Logger::INFO, 'test', array('release' => $localRelease));
- $handler->handle($record);
- $this->assertEquals($localRelease, $ravenClient->lastData['release']);
- }
-
- private function methodThatThrowsAnException()
- {
- throw new \Exception('This is an exception');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php
deleted file mode 100644
index 689d5278..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php
+++ /dev/null
@@ -1,127 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-
-class RedisHandlerTest extends TestCase
-{
- /**
- * @expectedException InvalidArgumentException
- */
- public function testConstructorShouldThrowExceptionForInvalidRedis()
- {
- new RedisHandler(new \stdClass(), 'key');
- }
-
- public function testConstructorShouldWorkWithPredis()
- {
- $redis = $this->getMock('Predis\Client');
- $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
- }
-
- public function testConstructorShouldWorkWithRedis()
- {
- $redis = $this->getMock('Redis');
- $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
- }
-
- public function testPredisHandle()
- {
- $redis = $this->getMock('Predis\Client', array('rpush'));
-
- // Predis\Client uses rpush
- $redis->expects($this->once())
- ->method('rpush')
- ->with('key', 'test');
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $handler = new RedisHandler($redis, 'key');
- $handler->setFormatter(new LineFormatter("%message%"));
- $handler->handle($record);
- }
-
- public function testRedisHandle()
- {
- $redis = $this->getMock('Redis', array('rpush'));
-
- // Redis uses rPush
- $redis->expects($this->once())
- ->method('rPush')
- ->with('key', 'test');
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $handler = new RedisHandler($redis, 'key');
- $handler->setFormatter(new LineFormatter("%message%"));
- $handler->handle($record);
- }
-
- public function testRedisHandleCapped()
- {
- $redis = $this->getMock('Redis', array('multi', 'rpush', 'ltrim', 'exec'));
-
- // Redis uses multi
- $redis->expects($this->once())
- ->method('multi')
- ->will($this->returnSelf());
-
- $redis->expects($this->once())
- ->method('rpush')
- ->will($this->returnSelf());
-
- $redis->expects($this->once())
- ->method('ltrim')
- ->will($this->returnSelf());
-
- $redis->expects($this->once())
- ->method('exec')
- ->will($this->returnSelf());
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10);
- $handler->setFormatter(new LineFormatter("%message%"));
- $handler->handle($record);
- }
-
- public function testPredisHandleCapped()
- {
- $redis = $this->getMock('Predis\Client', array('transaction'));
-
- $redisTransaction = $this->getMock('Predis\Client', array('rpush', 'ltrim'));
-
- $redisTransaction->expects($this->once())
- ->method('rpush')
- ->will($this->returnSelf());
-
- $redisTransaction->expects($this->once())
- ->method('ltrim')
- ->will($this->returnSelf());
-
- // Redis uses multi
- $redis->expects($this->once())
- ->method('transaction')
- ->will($this->returnCallback(function ($cb) use ($redisTransaction) {
- $cb($redisTransaction);
- }));
-
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
-
- $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10);
- $handler->setFormatter(new LineFormatter("%message%"));
- $handler->handle($record);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RollbarHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RollbarHandlerTest.php
deleted file mode 100644
index f302e917..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/RollbarHandlerTest.php
+++ /dev/null
@@ -1,84 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Exception;
-use Monolog\TestCase;
-use Monolog\Logger;
-use PHPUnit_Framework_MockObject_MockObject as MockObject;
-
-/**
- * @author Erik Johansson
- * @see https://rollbar.com/docs/notifier/rollbar-php/
- *
- * @coversDefaultClass Monolog\Handler\RollbarHandler
- */
-class RollbarHandlerTest extends TestCase
-{
- /**
- * @var MockObject
- */
- private $rollbarNotifier;
-
- /**
- * @var array
- */
- public $reportedExceptionArguments = null;
-
- protected function setUp()
- {
- parent::setUp();
-
- $this->setupRollbarNotifierMock();
- }
-
- /**
- * When reporting exceptions to Rollbar the
- * level has to be set in the payload data
- */
- public function testExceptionLogLevel()
- {
- $handler = $this->createHandler();
-
- $handler->handle($this->createExceptionRecord(Logger::DEBUG));
-
- $this->assertEquals('debug', $this->reportedExceptionArguments['payload']['level']);
- }
-
- private function setupRollbarNotifierMock()
- {
- $this->rollbarNotifier = $this->getMockBuilder('RollbarNotifier')
- ->setMethods(array('report_message', 'report_exception', 'flush'))
- ->getMock();
-
- $that = $this;
-
- $this->rollbarNotifier
- ->expects($this->any())
- ->method('report_exception')
- ->willReturnCallback(function ($exception, $context, $payload) use ($that) {
- $that->reportedExceptionArguments = compact('exception', 'context', 'payload');
- });
- }
-
- private function createHandler()
- {
- return new RollbarHandler($this->rollbarNotifier, Logger::DEBUG);
- }
-
- private function createExceptionRecord($level = Logger::DEBUG, $message = 'test', $exception = null)
- {
- return $this->getRecord($level, $message, array(
- 'exception' => $exception ?: new Exception()
- ));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php
deleted file mode 100644
index f1feb228..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php
+++ /dev/null
@@ -1,211 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use PHPUnit_Framework_Error_Deprecated;
-
-/**
- * @covers Monolog\Handler\RotatingFileHandler
- */
-class RotatingFileHandlerTest extends TestCase
-{
- /**
- * This var should be private but then the anonymous function
- * in the `setUp` method won't be able to set it. `$this` cant't
- * be used in the anonymous function in `setUp` because PHP 5.3
- * does not support it.
- */
- public $lastError;
-
- public function setUp()
- {
- $dir = __DIR__.'/Fixtures';
- chmod($dir, 0777);
- if (!is_writable($dir)) {
- $this->markTestSkipped($dir.' must be writable to test the RotatingFileHandler.');
- }
- $this->lastError = null;
- $self = $this;
- // workaround with &$self used for PHP 5.3
- set_error_handler(function($code, $message) use (&$self) {
- $self->lastError = array(
- 'code' => $code,
- 'message' => $message,
- );
- });
- }
-
- private function assertErrorWasTriggered($code, $message)
- {
- if (empty($this->lastError)) {
- $this->fail(
- sprintf(
- 'Failed asserting that error with code `%d` and message `%s` was triggered',
- $code,
- $message
- )
- );
- }
- $this->assertEquals($code, $this->lastError['code'], sprintf('Expected an error with code %d to be triggered, got `%s` instead', $code, $this->lastError['code']));
- $this->assertEquals($message, $this->lastError['message'], sprintf('Expected an error with message `%d` to be triggered, got `%s` instead', $message, $this->lastError['message']));
- }
-
- public function testRotationCreatesNewFile()
- {
- touch(__DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot');
-
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord());
-
- $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
- $this->assertTrue(file_exists($log));
- $this->assertEquals('test', file_get_contents($log));
- }
-
- /**
- * @dataProvider rotationTests
- */
- public function testRotation($createFile, $dateFormat, $timeCallback)
- {
- touch($old1 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-1)).'.rot');
- touch($old2 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-2)).'.rot');
- touch($old3 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-3)).'.rot');
- touch($old4 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-4)).'.rot');
-
- $log = __DIR__.'/Fixtures/foo-'.date($dateFormat).'.rot';
-
- if ($createFile) {
- touch($log);
- }
-
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
- $handler->handle($this->getRecord());
-
- $handler->close();
-
- $this->assertTrue(file_exists($log));
- $this->assertTrue(file_exists($old1));
- $this->assertEquals($createFile, file_exists($old2));
- $this->assertEquals($createFile, file_exists($old3));
- $this->assertEquals($createFile, file_exists($old4));
- $this->assertEquals('test', file_get_contents($log));
- }
-
- public function rotationTests()
- {
- $now = time();
- $dayCallback = function($ago) use ($now) {
- return $now + 86400 * $ago;
- };
- $monthCallback = function($ago) {
- return gmmktime(0, 0, 0, date('n') + $ago, 1, date('Y'));
- };
- $yearCallback = function($ago) {
- return gmmktime(0, 0, 0, 1, 1, date('Y') + $ago);
- };
-
- return array(
- 'Rotation is triggered when the file of the current day is not present'
- => array(true, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
- 'Rotation is not triggered when the file of the current day is already present'
- => array(false, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
-
- 'Rotation is triggered when the file of the current month is not present'
- => array(true, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
- 'Rotation is not triggered when the file of the current month is already present'
- => array(false, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
-
- 'Rotation is triggered when the file of the current year is not present'
- => array(true, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
- 'Rotation is not triggered when the file of the current year is already present'
- => array(false, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
- );
- }
-
- /**
- * @dataProvider dateFormatProvider
- */
- public function testAllowOnlyFixedDefinedDateFormats($dateFormat, $valid)
- {
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
- $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
- if (!$valid) {
- $this->assertErrorWasTriggered(
- E_USER_DEPRECATED,
- 'Invalid date format - format must be one of RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), '.
- 'RotatingFileHandler::FILE_PER_MONTH ("Y-m") or RotatingFileHandler::FILE_PER_YEAR ("Y"), '.
- 'or you can set one of the date formats using slashes, underscores and/or dots instead of dashes.'
- );
- }
- }
-
- public function dateFormatProvider()
- {
- return array(
- array(RotatingFileHandler::FILE_PER_DAY, true),
- array(RotatingFileHandler::FILE_PER_MONTH, true),
- array(RotatingFileHandler::FILE_PER_YEAR, true),
- array('m-d-Y', false),
- array('Y-m-d-h-i', false)
- );
- }
-
- /**
- * @dataProvider filenameFormatProvider
- */
- public function testDisallowFilenameFormatsWithoutDate($filenameFormat, $valid)
- {
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
- $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY);
- if (!$valid) {
- $this->assertErrorWasTriggered(
- E_USER_DEPRECATED,
- 'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.'
- );
- }
- }
-
- public function filenameFormatProvider()
- {
- return array(
- array('{filename}', false),
- array('{filename}-{date}', true),
- array('{date}', true),
- array('foobar-{date}', true),
- array('foo-{date}-bar', true),
- array('{date}-foobar', true),
- array('foobar', false),
- );
- }
-
- public function testReuseCurrentFile()
- {
- $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
- file_put_contents($log, "foo");
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord());
- $this->assertEquals('footest', file_get_contents($log));
- }
-
- public function tearDown()
- {
- foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) {
- unlink($file);
- }
- restore_error_handler();
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php
deleted file mode 100644
index b354cee1..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-
-/**
- * @covers Monolog\Handler\SamplingHandler::handle
- */
-class SamplingHandlerTest extends TestCase
-{
- public function testHandle()
- {
- $testHandler = new TestHandler();
- $handler = new SamplingHandler($testHandler, 2);
- for ($i = 0; $i < 10000; $i++) {
- $handler->handle($this->getRecord());
- }
- $count = count($testHandler->getRecords());
- // $count should be half of 10k, so between 4k and 6k
- $this->assertLessThan(6000, $count);
- $this->assertGreaterThan(4000, $count);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/Slack/SlackRecordTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/Slack/SlackRecordTest.php
deleted file mode 100644
index e1aa96d7..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/Slack/SlackRecordTest.php
+++ /dev/null
@@ -1,387 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler\Slack;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-/**
- * @coversDefaultClass Monolog\Handler\Slack\SlackRecord
- */
-class SlackRecordTest extends TestCase
-{
- private $jsonPrettyPrintFlag;
-
- protected function setUp()
- {
- $this->jsonPrettyPrintFlag = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 128;
- }
-
- public function dataGetAttachmentColor()
- {
- return array(
- array(Logger::DEBUG, SlackRecord::COLOR_DEFAULT),
- array(Logger::INFO, SlackRecord::COLOR_GOOD),
- array(Logger::NOTICE, SlackRecord::COLOR_GOOD),
- array(Logger::WARNING, SlackRecord::COLOR_WARNING),
- array(Logger::ERROR, SlackRecord::COLOR_DANGER),
- array(Logger::CRITICAL, SlackRecord::COLOR_DANGER),
- array(Logger::ALERT, SlackRecord::COLOR_DANGER),
- array(Logger::EMERGENCY, SlackRecord::COLOR_DANGER),
- );
- }
-
- /**
- * @dataProvider dataGetAttachmentColor
- * @param int $logLevel
- * @param string $expectedColour RGB hex color or name of Slack color
- * @covers ::getAttachmentColor
- */
- public function testGetAttachmentColor($logLevel, $expectedColour)
- {
- $slackRecord = new SlackRecord();
- $this->assertSame(
- $expectedColour,
- $slackRecord->getAttachmentColor($logLevel)
- );
- }
-
- public function testAddsChannel()
- {
- $channel = '#test';
- $record = new SlackRecord($channel);
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayHasKey('channel', $data);
- $this->assertSame($channel, $data['channel']);
- }
-
- public function testNoUsernameByDefault()
- {
- $record = new SlackRecord();
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayNotHasKey('username', $data);
- }
-
- /**
- * @return array
- */
- public function dataStringify()
- {
- $jsonPrettyPrintFlag = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 128;
-
- $multipleDimensions = array(array(1, 2));
- $numericKeys = array('library' => 'monolog');
- $singleDimension = array(1, 'Hello', 'Jordi');
-
- return array(
- array(array(), '[]'),
- array($multipleDimensions, json_encode($multipleDimensions, $jsonPrettyPrintFlag)),
- array($numericKeys, json_encode($numericKeys, $jsonPrettyPrintFlag)),
- array($singleDimension, json_encode($singleDimension))
- );
- }
-
- /**
- * @dataProvider dataStringify
- */
- public function testStringify($fields, $expectedResult)
- {
- $slackRecord = new SlackRecord(
- '#test',
- 'test',
- true,
- null,
- true,
- true
- );
-
- $this->assertSame($expectedResult, $slackRecord->stringify($fields));
- }
-
- public function testAddsCustomUsername()
- {
- $username = 'Monolog bot';
- $record = new SlackRecord(null, $username);
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayHasKey('username', $data);
- $this->assertSame($username, $data['username']);
- }
-
- public function testNoIcon()
- {
- $record = new SlackRecord();
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayNotHasKey('icon_emoji', $data);
- }
-
- public function testAddsIcon()
- {
- $record = $this->getRecord();
- $slackRecord = new SlackRecord(null, null, false, 'ghost');
- $data = $slackRecord->getSlackData($record);
-
- $slackRecord2 = new SlackRecord(null, null, false, 'http://github.com/Seldaek/monolog');
- $data2 = $slackRecord2->getSlackData($record);
-
- $this->assertArrayHasKey('icon_emoji', $data);
- $this->assertSame(':ghost:', $data['icon_emoji']);
- $this->assertArrayHasKey('icon_url', $data2);
- $this->assertSame('http://github.com/Seldaek/monolog', $data2['icon_url']);
- }
-
- public function testAttachmentsNotPresentIfNoAttachment()
- {
- $record = new SlackRecord(null, null, false);
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayNotHasKey('attachments', $data);
- }
-
- public function testAddsOneAttachment()
- {
- $record = new SlackRecord();
- $data = $record->getSlackData($this->getRecord());
-
- $this->assertArrayHasKey('attachments', $data);
- $this->assertArrayHasKey(0, $data['attachments']);
- $this->assertInternalType('array', $data['attachments'][0]);
- }
-
- public function testTextEqualsMessageIfNoAttachment()
- {
- $message = 'Test message';
- $record = new SlackRecord(null, null, false);
- $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
-
- $this->assertArrayHasKey('text', $data);
- $this->assertSame($message, $data['text']);
- }
-
- public function testTextEqualsFormatterOutput()
- {
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter
- ->expects($this->any())
- ->method('format')
- ->will($this->returnCallback(function ($record) { return $record['message'] . 'test'; }));
-
- $formatter2 = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter2
- ->expects($this->any())
- ->method('format')
- ->will($this->returnCallback(function ($record) { return $record['message'] . 'test1'; }));
-
- $message = 'Test message';
- $record = new SlackRecord(null, null, false, null, false, false, array(), $formatter);
- $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
-
- $this->assertArrayHasKey('text', $data);
- $this->assertSame($message . 'test', $data['text']);
-
- $record->setFormatter($formatter2);
- $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
-
- $this->assertArrayHasKey('text', $data);
- $this->assertSame($message . 'test1', $data['text']);
- }
-
- public function testAddsFallbackAndTextToAttachment()
- {
- $message = 'Test message';
- $record = new SlackRecord(null);
- $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
-
- $this->assertSame($message, $data['attachments'][0]['text']);
- $this->assertSame($message, $data['attachments'][0]['fallback']);
- }
-
- public function testMapsLevelToColorAttachmentColor()
- {
- $record = new SlackRecord(null);
- $errorLoggerRecord = $this->getRecord(Logger::ERROR);
- $emergencyLoggerRecord = $this->getRecord(Logger::EMERGENCY);
- $warningLoggerRecord = $this->getRecord(Logger::WARNING);
- $infoLoggerRecord = $this->getRecord(Logger::INFO);
- $debugLoggerRecord = $this->getRecord(Logger::DEBUG);
-
- $data = $record->getSlackData($errorLoggerRecord);
- $this->assertSame(SlackRecord::COLOR_DANGER, $data['attachments'][0]['color']);
-
- $data = $record->getSlackData($emergencyLoggerRecord);
- $this->assertSame(SlackRecord::COLOR_DANGER, $data['attachments'][0]['color']);
-
- $data = $record->getSlackData($warningLoggerRecord);
- $this->assertSame(SlackRecord::COLOR_WARNING, $data['attachments'][0]['color']);
-
- $data = $record->getSlackData($infoLoggerRecord);
- $this->assertSame(SlackRecord::COLOR_GOOD, $data['attachments'][0]['color']);
-
- $data = $record->getSlackData($debugLoggerRecord);
- $this->assertSame(SlackRecord::COLOR_DEFAULT, $data['attachments'][0]['color']);
- }
-
- public function testAddsShortAttachmentWithoutContextAndExtra()
- {
- $level = Logger::ERROR;
- $levelName = Logger::getLevelName($level);
- $record = new SlackRecord(null, null, true, null, true);
- $data = $record->getSlackData($this->getRecord($level, 'test', array('test' => 1)));
-
- $attachment = $data['attachments'][0];
- $this->assertArrayHasKey('title', $attachment);
- $this->assertArrayHasKey('fields', $attachment);
- $this->assertSame($levelName, $attachment['title']);
- $this->assertSame(array(), $attachment['fields']);
- }
-
- public function testAddsShortAttachmentWithContextAndExtra()
- {
- $level = Logger::ERROR;
- $levelName = Logger::getLevelName($level);
- $context = array('test' => 1);
- $extra = array('tags' => array('web'));
- $record = new SlackRecord(null, null, true, null, true, true);
- $loggerRecord = $this->getRecord($level, 'test', $context);
- $loggerRecord['extra'] = $extra;
- $data = $record->getSlackData($loggerRecord);
-
- $attachment = $data['attachments'][0];
- $this->assertArrayHasKey('title', $attachment);
- $this->assertArrayHasKey('fields', $attachment);
- $this->assertCount(2, $attachment['fields']);
- $this->assertSame($levelName, $attachment['title']);
- $this->assertSame(
- array(
- array(
- 'title' => 'Extra',
- 'value' => sprintf('```%s```', json_encode($extra, $this->jsonPrettyPrintFlag)),
- 'short' => false
- ),
- array(
- 'title' => 'Context',
- 'value' => sprintf('```%s```', json_encode($context, $this->jsonPrettyPrintFlag)),
- 'short' => false
- )
- ),
- $attachment['fields']
- );
- }
-
- public function testAddsLongAttachmentWithoutContextAndExtra()
- {
- $level = Logger::ERROR;
- $levelName = Logger::getLevelName($level);
- $record = new SlackRecord(null, null, true, null);
- $data = $record->getSlackData($this->getRecord($level, 'test', array('test' => 1)));
-
- $attachment = $data['attachments'][0];
- $this->assertArrayHasKey('title', $attachment);
- $this->assertArrayHasKey('fields', $attachment);
- $this->assertCount(1, $attachment['fields']);
- $this->assertSame('Message', $attachment['title']);
- $this->assertSame(
- array(array(
- 'title' => 'Level',
- 'value' => $levelName,
- 'short' => false
- )),
- $attachment['fields']
- );
- }
-
- public function testAddsLongAttachmentWithContextAndExtra()
- {
- $level = Logger::ERROR;
- $levelName = Logger::getLevelName($level);
- $context = array('test' => 1);
- $extra = array('tags' => array('web'));
- $record = new SlackRecord(null, null, true, null, false, true);
- $loggerRecord = $this->getRecord($level, 'test', $context);
- $loggerRecord['extra'] = $extra;
- $data = $record->getSlackData($loggerRecord);
-
- $expectedFields = array(
- array(
- 'title' => 'Level',
- 'value' => $levelName,
- 'short' => false,
- ),
- array(
- 'title' => 'tags',
- 'value' => sprintf('```%s```', json_encode($extra['tags'])),
- 'short' => false
- ),
- array(
- 'title' => 'test',
- 'value' => $context['test'],
- 'short' => false
- )
- );
-
- $attachment = $data['attachments'][0];
- $this->assertArrayHasKey('title', $attachment);
- $this->assertArrayHasKey('fields', $attachment);
- $this->assertCount(3, $attachment['fields']);
- $this->assertSame('Message', $attachment['title']);
- $this->assertSame(
- $expectedFields,
- $attachment['fields']
- );
- }
-
- public function testAddsTimestampToAttachment()
- {
- $record = $this->getRecord();
- $slackRecord = new SlackRecord();
- $data = $slackRecord->getSlackData($this->getRecord());
-
- $attachment = $data['attachments'][0];
- $this->assertArrayHasKey('ts', $attachment);
- $this->assertSame($record['datetime']->getTimestamp(), $attachment['ts']);
- }
-
- public function testExcludeExtraAndContextFields()
- {
- $record = $this->getRecord(
- Logger::WARNING,
- 'test',
- array('info' => array('library' => 'monolog', 'author' => 'Jordi'))
- );
- $record['extra'] = array('tags' => array('web', 'cli'));
-
- $slackRecord = new SlackRecord(null, null, true, null, false, true, array('context.info.library', 'extra.tags.1'));
- $data = $slackRecord->getSlackData($record);
- $attachment = $data['attachments'][0];
-
- $expected = array(
- array(
- 'title' => 'info',
- 'value' => sprintf('```%s```', json_encode(array('author' => 'Jordi'), $this->jsonPrettyPrintFlag)),
- 'short' => false
- ),
- array(
- 'title' => 'tags',
- 'value' => sprintf('```%s```', json_encode(array('web'))),
- 'short' => false
- ),
- );
-
- foreach ($expected as $field) {
- $this->assertNotFalse(array_search($field, $attachment['fields']));
- break;
- }
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php
deleted file mode 100644
index b12b01f4..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php
+++ /dev/null
@@ -1,155 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Handler\Slack\SlackRecord;
-
-/**
- * @author Greg Kedzierski
- * @see https://api.slack.com/
- */
-class SlackHandlerTest extends TestCase
-{
- /**
- * @var resource
- */
- private $res;
-
- /**
- * @var SlackHandler
- */
- private $handler;
-
- public function setUp()
- {
- if (!extension_loaded('openssl')) {
- $this->markTestSkipped('This test requires openssl to run');
- }
- }
-
- public function testWriteHeader()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/POST \/api\/chat.postMessage HTTP\/1.1\\r\\nHost: slack.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
- }
-
- public function testWriteContent()
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegExp('/username=Monolog/', $content);
- $this->assertRegExp('/channel=channel1/', $content);
- $this->assertRegExp('/token=myToken/', $content);
- $this->assertRegExp('/attachments/', $content);
- }
-
- public function testWriteContentUsesFormatterIfProvided()
- {
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
- $this->handler->setFormatter(new LineFormatter('foo--%message%'));
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test2'));
- fseek($this->res, 0);
- $content2 = fread($this->res, 1024);
-
- $this->assertRegexp('/text=test1/', $content);
- $this->assertRegexp('/text=foo--test2/', $content2);
- }
-
- public function testWriteContentWithEmoji()
- {
- $this->createHandler('myToken', 'channel1', 'Monolog', true, 'alien');
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/icon_emoji=%3Aalien%3A/', $content);
- }
-
- /**
- * @dataProvider provideLevelColors
- */
- public function testWriteContentWithColors($level, $expectedColor)
- {
- $this->createHandler();
- $this->handler->handle($this->getRecord($level, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/%22color%22%3A%22'.$expectedColor.'/', $content);
- }
-
- public function testWriteContentWithPlainTextMessage()
- {
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
- fseek($this->res, 0);
- $content = fread($this->res, 1024);
-
- $this->assertRegexp('/text=test1/', $content);
- }
-
- public function provideLevelColors()
- {
- return array(
- array(Logger::DEBUG, urlencode(SlackRecord::COLOR_DEFAULT)),
- array(Logger::INFO, SlackRecord::COLOR_GOOD),
- array(Logger::NOTICE, SlackRecord::COLOR_GOOD),
- array(Logger::WARNING, SlackRecord::COLOR_WARNING),
- array(Logger::ERROR, SlackRecord::COLOR_DANGER),
- array(Logger::CRITICAL, SlackRecord::COLOR_DANGER),
- array(Logger::ALERT, SlackRecord::COLOR_DANGER),
- array(Logger::EMERGENCY,SlackRecord::COLOR_DANGER),
- );
- }
-
- private function createHandler($token = 'myToken', $channel = 'channel1', $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeExtra = false)
- {
- $constructorArgs = array($token, $channel, $username, $useAttachment, $iconEmoji, Logger::DEBUG, true, $useShortAttachment, $includeExtra);
- $this->res = fopen('php://memory', 'a');
- $this->handler = $this->getMock(
- '\Monolog\Handler\SlackHandler',
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
- $constructorArgs
- );
-
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
-
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- $this->handler->expects($this->any())
- ->method('closeSocket')
- ->will($this->returnValue(true));
-
- $this->handler->setFormatter($this->getIdentityFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SlackWebhookHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SlackWebhookHandlerTest.php
deleted file mode 100644
index c9229e26..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SlackWebhookHandlerTest.php
+++ /dev/null
@@ -1,107 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Handler\Slack\SlackRecord;
-
-/**
- * @author Haralan Dobrev
- * @see https://api.slack.com/incoming-webhooks
- * @coversDefaultClass Monolog\Handler\SlackWebhookHandler
- */
-class SlackWebhookHandlerTest extends TestCase
-{
- const WEBHOOK_URL = 'https://hooks.slack.com/services/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E';
-
- /**
- * @covers ::__construct
- * @covers ::getSlackRecord
- */
- public function testConstructorMinimal()
- {
- $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
- $record = $this->getRecord();
- $slackRecord = $handler->getSlackRecord();
- $this->assertInstanceOf('Monolog\Handler\Slack\SlackRecord', $slackRecord);
- $this->assertEquals(array(
- 'attachments' => array(
- array(
- 'fallback' => 'test',
- 'text' => 'test',
- 'color' => SlackRecord::COLOR_WARNING,
- 'fields' => array(
- array(
- 'title' => 'Level',
- 'value' => 'WARNING',
- 'short' => false,
- ),
- ),
- 'title' => 'Message',
- 'mrkdwn_in' => array('fields'),
- 'ts' => $record['datetime']->getTimestamp(),
- ),
- ),
- ), $slackRecord->getSlackData($record));
- }
-
- /**
- * @covers ::__construct
- * @covers ::getSlackRecord
- */
- public function testConstructorFull()
- {
- $handler = new SlackWebhookHandler(
- self::WEBHOOK_URL,
- 'test-channel',
- 'test-username',
- false,
- ':ghost:',
- false,
- false,
- Logger::DEBUG,
- false
- );
-
- $slackRecord = $handler->getSlackRecord();
- $this->assertInstanceOf('Monolog\Handler\Slack\SlackRecord', $slackRecord);
- $this->assertEquals(array(
- 'username' => 'test-username',
- 'text' => 'test',
- 'channel' => 'test-channel',
- 'icon_emoji' => ':ghost:',
- ), $slackRecord->getSlackData($this->getRecord()));
- }
-
- /**
- * @covers ::getFormatter
- */
- public function testGetFormatter()
- {
- $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
- $formatter = $handler->getFormatter();
- $this->assertInstanceOf('Monolog\Formatter\FormatterInterface', $formatter);
- }
-
- /**
- * @covers ::setFormatter
- */
- public function testSetFormatter()
- {
- $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
- $formatter = new LineFormatter();
- $handler->setFormatter($formatter);
- $this->assertSame($formatter, $handler->getFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SlackbotHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SlackbotHandlerTest.php
deleted file mode 100644
index b1b02bde..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SlackbotHandlerTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @author Haralan Dobrev
- * @see https://slack.com/apps/A0F81R8ET-slackbot
- * @coversDefaultClass Monolog\Handler\SlackbotHandler
- */
-class SlackbotHandlerTest extends TestCase
-{
- /**
- * @covers ::__construct
- */
- public function testConstructorMinimal()
- {
- $handler = new SlackbotHandler('test-team', 'test-token', 'test-channel');
- $this->assertInstanceOf('Monolog\Handler\AbstractProcessingHandler', $handler);
- }
-
- /**
- * @covers ::__construct
- */
- public function testConstructorFull()
- {
- $handler = new SlackbotHandler(
- 'test-team',
- 'test-token',
- 'test-channel',
- Logger::DEBUG,
- false
- );
- $this->assertInstanceOf('Monolog\Handler\AbstractProcessingHandler', $handler);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php
deleted file mode 100644
index 1f9c1f28..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php
+++ /dev/null
@@ -1,309 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @author Pablo de Leon Belloc
- */
-class SocketHandlerTest extends TestCase
-{
- /**
- * @var Monolog\Handler\SocketHandler
- */
- private $handler;
-
- /**
- * @var resource
- */
- private $res;
-
- /**
- * @expectedException UnexpectedValueException
- */
- public function testInvalidHostname()
- {
- $this->createHandler('garbage://here');
- $this->writeRecord('data');
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
- public function testBadConnectionTimeout()
- {
- $this->createHandler('localhost:1234');
- $this->handler->setConnectionTimeout(-1);
- }
-
- public function testSetConnectionTimeout()
- {
- $this->createHandler('localhost:1234');
- $this->handler->setConnectionTimeout(10.1);
- $this->assertEquals(10.1, $this->handler->getConnectionTimeout());
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
- public function testBadTimeout()
- {
- $this->createHandler('localhost:1234');
- $this->handler->setTimeout(-1);
- }
-
- public function testSetTimeout()
- {
- $this->createHandler('localhost:1234');
- $this->handler->setTimeout(10.25);
- $this->assertEquals(10.25, $this->handler->getTimeout());
- }
-
- public function testSetWritingTimeout()
- {
- $this->createHandler('localhost:1234');
- $this->handler->setWritingTimeout(10.25);
- $this->assertEquals(10.25, $this->handler->getWritingTimeout());
- }
-
- public function testSetConnectionString()
- {
- $this->createHandler('tcp://localhost:9090');
- $this->assertEquals('tcp://localhost:9090', $this->handler->getConnectionString());
- }
-
- /**
- * @expectedException UnexpectedValueException
- */
- public function testExceptionIsThrownOnFsockopenError()
- {
- $this->setMockHandler(array('fsockopen'));
- $this->handler->expects($this->once())
- ->method('fsockopen')
- ->will($this->returnValue(false));
- $this->writeRecord('Hello world');
- }
-
- /**
- * @expectedException UnexpectedValueException
- */
- public function testExceptionIsThrownOnPfsockopenError()
- {
- $this->setMockHandler(array('pfsockopen'));
- $this->handler->expects($this->once())
- ->method('pfsockopen')
- ->will($this->returnValue(false));
- $this->handler->setPersistent(true);
- $this->writeRecord('Hello world');
- }
-
- /**
- * @expectedException UnexpectedValueException
- */
- public function testExceptionIsThrownIfCannotSetTimeout()
- {
- $this->setMockHandler(array('streamSetTimeout'));
- $this->handler->expects($this->once())
- ->method('streamSetTimeout')
- ->will($this->returnValue(false));
- $this->writeRecord('Hello world');
- }
-
- /**
- * @expectedException RuntimeException
- */
- public function testWriteFailsOnIfFwriteReturnsFalse()
- {
- $this->setMockHandler(array('fwrite'));
-
- $callback = function ($arg) {
- $map = array(
- 'Hello world' => 6,
- 'world' => false,
- );
-
- return $map[$arg];
- };
-
- $this->handler->expects($this->exactly(2))
- ->method('fwrite')
- ->will($this->returnCallback($callback));
-
- $this->writeRecord('Hello world');
- }
-
- /**
- * @expectedException RuntimeException
- */
- public function testWriteFailsIfStreamTimesOut()
- {
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
-
- $callback = function ($arg) {
- $map = array(
- 'Hello world' => 6,
- 'world' => 5,
- );
-
- return $map[$arg];
- };
-
- $this->handler->expects($this->exactly(1))
- ->method('fwrite')
- ->will($this->returnCallback($callback));
- $this->handler->expects($this->exactly(1))
- ->method('streamGetMetadata')
- ->will($this->returnValue(array('timed_out' => true)));
-
- $this->writeRecord('Hello world');
- }
-
- /**
- * @expectedException RuntimeException
- */
- public function testWriteFailsOnIncompleteWrite()
- {
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
-
- $res = $this->res;
- $callback = function ($string) use ($res) {
- fclose($res);
-
- return strlen('Hello');
- };
-
- $this->handler->expects($this->exactly(1))
- ->method('fwrite')
- ->will($this->returnCallback($callback));
- $this->handler->expects($this->exactly(1))
- ->method('streamGetMetadata')
- ->will($this->returnValue(array('timed_out' => false)));
-
- $this->writeRecord('Hello world');
- }
-
- public function testWriteWithMemoryFile()
- {
- $this->setMockHandler();
- $this->writeRecord('test1');
- $this->writeRecord('test2');
- $this->writeRecord('test3');
- fseek($this->res, 0);
- $this->assertEquals('test1test2test3', fread($this->res, 1024));
- }
-
- public function testWriteWithMock()
- {
- $this->setMockHandler(array('fwrite'));
-
- $callback = function ($arg) {
- $map = array(
- 'Hello world' => 6,
- 'world' => 5,
- );
-
- return $map[$arg];
- };
-
- $this->handler->expects($this->exactly(2))
- ->method('fwrite')
- ->will($this->returnCallback($callback));
-
- $this->writeRecord('Hello world');
- }
-
- public function testClose()
- {
- $this->setMockHandler();
- $this->writeRecord('Hello world');
- $this->assertInternalType('resource', $this->res);
- $this->handler->close();
- $this->assertFalse(is_resource($this->res), "Expected resource to be closed after closing handler");
- }
-
- public function testCloseDoesNotClosePersistentSocket()
- {
- $this->setMockHandler();
- $this->handler->setPersistent(true);
- $this->writeRecord('Hello world');
- $this->assertTrue(is_resource($this->res));
- $this->handler->close();
- $this->assertTrue(is_resource($this->res));
- }
-
- /**
- * @expectedException \RuntimeException
- */
- public function testAvoidInfiniteLoopWhenNoDataIsWrittenForAWritingTimeoutSeconds()
- {
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
-
- $this->handler->expects($this->any())
- ->method('fwrite')
- ->will($this->returnValue(0));
-
- $this->handler->expects($this->any())
- ->method('streamGetMetadata')
- ->will($this->returnValue(array('timed_out' => false)));
-
- $this->handler->setWritingTimeout(1);
-
- $this->writeRecord('Hello world');
- }
-
- private function createHandler($connectionString)
- {
- $this->handler = new SocketHandler($connectionString);
- $this->handler->setFormatter($this->getIdentityFormatter());
- }
-
- private function writeRecord($string)
- {
- $this->handler->handle($this->getRecord(Logger::WARNING, $string));
- }
-
- private function setMockHandler(array $methods = array())
- {
- $this->res = fopen('php://memory', 'a');
-
- $defaultMethods = array('fsockopen', 'pfsockopen', 'streamSetTimeout');
- $newMethods = array_diff($methods, $defaultMethods);
-
- $finalMethods = array_merge($defaultMethods, $newMethods);
-
- $this->handler = $this->getMock(
- '\Monolog\Handler\SocketHandler', $finalMethods, array('localhost:1234')
- );
-
- if (!in_array('fsockopen', $methods)) {
- $this->handler->expects($this->any())
- ->method('fsockopen')
- ->will($this->returnValue($this->res));
- }
-
- if (!in_array('pfsockopen', $methods)) {
- $this->handler->expects($this->any())
- ->method('pfsockopen')
- ->will($this->returnValue($this->res));
- }
-
- if (!in_array('streamSetTimeout', $methods)) {
- $this->handler->expects($this->any())
- ->method('streamSetTimeout')
- ->will($this->returnValue(true));
- }
-
- $this->handler->setFormatter($this->getIdentityFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php
deleted file mode 100644
index 487030fe..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php
+++ /dev/null
@@ -1,184 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class StreamHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWrite()
- {
- $handle = fopen('php://memory', 'a+');
- $handler = new StreamHandler($handle);
- $handler->setFormatter($this->getIdentityFormatter());
- $handler->handle($this->getRecord(Logger::WARNING, 'test'));
- $handler->handle($this->getRecord(Logger::WARNING, 'test2'));
- $handler->handle($this->getRecord(Logger::WARNING, 'test3'));
- fseek($handle, 0);
- $this->assertEquals('testtest2test3', fread($handle, 100));
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::close
- */
- public function testCloseKeepsExternalHandlersOpen()
- {
- $handle = fopen('php://memory', 'a+');
- $handler = new StreamHandler($handle);
- $this->assertTrue(is_resource($handle));
- $handler->close();
- $this->assertTrue(is_resource($handle));
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::close
- */
- public function testClose()
- {
- $handler = new StreamHandler('php://memory');
- $handler->handle($this->getRecord(Logger::WARNING, 'test'));
- $streamProp = new \ReflectionProperty('Monolog\Handler\StreamHandler', 'stream');
- $streamProp->setAccessible(true);
- $handle = $streamProp->getValue($handler);
-
- $this->assertTrue(is_resource($handle));
- $handler->close();
- $this->assertFalse(is_resource($handle));
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteCreatesTheStreamResource()
- {
- $handler = new StreamHandler('php://memory');
- $handler->handle($this->getRecord());
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteLocking()
- {
- $temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'monolog_locked_log';
- $handler = new StreamHandler($temp, Logger::DEBUG, true, null, true);
- $handler->handle($this->getRecord());
- }
-
- /**
- * @expectedException LogicException
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteMissingResource()
- {
- $handler = new StreamHandler(null);
- $handler->handle($this->getRecord());
- }
-
- public function invalidArgumentProvider()
- {
- return array(
- array(1),
- array(array()),
- array(array('bogus://url')),
- );
- }
-
- /**
- * @dataProvider invalidArgumentProvider
- * @expectedException InvalidArgumentException
- * @covers Monolog\Handler\StreamHandler::__construct
- */
- public function testWriteInvalidArgument($invalidArgument)
- {
- $handler = new StreamHandler($invalidArgument);
- }
-
- /**
- * @expectedException UnexpectedValueException
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteInvalidResource()
- {
- $handler = new StreamHandler('bogus://url');
- $handler->handle($this->getRecord());
- }
-
- /**
- * @expectedException UnexpectedValueException
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteNonExistingResource()
- {
- $handler = new StreamHandler('ftp://foo/bar/baz/'.rand(0, 10000));
- $handler->handle($this->getRecord());
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteNonExistingPath()
- {
- $handler = new StreamHandler(sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
- $handler->handle($this->getRecord());
- }
-
- /**
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteNonExistingFileResource()
- {
- $handler = new StreamHandler('file://'.sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
- $handler->handle($this->getRecord());
- }
-
- /**
- * @expectedException Exception
- * @expectedExceptionMessageRegExp /There is no existing directory at/
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteNonExistingAndNotCreatablePath()
- {
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
- $this->markTestSkipped('Permissions checks can not run on windows');
- }
- $handler = new StreamHandler('/foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
- $handler->handle($this->getRecord());
- }
-
- /**
- * @expectedException Exception
- * @expectedExceptionMessageRegExp /There is no existing directory at/
- * @covers Monolog\Handler\StreamHandler::__construct
- * @covers Monolog\Handler\StreamHandler::write
- */
- public function testWriteNonExistingAndNotCreatableFileResource()
- {
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
- $this->markTestSkipped('Permissions checks can not run on windows');
- }
- $handler = new StreamHandler('file:///foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
- $handler->handle($this->getRecord());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php
deleted file mode 100644
index 1d62940f..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php
+++ /dev/null
@@ -1,113 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-
-class SwiftMailerHandlerTest extends TestCase
-{
- /** @var \Swift_Mailer|\PHPUnit_Framework_MockObject_MockObject */
- private $mailer;
-
- public function setUp()
- {
- $this->mailer = $this
- ->getMockBuilder('Swift_Mailer')
- ->disableOriginalConstructor()
- ->getMock();
- }
-
- public function testMessageCreationIsLazyWhenUsingCallback()
- {
- $this->mailer->expects($this->never())
- ->method('send');
-
- $callback = function () {
- throw new \RuntimeException('Swift_Message creation callback should not have been called in this test');
- };
- $handler = new SwiftMailerHandler($this->mailer, $callback);
-
- $records = array(
- $this->getRecord(Logger::DEBUG),
- $this->getRecord(Logger::INFO),
- );
- $handler->handleBatch($records);
- }
-
- public function testMessageCanBeCustomizedGivenLoggedData()
- {
- // Wire Mailer to expect a specific Swift_Message with a customized Subject
- $expectedMessage = new \Swift_Message();
- $this->mailer->expects($this->once())
- ->method('send')
- ->with($this->callback(function ($value) use ($expectedMessage) {
- return $value instanceof \Swift_Message
- && $value->getSubject() === 'Emergency'
- && $value === $expectedMessage;
- }));
-
- // Callback dynamically changes subject based on number of logged records
- $callback = function ($content, array $records) use ($expectedMessage) {
- $subject = count($records) > 0 ? 'Emergency' : 'Normal';
- $expectedMessage->setSubject($subject);
-
- return $expectedMessage;
- };
- $handler = new SwiftMailerHandler($this->mailer, $callback);
-
- // Logging 1 record makes this an Emergency
- $records = array(
- $this->getRecord(Logger::EMERGENCY),
- );
- $handler->handleBatch($records);
- }
-
- public function testMessageSubjectFormatting()
- {
- // Wire Mailer to expect a specific Swift_Message with a customized Subject
- $messageTemplate = new \Swift_Message();
- $messageTemplate->setSubject('Alert: %level_name% %message%');
- $receivedMessage = null;
-
- $this->mailer->expects($this->once())
- ->method('send')
- ->with($this->callback(function ($value) use (&$receivedMessage) {
- $receivedMessage = $value;
- return true;
- }));
-
- $handler = new SwiftMailerHandler($this->mailer, $messageTemplate);
-
- $records = array(
- $this->getRecord(Logger::EMERGENCY),
- );
- $handler->handleBatch($records);
-
- $this->assertEquals('Alert: EMERGENCY test', $receivedMessage->getSubject());
- }
-
- public function testMessageHaveUniqueId()
- {
- $messageTemplate = new \Swift_Message();
- $handler = new SwiftMailerHandler($this->mailer, $messageTemplate);
-
- $method = new \ReflectionMethod('Monolog\Handler\SwiftMailerHandler', 'buildMessage');
- $method->setAccessible(true);
- $method->invokeArgs($handler, array($messageTemplate, array()));
-
- $builtMessage1 = $method->invoke($handler, $messageTemplate, array());
- $builtMessage2 = $method->invoke($handler, $messageTemplate, array());
-
- $this->assertFalse($builtMessage1->getId() === $builtMessage2->getId(), 'Two different messages have the same id');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php
deleted file mode 100644
index 8f9e46bf..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\Logger;
-
-class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @covers Monolog\Handler\SyslogHandler::__construct
- */
- public function testConstruct()
- {
- $handler = new SyslogHandler('test');
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
-
- $handler = new SyslogHandler('test', LOG_USER);
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
-
- $handler = new SyslogHandler('test', 'user');
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
-
- $handler = new SyslogHandler('test', LOG_USER, Logger::DEBUG, true, LOG_PERROR);
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
- }
-
- /**
- * @covers Monolog\Handler\SyslogHandler::__construct
- */
- public function testConstructInvalidFacility()
- {
- $this->setExpectedException('UnexpectedValueException');
- $handler = new SyslogHandler('test', 'unknown');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php
deleted file mode 100644
index 7ee8a985..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php
+++ /dev/null
@@ -1,76 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-
-/**
- * @requires extension sockets
- */
-class SyslogUdpHandlerTest extends TestCase
-{
- /**
- * @expectedException UnexpectedValueException
- */
- public function testWeValidateFacilities()
- {
- $handler = new SyslogUdpHandler("ip", null, "invalidFacility");
- }
-
- public function testWeSplitIntoLines()
- {
- $time = '2014-01-07T12:34';
- $pid = getmypid();
- $host = gethostname();
-
- $handler = $this->getMockBuilder('\Monolog\Handler\SyslogUdpHandler')
- ->setConstructorArgs(array("127.0.0.1", 514, "authpriv"))
- ->setMethods(array('getDateTime'))
- ->getMock();
-
- $handler->method('getDateTime')
- ->willReturn($time);
-
- $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter());
-
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol'));
- $socket->expects($this->at(0))
- ->method('write')
- ->with("lol", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 $time $host php $pid - - ");
- $socket->expects($this->at(1))
- ->method('write')
- ->with("hej", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 $time $host php $pid - - ");
-
- $handler->setSocket($socket);
-
- $handler->handle($this->getRecordWithMessage("hej\nlol"));
- }
-
- public function testSplitWorksOnEmptyMsg()
- {
- $handler = new SyslogUdpHandler("127.0.0.1", 514, "authpriv");
- $handler->setFormatter($this->getIdentityFormatter());
-
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol'));
- $socket->expects($this->never())
- ->method('write');
-
- $handler->setSocket($socket);
-
- $handler->handle($this->getRecordWithMessage(null));
- }
-
- protected function getRecordWithMessage($msg)
- {
- return array('message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => array(), 'channel' => 'lol');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php
deleted file mode 100644
index bfb8d3df..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php
+++ /dev/null
@@ -1,70 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-/**
- * @covers Monolog\Handler\TestHandler
- */
-class TestHandlerTest extends TestCase
-{
- /**
- * @dataProvider methodProvider
- */
- public function testHandler($method, $level)
- {
- $handler = new TestHandler;
- $record = $this->getRecord($level, 'test'.$method);
- $this->assertFalse($handler->hasRecords($level));
- $this->assertFalse($handler->hasRecord($record, $level));
- $this->assertFalse($handler->{'has'.$method}($record), 'has'.$method);
- $this->assertFalse($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains');
- $this->assertFalse($handler->{'has'.$method.'ThatPasses'}(function ($rec) {
- return true;
- }), 'has'.$method.'ThatPasses');
- $this->assertFalse($handler->{'has'.$method.'ThatMatches'}('/test\w+/'));
- $this->assertFalse($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records');
- $handler->handle($record);
-
- $this->assertFalse($handler->{'has'.$method}('bar'), 'has'.$method);
- $this->assertTrue($handler->hasRecords($level));
- $this->assertTrue($handler->hasRecord($record, $level));
- $this->assertTrue($handler->{'has'.$method}($record), 'has'.$method);
- $this->assertTrue($handler->{'has'.$method}('test'.$method), 'has'.$method);
- $this->assertTrue($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains');
- $this->assertTrue($handler->{'has'.$method.'ThatPasses'}(function ($rec) {
- return true;
- }), 'has'.$method.'ThatPasses');
- $this->assertTrue($handler->{'has'.$method.'ThatMatches'}('/test\w+/'));
- $this->assertTrue($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records');
-
- $records = $handler->getRecords();
- unset($records[0]['formatted']);
- $this->assertEquals(array($record), $records);
- }
-
- public function methodProvider()
- {
- return array(
- array('Emergency', Logger::EMERGENCY),
- array('Alert' , Logger::ALERT),
- array('Critical' , Logger::CRITICAL),
- array('Error' , Logger::ERROR),
- array('Warning' , Logger::WARNING),
- array('Info' , Logger::INFO),
- array('Notice' , Logger::NOTICE),
- array('Debug' , Logger::DEBUG),
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php
deleted file mode 100644
index fa524d00..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Handler\SyslogUdp\UdpSocket;
-
-/**
- * @requires extension sockets
- */
-class UdpSocketTest extends TestCase
-{
- public function testWeDoNotTruncateShortMessages()
- {
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
-
- $socket->expects($this->at(0))
- ->method('send')
- ->with("HEADER: The quick brown fox jumps over the lazy dog");
-
- $socket->write("The quick brown fox jumps over the lazy dog", "HEADER: ");
- }
-
- public function testLongMessagesAreTruncated()
- {
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
-
- $truncatedString = str_repeat("derp", 16254).'d';
-
- $socket->expects($this->exactly(1))
- ->method('send')
- ->with("HEADER" . $truncatedString);
-
- $longString = str_repeat("derp", 20000);
-
- $socket->write($longString, "HEADER");
- }
-
- public function testDoubleCloseDoesNotError()
- {
- $socket = new UdpSocket('127.0.0.1', 514);
- $socket->close();
- $socket->close();
- }
-
- /**
- * @expectedException LogicException
- */
- public function testWriteAfterCloseErrors()
- {
- $socket = new UdpSocket('127.0.0.1', 514);
- $socket->close();
- $socket->write('foo', "HEADER");
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php
deleted file mode 100644
index 8d37a1fc..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php
+++ /dev/null
@@ -1,121 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-use Monolog\Logger;
-
-class WhatFailureGroupHandlerTest extends TestCase
-{
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::__construct
- * @expectedException InvalidArgumentException
- */
- public function testConstructorOnlyTakesHandler()
- {
- new WhatFailureGroupHandler(array(new TestHandler(), "foo"));
- }
-
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::__construct
- * @covers Monolog\Handler\WhatFailureGroupHandler::handle
- */
- public function testHandle()
- {
- $testHandlers = array(new TestHandler(), new TestHandler());
- $handler = new WhatFailureGroupHandler($testHandlers);
- $handler->handle($this->getRecord(Logger::DEBUG));
- $handler->handle($this->getRecord(Logger::INFO));
- foreach ($testHandlers as $test) {
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- }
- }
-
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::handleBatch
- */
- public function testHandleBatch()
- {
- $testHandlers = array(new TestHandler(), new TestHandler());
- $handler = new WhatFailureGroupHandler($testHandlers);
- $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
- foreach ($testHandlers as $test) {
- $this->assertTrue($test->hasDebugRecords());
- $this->assertTrue($test->hasInfoRecords());
- $this->assertTrue(count($test->getRecords()) === 2);
- }
- }
-
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::isHandling
- */
- public function testIsHandling()
- {
- $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING));
- $handler = new WhatFailureGroupHandler($testHandlers);
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR)));
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING)));
- $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
- }
-
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::handle
- */
- public function testHandleUsesProcessors()
- {
- $test = new TestHandler();
- $handler = new WhatFailureGroupHandler(array($test));
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-
- /**
- * @covers Monolog\Handler\WhatFailureGroupHandler::handle
- */
- public function testHandleException()
- {
- $test = new TestHandler();
- $exception = new ExceptionTestHandler();
- $handler = new WhatFailureGroupHandler(array($exception, $test, $exception));
- $handler->pushProcessor(function ($record) {
- $record['extra']['foo'] = true;
-
- return $record;
- });
- $handler->handle($this->getRecord(Logger::WARNING));
- $this->assertTrue($test->hasWarningRecords());
- $records = $test->getRecords();
- $this->assertTrue($records[0]['extra']['foo']);
- }
-}
-
-class ExceptionTestHandler extends TestHandler
-{
- /**
- * {@inheritdoc}
- */
- public function handle(array $record)
- {
- parent::handle($record);
-
- throw new \Exception("ExceptionTestHandler::handle");
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php
deleted file mode 100644
index 69b001ea..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Handler;
-
-use Monolog\TestCase;
-
-class ZendMonitorHandlerTest extends TestCase
-{
- protected $zendMonitorHandler;
-
- public function setUp()
- {
- if (!function_exists('zend_monitor_custom_event')) {
- $this->markTestSkipped('ZendServer is not installed');
- }
- }
-
- /**
- * @covers Monolog\Handler\ZendMonitorHandler::write
- */
- public function testWrite()
- {
- $record = $this->getRecord();
- $formatterResult = array(
- 'message' => $record['message'],
- );
-
- $zendMonitor = $this->getMockBuilder('Monolog\Handler\ZendMonitorHandler')
- ->setMethods(array('writeZendMonitorCustomEvent', 'getDefaultFormatter'))
- ->getMock();
-
- $formatterMock = $this->getMockBuilder('Monolog\Formatter\NormalizerFormatter')
- ->disableOriginalConstructor()
- ->getMock();
-
- $formatterMock->expects($this->once())
- ->method('format')
- ->will($this->returnValue($formatterResult));
-
- $zendMonitor->expects($this->once())
- ->method('getDefaultFormatter')
- ->will($this->returnValue($formatterMock));
-
- $levelMap = $zendMonitor->getLevelMap();
-
- $zendMonitor->expects($this->once())
- ->method('writeZendMonitorCustomEvent')
- ->with($levelMap[$record['level']], $record['message'], $formatterResult);
-
- $zendMonitor->handle($record);
- }
-
- /**
- * @covers Monolog\Handler\ZendMonitorHandler::getDefaultFormatter
- */
- public function testGetDefaultFormatterReturnsNormalizerFormatter()
- {
- $zendMonitor = new ZendMonitorHandler();
- $this->assertInstanceOf('Monolog\Formatter\NormalizerFormatter', $zendMonitor->getDefaultFormatter());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/LoggerTest.php b/vendor/monolog/monolog/tests/Monolog/LoggerTest.php
deleted file mode 100644
index 1ecc34a0..00000000
--- a/vendor/monolog/monolog/tests/Monolog/LoggerTest.php
+++ /dev/null
@@ -1,548 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-use Monolog\Processor\WebProcessor;
-use Monolog\Handler\TestHandler;
-
-class LoggerTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @covers Monolog\Logger::getName
- */
- public function testGetName()
- {
- $logger = new Logger('foo');
- $this->assertEquals('foo', $logger->getName());
- }
-
- /**
- * @covers Monolog\Logger::getLevelName
- */
- public function testGetLevelName()
- {
- $this->assertEquals('ERROR', Logger::getLevelName(Logger::ERROR));
- }
-
- /**
- * @covers Monolog\Logger::withName
- */
- public function testWithName()
- {
- $first = new Logger('first', array($handler = new TestHandler()));
- $second = $first->withName('second');
-
- $this->assertSame('first', $first->getName());
- $this->assertSame('second', $second->getName());
- $this->assertSame($handler, $second->popHandler());
- }
-
- /**
- * @covers Monolog\Logger::toMonologLevel
- */
- public function testConvertPSR3ToMonologLevel()
- {
- $this->assertEquals(Logger::toMonologLevel('debug'), 100);
- $this->assertEquals(Logger::toMonologLevel('info'), 200);
- $this->assertEquals(Logger::toMonologLevel('notice'), 250);
- $this->assertEquals(Logger::toMonologLevel('warning'), 300);
- $this->assertEquals(Logger::toMonologLevel('error'), 400);
- $this->assertEquals(Logger::toMonologLevel('critical'), 500);
- $this->assertEquals(Logger::toMonologLevel('alert'), 550);
- $this->assertEquals(Logger::toMonologLevel('emergency'), 600);
- }
-
- /**
- * @covers Monolog\Logger::getLevelName
- * @expectedException InvalidArgumentException
- */
- public function testGetLevelNameThrows()
- {
- Logger::getLevelName(5);
- }
-
- /**
- * @covers Monolog\Logger::__construct
- */
- public function testChannel()
- {
- $logger = new Logger('foo');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->addWarning('test');
- list($record) = $handler->getRecords();
- $this->assertEquals('foo', $record['channel']);
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testLog()
- {
- $logger = new Logger(__METHOD__);
-
- $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
- $handler->expects($this->once())
- ->method('handle');
- $logger->pushHandler($handler);
-
- $this->assertTrue($logger->addWarning('test'));
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testLogNotHandled()
- {
- $logger = new Logger(__METHOD__);
-
- $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR));
- $handler->expects($this->never())
- ->method('handle');
- $logger->pushHandler($handler);
-
- $this->assertFalse($logger->addWarning('test'));
- }
-
- public function testHandlersInCtor()
- {
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
- $logger = new Logger(__METHOD__, array($handler1, $handler2));
-
- $this->assertEquals($handler1, $logger->popHandler());
- $this->assertEquals($handler2, $logger->popHandler());
- }
-
- public function testProcessorsInCtor()
- {
- $processor1 = new WebProcessor;
- $processor2 = new WebProcessor;
- $logger = new Logger(__METHOD__, array(), array($processor1, $processor2));
-
- $this->assertEquals($processor1, $logger->popProcessor());
- $this->assertEquals($processor2, $logger->popProcessor());
- }
-
- /**
- * @covers Monolog\Logger::pushHandler
- * @covers Monolog\Logger::popHandler
- * @expectedException LogicException
- */
- public function testPushPopHandler()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
-
- $logger->pushHandler($handler1);
- $logger->pushHandler($handler2);
-
- $this->assertEquals($handler2, $logger->popHandler());
- $this->assertEquals($handler1, $logger->popHandler());
- $logger->popHandler();
- }
-
- /**
- * @covers Monolog\Logger::setHandlers
- */
- public function testSetHandlers()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
-
- $logger->pushHandler($handler1);
- $logger->setHandlers(array($handler2));
-
- // handler1 has been removed
- $this->assertEquals(array($handler2), $logger->getHandlers());
-
- $logger->setHandlers(array(
- "AMapKey" => $handler1,
- "Woop" => $handler2,
- ));
-
- // Keys have been scrubbed
- $this->assertEquals(array($handler1, $handler2), $logger->getHandlers());
- }
-
- /**
- * @covers Monolog\Logger::pushProcessor
- * @covers Monolog\Logger::popProcessor
- * @expectedException LogicException
- */
- public function testPushPopProcessor()
- {
- $logger = new Logger(__METHOD__);
- $processor1 = new WebProcessor;
- $processor2 = new WebProcessor;
-
- $logger->pushProcessor($processor1);
- $logger->pushProcessor($processor2);
-
- $this->assertEquals($processor2, $logger->popProcessor());
- $this->assertEquals($processor1, $logger->popProcessor());
- $logger->popProcessor();
- }
-
- /**
- * @covers Monolog\Logger::pushProcessor
- * @expectedException InvalidArgumentException
- */
- public function testPushProcessorWithNonCallable()
- {
- $logger = new Logger(__METHOD__);
-
- $logger->pushProcessor(new \stdClass());
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testProcessorsAreExecuted()
- {
- $logger = new Logger(__METHOD__);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->pushProcessor(function ($record) {
- $record['extra']['win'] = true;
-
- return $record;
- });
- $logger->addError('test');
- list($record) = $handler->getRecords();
- $this->assertTrue($record['extra']['win']);
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testProcessorsAreCalledOnlyOnce()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler->expects($this->any())
- ->method('handle')
- ->will($this->returnValue(true))
- ;
- $logger->pushHandler($handler);
-
- $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor')
- ->disableOriginalConstructor()
- ->setMethods(array('__invoke'))
- ->getMock()
- ;
- $processor->expects($this->once())
- ->method('__invoke')
- ->will($this->returnArgument(0))
- ;
- $logger->pushProcessor($processor);
-
- $logger->addError('test');
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testProcessorsNotCalledWhenNotHandled()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler->expects($this->once())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
- $logger->pushHandler($handler);
- $that = $this;
- $logger->pushProcessor(function ($record) use ($that) {
- $that->fail('The processor should not be called');
- });
- $logger->addAlert('test');
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testHandlersNotCalledBeforeFirstHandling()
- {
- $logger = new Logger(__METHOD__);
-
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->never())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
- $handler1->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
- $logger->pushHandler($handler1);
-
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->once())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler2->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
- $logger->pushHandler($handler2);
-
- $handler3 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler3->expects($this->once())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
- $handler3->expects($this->never())
- ->method('handle')
- ;
- $logger->pushHandler($handler3);
-
- $logger->debug('test');
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testHandlersNotCalledBeforeFirstHandlingWithAssocArray()
- {
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->never())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
- $handler1->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
-
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->once())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler2->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
-
- $handler3 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler3->expects($this->once())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
- $handler3->expects($this->never())
- ->method('handle')
- ;
-
- $logger = new Logger(__METHOD__, array('last' => $handler3, 'second' => $handler2, 'first' => $handler1));
-
- $logger->debug('test');
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testBubblingWhenTheHandlerReturnsFalse()
- {
- $logger = new Logger(__METHOD__);
-
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler1->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
- $logger->pushHandler($handler1);
-
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler2->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(false))
- ;
- $logger->pushHandler($handler2);
-
- $logger->debug('test');
- }
-
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testNotBubblingWhenTheHandlerReturnsTrue()
- {
- $logger = new Logger(__METHOD__);
-
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler1->expects($this->never())
- ->method('handle')
- ;
- $logger->pushHandler($handler1);
-
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
- $handler2->expects($this->once())
- ->method('handle')
- ->will($this->returnValue(true))
- ;
- $logger->pushHandler($handler2);
-
- $logger->debug('test');
- }
-
- /**
- * @covers Monolog\Logger::isHandling
- */
- public function testIsHandling()
- {
- $logger = new Logger(__METHOD__);
-
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(false))
- ;
-
- $logger->pushHandler($handler1);
- $this->assertFalse($logger->isHandling(Logger::DEBUG));
-
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->will($this->returnValue(true))
- ;
-
- $logger->pushHandler($handler2);
- $this->assertTrue($logger->isHandling(Logger::DEBUG));
- }
-
- /**
- * @dataProvider logMethodProvider
- * @covers Monolog\Logger::addDebug
- * @covers Monolog\Logger::addInfo
- * @covers Monolog\Logger::addNotice
- * @covers Monolog\Logger::addWarning
- * @covers Monolog\Logger::addError
- * @covers Monolog\Logger::addCritical
- * @covers Monolog\Logger::addAlert
- * @covers Monolog\Logger::addEmergency
- * @covers Monolog\Logger::debug
- * @covers Monolog\Logger::info
- * @covers Monolog\Logger::notice
- * @covers Monolog\Logger::warn
- * @covers Monolog\Logger::err
- * @covers Monolog\Logger::crit
- * @covers Monolog\Logger::alert
- * @covers Monolog\Logger::emerg
- */
- public function testLogMethods($method, $expectedLevel)
- {
- $logger = new Logger('foo');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->{$method}('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($expectedLevel, $record['level']);
- }
-
- public function logMethodProvider()
- {
- return array(
- // monolog methods
- array('addDebug', Logger::DEBUG),
- array('addInfo', Logger::INFO),
- array('addNotice', Logger::NOTICE),
- array('addWarning', Logger::WARNING),
- array('addError', Logger::ERROR),
- array('addCritical', Logger::CRITICAL),
- array('addAlert', Logger::ALERT),
- array('addEmergency', Logger::EMERGENCY),
-
- // ZF/Sf2 compat methods
- array('debug', Logger::DEBUG),
- array('info', Logger::INFO),
- array('notice', Logger::NOTICE),
- array('warn', Logger::WARNING),
- array('err', Logger::ERROR),
- array('crit', Logger::CRITICAL),
- array('alert', Logger::ALERT),
- array('emerg', Logger::EMERGENCY),
- );
- }
-
- /**
- * @dataProvider setTimezoneProvider
- * @covers Monolog\Logger::setTimezone
- */
- public function testSetTimezone($tz)
- {
- Logger::setTimezone($tz);
- $logger = new Logger('foo');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($tz, $record['datetime']->getTimezone());
- }
-
- public function setTimezoneProvider()
- {
- return array_map(
- function ($tz) { return array(new \DateTimeZone($tz)); },
- \DateTimeZone::listIdentifiers()
- );
- }
-
- /**
- * @dataProvider useMicrosecondTimestampsProvider
- * @covers Monolog\Logger::useMicrosecondTimestamps
- * @covers Monolog\Logger::addRecord
- */
- public function testUseMicrosecondTimestamps($micro, $assert)
- {
- $logger = new Logger('foo');
- $logger->useMicrosecondTimestamps($micro);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->{$assert}('000000', $record['datetime']->format('u'));
- }
-
- public function useMicrosecondTimestampsProvider()
- {
- return array(
- // this has a very small chance of a false negative (1/10^6)
- 'with microseconds' => array(true, 'assertNotSame'),
- 'without microseconds' => array(false, PHP_VERSION_ID >= 70100 ? 'assertNotSame' : 'assertSame'),
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php
deleted file mode 100644
index 5adb505d..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class GitProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\GitProcessor::__invoke
- */
- public function testProcessor()
- {
- $processor = new GitProcessor();
- $record = $processor($this->getRecord());
-
- $this->assertArrayHasKey('git', $record['extra']);
- $this->assertTrue(!is_array($record['extra']['git']['branch']));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php
deleted file mode 100644
index 0dd411d7..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php
+++ /dev/null
@@ -1,123 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Acme;
-
-class Tester
-{
- public function test($handler, $record)
- {
- $handler->handle($record);
- }
-}
-
-function tester($handler, $record)
-{
- $handler->handle($record);
-}
-
-namespace Monolog\Processor;
-
-use Monolog\Logger;
-use Monolog\TestCase;
-use Monolog\Handler\TestHandler;
-
-class IntrospectionProcessorTest extends TestCase
-{
- public function getHandler()
- {
- $processor = new IntrospectionProcessor();
- $handler = new TestHandler();
- $handler->pushProcessor($processor);
-
- return $handler;
- }
-
- public function testProcessorFromClass()
- {
- $handler = $this->getHandler();
- $tester = new \Acme\Tester;
- $tester->test($handler, $this->getRecord());
- list($record) = $handler->getRecords();
- $this->assertEquals(__FILE__, $record['extra']['file']);
- $this->assertEquals(18, $record['extra']['line']);
- $this->assertEquals('Acme\Tester', $record['extra']['class']);
- $this->assertEquals('test', $record['extra']['function']);
- }
-
- public function testProcessorFromFunc()
- {
- $handler = $this->getHandler();
- \Acme\tester($handler, $this->getRecord());
- list($record) = $handler->getRecords();
- $this->assertEquals(__FILE__, $record['extra']['file']);
- $this->assertEquals(24, $record['extra']['line']);
- $this->assertEquals(null, $record['extra']['class']);
- $this->assertEquals('Acme\tester', $record['extra']['function']);
- }
-
- public function testLevelTooLow()
- {
- $input = array(
- 'level' => Logger::DEBUG,
- 'extra' => array(),
- );
-
- $expected = $input;
-
- $processor = new IntrospectionProcessor(Logger::CRITICAL);
- $actual = $processor($input);
-
- $this->assertEquals($expected, $actual);
- }
-
- public function testLevelEqual()
- {
- $input = array(
- 'level' => Logger::CRITICAL,
- 'extra' => array(),
- );
-
- $expected = $input;
- $expected['extra'] = array(
- 'file' => null,
- 'line' => null,
- 'class' => 'ReflectionMethod',
- 'function' => 'invokeArgs',
- );
-
- $processor = new IntrospectionProcessor(Logger::CRITICAL);
- $actual = $processor($input);
-
- $this->assertEquals($expected, $actual);
- }
-
- public function testLevelHigher()
- {
- $input = array(
- 'level' => Logger::EMERGENCY,
- 'extra' => array(),
- );
-
- $expected = $input;
- $expected['extra'] = array(
- 'file' => null,
- 'line' => null,
- 'class' => 'ReflectionMethod',
- 'function' => 'invokeArgs',
- );
-
- $processor = new IntrospectionProcessor(Logger::CRITICAL);
- $actual = $processor($input);
-
- $this->assertEquals($expected, $actual);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php
deleted file mode 100644
index eb666144..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class MemoryPeakUsageProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\MemoryPeakUsageProcessor::__invoke
- * @covers Monolog\Processor\MemoryProcessor::formatBytes
- */
- public function testProcessor()
- {
- $processor = new MemoryPeakUsageProcessor();
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('memory_peak_usage', $record['extra']);
- $this->assertRegExp('#[0-9.]+ (M|K)?B$#', $record['extra']['memory_peak_usage']);
- }
-
- /**
- * @covers Monolog\Processor\MemoryPeakUsageProcessor::__invoke
- * @covers Monolog\Processor\MemoryProcessor::formatBytes
- */
- public function testProcessorWithoutFormatting()
- {
- $processor = new MemoryPeakUsageProcessor(true, false);
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('memory_peak_usage', $record['extra']);
- $this->assertInternalType('int', $record['extra']['memory_peak_usage']);
- $this->assertGreaterThan(0, $record['extra']['memory_peak_usage']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php
deleted file mode 100644
index 4692dbfc..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class MemoryUsageProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\MemoryUsageProcessor::__invoke
- * @covers Monolog\Processor\MemoryProcessor::formatBytes
- */
- public function testProcessor()
- {
- $processor = new MemoryUsageProcessor();
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('memory_usage', $record['extra']);
- $this->assertRegExp('#[0-9.]+ (M|K)?B$#', $record['extra']['memory_usage']);
- }
-
- /**
- * @covers Monolog\Processor\MemoryUsageProcessor::__invoke
- * @covers Monolog\Processor\MemoryProcessor::formatBytes
- */
- public function testProcessorWithoutFormatting()
- {
- $processor = new MemoryUsageProcessor(true, false);
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('memory_usage', $record['extra']);
- $this->assertInternalType('int', $record['extra']['memory_usage']);
- $this->assertGreaterThan(0, $record['extra']['memory_usage']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/MercurialProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/MercurialProcessorTest.php
deleted file mode 100644
index 11f2b35a..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/MercurialProcessorTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class MercurialProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\MercurialProcessor::__invoke
- */
- public function testProcessor()
- {
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
- exec("where hg 2>NUL", $output, $result);
- } else {
- exec("which hg 2>/dev/null >/dev/null", $output, $result);
- }
- if ($result != 0) {
- $this->markTestSkipped('hg is missing');
- return;
- }
-
- `hg init`;
- $processor = new MercurialProcessor();
- $record = $processor($this->getRecord());
-
- $this->assertArrayHasKey('hg', $record['extra']);
- $this->assertTrue(!is_array($record['extra']['hg']['branch']));
- $this->assertTrue(!is_array($record['extra']['hg']['revision']));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php
deleted file mode 100644
index 458d2a33..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class ProcessIdProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\ProcessIdProcessor::__invoke
- */
- public function testProcessor()
- {
- $processor = new ProcessIdProcessor();
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('process_id', $record['extra']);
- $this->assertInternalType('int', $record['extra']['process_id']);
- $this->assertGreaterThan(0, $record['extra']['process_id']);
- $this->assertEquals(getmypid(), $record['extra']['process_id']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php
deleted file mode 100644
index 029a0c02..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-class PsrLogMessageProcessorTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @dataProvider getPairs
- */
- public function testReplacement($val, $expected)
- {
- $proc = new PsrLogMessageProcessor;
-
- $message = $proc(array(
- 'message' => '{foo}',
- 'context' => array('foo' => $val),
- ));
- $this->assertEquals($expected, $message['message']);
- }
-
- public function getPairs()
- {
- return array(
- array('foo', 'foo'),
- array('3', '3'),
- array(3, '3'),
- array(null, ''),
- array(true, '1'),
- array(false, ''),
- array(new \stdClass, '[object stdClass]'),
- array(array(), '[array]'),
- );
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php
deleted file mode 100644
index 0d860c61..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class TagProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\TagProcessor::__invoke
- */
- public function testProcessor()
- {
- $tags = array(1, 2, 3);
- $processor = new TagProcessor($tags);
- $record = $processor($this->getRecord());
-
- $this->assertEquals($tags, $record['extra']['tags']);
- }
-
- /**
- * @covers Monolog\Processor\TagProcessor::__invoke
- */
- public function testProcessorTagModification()
- {
- $tags = array(1, 2, 3);
- $processor = new TagProcessor($tags);
-
- $record = $processor($this->getRecord());
- $this->assertEquals($tags, $record['extra']['tags']);
-
- $processor->setTags(array('a', 'b'));
- $record = $processor($this->getRecord());
- $this->assertEquals(array('a', 'b'), $record['extra']['tags']);
-
- $processor->addTags(array('a', 'c', 'foo' => 'bar'));
- $record = $processor($this->getRecord());
- $this->assertEquals(array('a', 'b', 'a', 'c', 'foo' => 'bar'), $record['extra']['tags']);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php
deleted file mode 100644
index 5d13058f..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class UidProcessorTest extends TestCase
-{
- /**
- * @covers Monolog\Processor\UidProcessor::__invoke
- */
- public function testProcessor()
- {
- $processor = new UidProcessor();
- $record = $processor($this->getRecord());
- $this->assertArrayHasKey('uid', $record['extra']);
- }
-
- public function testGetUid()
- {
- $processor = new UidProcessor(10);
- $this->assertEquals(10, strlen($processor->getUid()));
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php
deleted file mode 100644
index 4105baf7..00000000
--- a/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php
+++ /dev/null
@@ -1,113 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog\Processor;
-
-use Monolog\TestCase;
-
-class WebProcessorTest extends TestCase
-{
- public function testProcessor()
- {
- $server = array(
- 'REQUEST_URI' => 'A',
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- 'HTTP_REFERER' => 'D',
- 'SERVER_NAME' => 'F',
- 'UNIQUE_ID' => 'G',
- );
-
- $processor = new WebProcessor($server);
- $record = $processor($this->getRecord());
- $this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
- $this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']);
- $this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
- $this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
- $this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
- $this->assertEquals($server['UNIQUE_ID'], $record['extra']['unique_id']);
- }
-
- public function testProcessorDoNothingIfNoRequestUri()
- {
- $server = array(
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- );
- $processor = new WebProcessor($server);
- $record = $processor($this->getRecord());
- $this->assertEmpty($record['extra']);
- }
-
- public function testProcessorReturnNullIfNoHttpReferer()
- {
- $server = array(
- 'REQUEST_URI' => 'A',
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- 'SERVER_NAME' => 'F',
- );
- $processor = new WebProcessor($server);
- $record = $processor($this->getRecord());
- $this->assertNull($record['extra']['referrer']);
- }
-
- public function testProcessorDoesNotAddUniqueIdIfNotPresent()
- {
- $server = array(
- 'REQUEST_URI' => 'A',
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- 'SERVER_NAME' => 'F',
- );
- $processor = new WebProcessor($server);
- $record = $processor($this->getRecord());
- $this->assertFalse(isset($record['extra']['unique_id']));
- }
-
- public function testProcessorAddsOnlyRequestedExtraFields()
- {
- $server = array(
- 'REQUEST_URI' => 'A',
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- 'SERVER_NAME' => 'F',
- );
-
- $processor = new WebProcessor($server, array('url', 'http_method'));
- $record = $processor($this->getRecord());
-
- $this->assertSame(array('url' => 'A', 'http_method' => 'C'), $record['extra']);
- }
-
- public function testProcessorConfiguringOfExtraFields()
- {
- $server = array(
- 'REQUEST_URI' => 'A',
- 'REMOTE_ADDR' => 'B',
- 'REQUEST_METHOD' => 'C',
- 'SERVER_NAME' => 'F',
- );
-
- $processor = new WebProcessor($server, array('url' => 'REMOTE_ADDR'));
- $record = $processor($this->getRecord());
-
- $this->assertSame(array('url' => 'B'), $record['extra']);
- }
-
- /**
- * @expectedException UnexpectedValueException
- */
- public function testInvalidData()
- {
- new WebProcessor(new \stdClass);
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php b/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php
deleted file mode 100644
index ab899449..00000000
--- a/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-use Monolog\Handler\TestHandler;
-use Monolog\Formatter\LineFormatter;
-use Monolog\Processor\PsrLogMessageProcessor;
-use Psr\Log\Test\LoggerInterfaceTest;
-
-class PsrLogCompatTest extends LoggerInterfaceTest
-{
- private $handler;
-
- public function getLogger()
- {
- $logger = new Logger('foo');
- $logger->pushHandler($handler = new TestHandler);
- $logger->pushProcessor(new PsrLogMessageProcessor);
- $handler->setFormatter(new LineFormatter('%level_name% %message%'));
-
- $this->handler = $handler;
-
- return $logger;
- }
-
- public function getLogs()
- {
- $convert = function ($record) {
- $lower = function ($match) {
- return strtolower($match[0]);
- };
-
- return preg_replace_callback('{^[A-Z]+}', $lower, $record['formatted']);
- };
-
- return array_map($convert, $this->handler->getRecords());
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/RegistryTest.php b/vendor/monolog/monolog/tests/Monolog/RegistryTest.php
deleted file mode 100644
index 15fdfbd2..00000000
--- a/vendor/monolog/monolog/tests/Monolog/RegistryTest.php
+++ /dev/null
@@ -1,153 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-class RegistryTest extends \PHPUnit_Framework_TestCase
-{
- protected function setUp()
- {
- Registry::clear();
- }
-
- /**
- * @dataProvider hasLoggerProvider
- * @covers Monolog\Registry::hasLogger
- */
- public function testHasLogger(array $loggersToAdd, array $loggersToCheck, array $expectedResult)
- {
- foreach ($loggersToAdd as $loggerToAdd) {
- Registry::addLogger($loggerToAdd);
- }
- foreach ($loggersToCheck as $index => $loggerToCheck) {
- $this->assertSame($expectedResult[$index], Registry::hasLogger($loggerToCheck));
- }
- }
-
- public function hasLoggerProvider()
- {
- $logger1 = new Logger('test1');
- $logger2 = new Logger('test2');
- $logger3 = new Logger('test3');
-
- return array(
- // only instances
- array(
- array($logger1),
- array($logger1, $logger2),
- array(true, false),
- ),
- // only names
- array(
- array($logger1),
- array('test1', 'test2'),
- array(true, false),
- ),
- // mixed case
- array(
- array($logger1, $logger2),
- array('test1', $logger2, 'test3', $logger3),
- array(true, true, false, false),
- ),
- );
- }
-
- /**
- * @covers Monolog\Registry::clear
- */
- public function testClearClears()
- {
- Registry::addLogger(new Logger('test1'), 'log');
- Registry::clear();
-
- $this->setExpectedException('\InvalidArgumentException');
- Registry::getInstance('log');
- }
-
- /**
- * @dataProvider removedLoggerProvider
- * @covers Monolog\Registry::addLogger
- * @covers Monolog\Registry::removeLogger
- */
- public function testRemovesLogger($loggerToAdd, $remove)
- {
- Registry::addLogger($loggerToAdd);
- Registry::removeLogger($remove);
-
- $this->setExpectedException('\InvalidArgumentException');
- Registry::getInstance($loggerToAdd->getName());
- }
-
- public function removedLoggerProvider()
- {
- $logger1 = new Logger('test1');
-
- return array(
- array($logger1, $logger1),
- array($logger1, 'test1'),
- );
- }
-
- /**
- * @covers Monolog\Registry::addLogger
- * @covers Monolog\Registry::getInstance
- * @covers Monolog\Registry::__callStatic
- */
- public function testGetsSameLogger()
- {
- $logger1 = new Logger('test1');
- $logger2 = new Logger('test2');
-
- Registry::addLogger($logger1, 'test1');
- Registry::addLogger($logger2);
-
- $this->assertSame($logger1, Registry::getInstance('test1'));
- $this->assertSame($logger2, Registry::test2());
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @covers Monolog\Registry::getInstance
- */
- public function testFailsOnNonExistantLogger()
- {
- Registry::getInstance('test1');
- }
-
- /**
- * @covers Monolog\Registry::addLogger
- */
- public function testReplacesLogger()
- {
- $log1 = new Logger('test1');
- $log2 = new Logger('test2');
-
- Registry::addLogger($log1, 'log');
-
- Registry::addLogger($log2, 'log', true);
-
- $this->assertSame($log2, Registry::getInstance('log'));
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @covers Monolog\Registry::addLogger
- */
- public function testFailsOnUnspecifiedReplacement()
- {
- $log1 = new Logger('test1');
- $log2 = new Logger('test2');
-
- Registry::addLogger($log1, 'log');
-
- Registry::addLogger($log2, 'log');
- }
-}
diff --git a/vendor/monolog/monolog/tests/Monolog/TestCase.php b/vendor/monolog/monolog/tests/Monolog/TestCase.php
deleted file mode 100644
index 4eb7b4c9..00000000
--- a/vendor/monolog/monolog/tests/Monolog/TestCase.php
+++ /dev/null
@@ -1,58 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-class TestCase extends \PHPUnit_Framework_TestCase
-{
- /**
- * @return array Record
- */
- protected function getRecord($level = Logger::WARNING, $message = 'test', $context = array())
- {
- return array(
- 'message' => $message,
- 'context' => $context,
- 'level' => $level,
- 'level_name' => Logger::getLevelName($level),
- 'channel' => 'test',
- 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))),
- 'extra' => array(),
- );
- }
-
- /**
- * @return array
- */
- protected function getMultipleRecords()
- {
- return array(
- $this->getRecord(Logger::DEBUG, 'debug message 1'),
- $this->getRecord(Logger::DEBUG, 'debug message 2'),
- $this->getRecord(Logger::INFO, 'information'),
- $this->getRecord(Logger::WARNING, 'warning'),
- $this->getRecord(Logger::ERROR, 'error'),
- );
- }
-
- /**
- * @return Monolog\Formatter\FormatterInterface
- */
- protected function getIdentityFormatter()
- {
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
- $formatter->expects($this->any())
- ->method('format')
- ->will($this->returnCallback(function ($record) { return $record['message']; }));
-
- return $formatter;
- }
-}
diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php
index 5ea72438..e695046e 100644
--- a/vendor/psr/log/Psr/Log/LoggerInterface.php
+++ b/vendor/psr/log/Psr/Log/LoggerInterface.php
@@ -118,6 +118,8 @@ interface LoggerInterface
* @param array $context
*
* @return void
+ *
+ * @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, $message, array $context = array());
}
diff --git a/vendor/psr/log/Psr/Log/LoggerTrait.php b/vendor/psr/log/Psr/Log/LoggerTrait.php
index 867225df..e392fef0 100644
--- a/vendor/psr/log/Psr/Log/LoggerTrait.php
+++ b/vendor/psr/log/Psr/Log/LoggerTrait.php
@@ -135,6 +135,8 @@ trait LoggerTrait
* @param array $context
*
* @return void
+ *
+ * @throws \Psr\Log\InvalidArgumentException
*/
abstract public function log($level, $message, array $context = array());
}
diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php
index d8cd682c..c8f7293b 100644
--- a/vendor/psr/log/Psr/Log/NullLogger.php
+++ b/vendor/psr/log/Psr/Log/NullLogger.php
@@ -20,6 +20,8 @@ class NullLogger extends AbstractLogger
* @param array $context
*
* @return void
+ *
+ * @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, $message, array $context = array())
{
diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
index a0391a52..9ecb6c4b 100644
--- a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
+++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
@@ -4,6 +4,7 @@ namespace Psr\Log\Test;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
+use PHPUnit\Framework\TestCase;
/**
* Provides a base test class for ensuring compliance with the LoggerInterface.
@@ -11,7 +12,7 @@ use Psr\Log\LogLevel;
* Implementors can extend the class and implement abstract methods to run this
* as part of their test suite.
*/
-abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
+abstract class LoggerInterfaceTest extends TestCase
{
/**
* @return LoggerInterface
@@ -101,6 +102,9 @@ abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
public function testContextCanContainAnything()
{
+ $closed = fopen('php://memory', 'r');
+ fclose($closed);
+
$context = array(
'bool' => true,
'null' => null,
@@ -110,6 +114,7 @@ abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
'nested' => array('with object' => new DummyTest),
'object' => new \DateTime,
'resource' => fopen('php://memory', 'r'),
+ 'closed' => $closed,
);
$this->getLogger()->warning('Crazy context data', $context);
@@ -136,5 +141,6 @@ class DummyTest
{
public function __toString()
{
+ return 'DummyTest';
}
}
diff --git a/vendor/psr/log/Psr/Log/Test/TestLogger.php b/vendor/psr/log/Psr/Log/Test/TestLogger.php
new file mode 100644
index 00000000..1be32304
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/Test/TestLogger.php
@@ -0,0 +1,147 @@
+ $level,
+ 'message' => $message,
+ 'context' => $context,
+ ];
+
+ $this->recordsByLevel[$record['level']][] = $record;
+ $this->records[] = $record;
+ }
+
+ public function hasRecords($level)
+ {
+ return isset($this->recordsByLevel[$level]);
+ }
+
+ public function hasRecord($record, $level)
+ {
+ if (is_string($record)) {
+ $record = ['message' => $record];
+ }
+ return $this->hasRecordThatPasses(function ($rec) use ($record) {
+ if ($rec['message'] !== $record['message']) {
+ return false;
+ }
+ if (isset($record['context']) && $rec['context'] !== $record['context']) {
+ return false;
+ }
+ return true;
+ }, $level);
+ }
+
+ public function hasRecordThatContains($message, $level)
+ {
+ return $this->hasRecordThatPasses(function ($rec) use ($message) {
+ return strpos($rec['message'], $message) !== false;
+ }, $level);
+ }
+
+ public function hasRecordThatMatches($regex, $level)
+ {
+ return $this->hasRecordThatPasses(function ($rec) use ($regex) {
+ return preg_match($regex, $rec['message']) > 0;
+ }, $level);
+ }
+
+ public function hasRecordThatPasses(callable $predicate, $level)
+ {
+ if (!isset($this->recordsByLevel[$level])) {
+ return false;
+ }
+ foreach ($this->recordsByLevel[$level] as $i => $rec) {
+ if (call_user_func($predicate, $rec, $i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function __call($method, $args)
+ {
+ if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
+ $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
+ $level = strtolower($matches[2]);
+ if (method_exists($this, $genericMethod)) {
+ $args[] = $level;
+ return call_user_func_array([$this, $genericMethod], $args);
+ }
+ }
+ throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()');
+ }
+
+ public function reset()
+ {
+ $this->records = [];
+ $this->recordsByLevel = [];
+ }
+}
diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md
index 574bc1cb..a9f20c43 100644
--- a/vendor/psr/log/README.md
+++ b/vendor/psr/log/README.md
@@ -7,6 +7,13 @@ This repository holds all interfaces/classes/traits related to
Note that this is not a logger of its own. It is merely an interface that
describes a logger. See the specification for more details.
+Installation
+------------
+
+```bash
+composer require psr/log
+```
+
Usage
-----
@@ -31,6 +38,12 @@ class Foo
if ($this->logger) {
$this->logger->info('Doing work');
}
+
+ try {
+ $this->doSomethingElse();
+ } catch (Exception $exception) {
+ $this->logger->error('Oh no!', array('exception' => $exception));
+ }
// do something useful
}
diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json
index 87934d70..3f6d4eea 100644
--- a/vendor/psr/log/composer.json
+++ b/vendor/psr/log/composer.json
@@ -20,7 +20,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.1.x-dev"
}
}
}
diff --git a/vendor/ralouphie/getallheaders/LICENSE b/vendor/ralouphie/getallheaders/LICENSE
new file mode 100644
index 00000000..be5540c2
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Ralph Khattar
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/ralouphie/getallheaders/README.md b/vendor/ralouphie/getallheaders/README.md
new file mode 100644
index 00000000..9430d76b
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/README.md
@@ -0,0 +1,27 @@
+getallheaders
+=============
+
+PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3.
+
+[](https://travis-ci.org/ralouphie/getallheaders)
+[](https://coveralls.io/r/ralouphie/getallheaders?branch=master)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+
+
+This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php).
+
+## Install
+
+For PHP version **`>= 5.6`**:
+
+```
+composer require ralouphie/getallheaders
+```
+
+For PHP version **`< 5.6`**:
+
+```
+composer require ralouphie/getallheaders "^2"
+```
diff --git a/vendor/ralouphie/getallheaders/composer.json b/vendor/ralouphie/getallheaders/composer.json
new file mode 100644
index 00000000..de8ce62e
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "ralouphie/getallheaders",
+ "description": "A polyfill for getallheaders.",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5 || ^6.5",
+ "php-coveralls/php-coveralls": "^2.1"
+ },
+ "autoload": {
+ "files": ["src/getallheaders.php"]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "getallheaders\\Tests\\": "tests/"
+ }
+ }
+}
diff --git a/vendor/ralouphie/getallheaders/src/getallheaders.php b/vendor/ralouphie/getallheaders/src/getallheaders.php
new file mode 100644
index 00000000..c7285a5b
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/src/getallheaders.php
@@ -0,0 +1,46 @@
+ 'Content-Type',
+ 'CONTENT_LENGTH' => 'Content-Length',
+ 'CONTENT_MD5' => 'Content-Md5',
+ );
+
+ foreach ($_SERVER as $key => $value) {
+ if (substr($key, 0, 5) === 'HTTP_') {
+ $key = substr($key, 5);
+ if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
+ $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
+ $headers[$key] = $value;
+ }
+ } elseif (isset($copy_server[$key])) {
+ $headers[$copy_server[$key]] = $value;
+ }
+ }
+
+ if (!isset($headers['Authorization'])) {
+ if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+ } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
+ $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
+ $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
+ } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
+ $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
+ }
+ }
+
+ return $headers;
+ }
+
+}
diff --git a/vendor/leafo/scssphp/LICENSE.md b/vendor/scssphp/scssphp/LICENSE.md
similarity index 93%
rename from vendor/leafo/scssphp/LICENSE.md
rename to vendor/scssphp/scssphp/LICENSE.md
index 2f5412f9..afcfdfb2 100644
--- a/vendor/leafo/scssphp/LICENSE.md
+++ b/vendor/scssphp/scssphp/LICENSE.md
@@ -1,4 +1,4 @@
-Copyright (c) 2015 Leaf Corcoran, http://leafo.github.io/scssphp
+Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/vendor/leafo/scssphp/README.md b/vendor/scssphp/scssphp/README.md
similarity index 81%
rename from vendor/leafo/scssphp/README.md
rename to vendor/scssphp/scssphp/README.md
index 53a4c7a4..f541e488 100644
--- a/vendor/leafo/scssphp/README.md
+++ b/vendor/scssphp/scssphp/README.md
@@ -1,12 +1,12 @@
# scssphp
-###
+###
-[](http://travis-ci.org/leafo/scssphp)
-[](https://packagist.org/packages/leafo/scssphp)
+[](http://travis-ci.org/scssphp/scssphp)
+[](https://packagist.org/packages/scssphp/scssphp)
`scssphp` is a compiler for SCSS written in PHP.
-Checkout the homepage, , for directions on how to use.
+Checkout the homepage, , for directions on how to use.
## Running Tests
diff --git a/vendor/leafo/scssphp/bin/pscss b/vendor/scssphp/scssphp/bin/pscss
similarity index 73%
rename from vendor/leafo/scssphp/bin/pscss
rename to vendor/scssphp/scssphp/bin/pscss
index be1cb51c..f944b632 100644
--- a/vendor/leafo/scssphp/bin/pscss
+++ b/vendor/scssphp/scssphp/bin/pscss
@@ -3,24 +3,24 @@
/**
* SCSSPHP
*
- * @copyright 2012-2015 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
error_reporting(E_ALL);
-if (version_compare(PHP_VERSION, '5.4') < 0) {
- die('Requires PHP 5.4 or above');
+if (version_compare(PHP_VERSION, '5.6') < 0) {
+ die('Requires PHP 5.6 or above');
}
include __DIR__ . '/../scss.inc.php';
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Parser;
-use Leafo\ScssPhp\Version;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Parser;
+use ScssPhp\ScssPhp\Version;
$style = null;
$loadPaths = null;
@@ -62,7 +62,7 @@ function parseArgument(&$i, $options) {
}
for ($i = 1; $i < $argc; $i++) {
- if ($argv[$i] === '-h' || $argv[$i] === '--help') {
+ if ($argv[$i] === '-?' || $argv[$i] === '-h' || $argv[$i] === '--help') {
$exe = $argv[0];
$HELP = <<setFormatter('Leafo\\ScssPhp\\Formatter\\' . ucfirst($style));
+ $scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($style));
}
if ($sourceMap) {
- $scss->setSourceMap(Compiler::SOURCE_MAP_FILE);
+ $scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
}
if ($encoding) {
diff --git a/vendor/scssphp/scssphp/composer.json b/vendor/scssphp/scssphp/composer.json
new file mode 100644
index 00000000..ff0590fb
--- /dev/null
+++ b/vendor/scssphp/scssphp/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "scssphp/scssphp",
+ "type": "library",
+ "description": "scssphp is a compiler for SCSS written in PHP.",
+ "keywords": ["css", "stylesheet", "scss", "sass", "less"],
+ "homepage": "http://scssphp.github.io/scssphp/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Anthon Pang",
+ "email": "apang@softwaredevelopment.ca",
+ "homepage": "https://github.com/robocoder"
+ },
+ {
+ "name": "Cédric Morin",
+ "email": "cedric@yterium.com",
+ "homepage": "https://github.com/Cerdic"
+ }
+ ],
+ "autoload": {
+ "psr-4": { "ScssPhp\\ScssPhp\\": "src/" }
+ },
+ "autoload-dev": {
+ "psr-4": { "ScssPhp\\ScssPhp\\Tests\\": "tests/" }
+ },
+ "require": {
+ "php": ">=5.6.0",
+ "ext-json": "*",
+ "ext-ctype": "*"
+ },
+ "require-dev": {
+ "squizlabs/php_codesniffer": "~2.5",
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3",
+ "twbs/bootstrap": "~4.3",
+ "zurb/foundation": "~6.5"
+ },
+ "minimum-stability": "dev",
+ "bin": ["bin/pscss"],
+ "archive": {
+ "exclude": [
+ "/Makefile",
+ "/.gitattributes",
+ "/.gitignore",
+ "/.travis.yml",
+ "/phpunit.xml.dist",
+ "/tests"
+ ]
+ }
+}
diff --git a/vendor/leafo/scssphp/example/Server.php b/vendor/scssphp/scssphp/example/Server.php
similarity index 90%
rename from vendor/leafo/scssphp/example/Server.php
rename to vendor/scssphp/scssphp/example/Server.php
index 6ea97018..6fa11e3a 100644
--- a/vendor/leafo/scssphp/example/Server.php
+++ b/vendor/scssphp/scssphp/example/Server.php
@@ -2,18 +2,18 @@
/**
* SCSSPHP
*
- * @copyright 2012-2017 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Exception\ServerException;
-use Leafo\ScssPhp\Version;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Exception\ServerException;
+use ScssPhp\ScssPhp\Version;
/**
* Server
@@ -38,7 +38,7 @@ class Server
private $cacheDir;
/**
- * @var \Leafo\ScssPhp\Compiler
+ * @var \ScssPhp\ScssPhp\Compiler
*/
private $scss;
@@ -62,13 +62,16 @@ class Server
*/
protected function inputName()
{
- switch (true) {
- case isset($_GET['p']):
- return $_GET['p'];
- case isset($_SERVER['PATH_INFO']):
- return $_SERVER['PATH_INFO'];
- case isset($_SERVER['DOCUMENT_URI']):
- return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
+ if (isset($_GET['p'])) {
+ return $_GET['p'];
+ }
+
+ if (isset($_SERVER['PATH_INFO'])) {
+ return $_SERVER['PATH_INFO'];
+ }
+
+ if (isset($_SERVER['DOCUMENT_URI'])) {
+ return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
}
}
@@ -96,6 +99,8 @@ class Server
/**
* Get path to cached .css file
*
+ * @param string $fname
+ *
* @return string
*/
protected function cacheName($fname)
@@ -106,6 +111,8 @@ class Server
/**
* Get path to meta data
*
+ * @param string $out
+ *
* @return string
*/
protected function metadataName($out)
@@ -270,7 +277,7 @@ class Server
*
* @return string|bool
*
- * @throws \Leafo\ScssPhp\Exception\ServerException
+ * @throws \ScssPhp\ScssPhp\Exception\ServerException
*/
public function compileFile($in, $out = null)
{
@@ -284,11 +291,11 @@ class Server
$compiled = $this->scss->compile(file_get_contents($in), $in);
- if ($out !== null) {
- return file_put_contents($out, $compiled);
+ if (is_null($out)) {
+ return $compiled;
}
- return $compiled;
+ return file_put_contents($out, $compiled);
}
/**
@@ -395,7 +402,7 @@ class Server
*
* @return string Compiled CSS results
*
- * @throws \Leafo\ScssPhp\Exception\ServerException
+ * @throws \ScssPhp\ScssPhp\Exception\ServerException
*/
public function checkedCachedCompile($in, $out, $force = false)
{
@@ -466,27 +473,28 @@ class Server
return null;
}
- if ($root !== null) {
- // If we have a root value which means we should rebuild.
- $out = array();
- $out['root'] = $root;
- $out['compiled'] = $this->compileFile($root);
- $out['files'] = $this->scss->getParsedFiles();
- $out['updated'] = time();
- return $out;
- } else {
+ if (is_null($root)) {
// No changes, pass back the structure
// we were given initially.
return $in;
}
+
+ // If we have a root value which means we should rebuild.
+ $out = [];
+ $out['root'] = $root;
+ $out['compiled'] = $this->compileFile($root);
+ $out['files'] = $this->scss->getParsedFiles();
+ $out['updated'] = time();
+
+ return $out;
}
/**
* Constructor
*
- * @param string $dir Root directory to .scss files
- * @param string $cacheDir Cache directory
- * @param \Leafo\ScssPhp\Compiler|null $scss SCSS compiler instance
+ * @param string $dir Root directory to .scss files
+ * @param string $cacheDir Cache directory
+ * @param \ScssPhp\ScssPhp\Compiler|null $scss SCSS compiler instance
*/
public function __construct($dir, $cacheDir = null, $scss = null)
{
diff --git a/vendor/leafo/scssphp/scss.inc.php b/vendor/scssphp/scssphp/scss.inc.php
similarity index 80%
rename from vendor/leafo/scssphp/scss.inc.php
rename to vendor/scssphp/scssphp/scss.inc.php
index 13c84bf5..e4ec7f18 100644
--- a/vendor/leafo/scssphp/scss.inc.php
+++ b/vendor/scssphp/scssphp/scss.inc.php
@@ -1,11 +1,12 @@
$lastModified) &&
+ $cacheTime + self::$gcLifetime > time()
+ ) {
+ $c = file_get_contents($fileCache);
+ $c = unserialize($c);
+
+ if (is_array($c) && isset($c['value'])) {
+ return $c['value'];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Put in cache the result of $operation on $what,
+ * which is known as dependant from the content of $options
+ *
+ * @param string $operation
+ * @param mixed $what
+ * @param mixed $value
+ * @param array $options
+ */
+ public function setCache($operation, $what, $value, $options = [])
+ {
+ $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options);
+
+ $c = ['value' => $value];
+ $c = serialize($c);
+ file_put_contents($fileCache, $c);
+
+ if (self::$forceRefresh === 'once') {
+ self::$refreshed[$fileCache] = true;
+ }
+ }
+
+ /**
+ * Get the cache name for the caching of $operation on $what,
+ * which is known as dependant from the content of $options
+ *
+ * @param string $operation
+ * @param mixed $what
+ * @param array $options
+ *
+ * @return string
+ */
+ private static function cacheName($operation, $what, $options = [])
+ {
+ $t = [
+ 'version' => self::CACHE_VERSION,
+ 'operation' => $operation,
+ 'what' => $what,
+ 'options' => $options
+ ];
+
+ $t = self::$prefix
+ . sha1(json_encode($t))
+ . ".$operation"
+ . ".scsscache";
+
+ return $t;
+ }
+
+ /**
+ * Check that the cache dir exists and is writeable
+ *
+ * @throws \Exception
+ */
+ public static function checkCacheDir()
+ {
+ self::$cacheDir = str_replace('\\', '/', self::$cacheDir);
+ self::$cacheDir = rtrim(self::$cacheDir, '/') . '/';
+
+ if (! is_dir(self::$cacheDir)) {
+ if (! mkdir(self::$cacheDir)) {
+ throw new Exception('Cache directory couldn\'t be created: ' . self::$cacheDir);
+ }
+ }
+
+ if (! is_writable(self::$cacheDir)) {
+ throw new Exception('Cache directory isn\'t writable: ' . self::$cacheDir);
+ }
+ }
+
+ /**
+ * Delete unused cached files
+ */
+ public static function cleanCache()
+ {
+ static $clean = false;
+
+ if ($clean || empty(self::$cacheDir)) {
+ return;
+ }
+
+ $clean = true;
+
+ // only remove files with extensions created by SCSSPHP Cache
+ // css files removed based on the list files
+ $removeTypes = ['scsscache' => 1];
+
+ $files = scandir(self::$cacheDir);
+
+ if (! $files) {
+ return;
+ }
+
+ $checkTime = time() - self::$gcLifetime;
+
+ foreach ($files as $file) {
+ // don't delete if the file wasn't created with SCSSPHP Cache
+ if (strpos($file, self::$prefix) !== 0) {
+ continue;
+ }
+
+ $parts = explode('.', $file);
+ $type = array_pop($parts);
+
+ if (! isset($removeTypes[$type])) {
+ continue;
+ }
+
+ $fullPath = self::$cacheDir . $file;
+ $mtime = filemtime($fullPath);
+
+ // don't delete if it's a relatively new file
+ if ($mtime > $checkTime) {
+ continue;
+ }
+
+ unlink($fullPath);
+ }
+ }
+}
diff --git a/vendor/leafo/scssphp/src/Colors.php b/vendor/scssphp/scssphp/src/Colors.php
similarity index 74%
rename from vendor/leafo/scssphp/src/Colors.php
rename to vendor/scssphp/scssphp/src/Colors.php
index 2314ea58..ef6409ac 100644
--- a/vendor/leafo/scssphp/src/Colors.php
+++ b/vendor/scssphp/scssphp/src/Colors.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
/**
* CSS Colors
@@ -25,7 +25,7 @@ class Colors
*
* @var array
*/
- public static $cssColors = [
+ protected static $cssColors = [
'aliceblue' => '240,248,255',
'antiquewhite' => '250,235,215',
'aqua' => '0,255,255',
@@ -176,4 +176,71 @@ class Colors
'yellow' => '255,255,0',
'yellowgreen' => '154,205,50',
];
+
+ /**
+ * Convert named color in a [r,g,b[,a]] array
+ *
+ * @param string $colorName
+ *
+ * @return array|null
+ */
+ public static function colorNameToRGBa($colorName)
+ {
+ if (is_string($colorName) && isset(static::$cssColors[$colorName])) {
+ $rgba = explode(',', static::$cssColors[$colorName]);
+
+ // only case with opacity is transparent, with opacity=0, so we can intval on opacity also
+ $rgba = array_map('intval', $rgba);
+
+ return $rgba;
+ }
+
+ return null;
+ }
+
+ /**
+ * Reverse conversion : from RGBA to a color name if possible
+ *
+ * @param integer $r
+ * @param integer $g
+ * @param integer $b
+ * @param integer $a
+ *
+ * @return string|null
+ */
+ public static function RGBaToColorName($r, $g, $b, $a = 1)
+ {
+ static $reverseColorTable = null;
+
+ if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b) || ! is_numeric($a)) {
+ return null;
+ }
+
+ if ($a < 1) {
+ # specific case we dont' revert according to spec
+ #if (! $a && ! $r && ! $g && ! $b) {
+ # return 'transparent';
+ #}
+
+ return null;
+ }
+
+ if (is_null($reverseColorTable)) {
+ $reverseColorTable = [];
+
+ foreach (static::$cssColors as $name => $rgb_str) {
+ $rgb_str = explode(',', $rgb_str);
+
+ if (count($rgb_str) == 3) {
+ $reverseColorTable[intval($rgb_str[0])][intval($rgb_str[1])][intval($rgb_str[2])] = $name;
+ }
+ }
+ }
+
+ if (isset($reverseColorTable[intval($r)][intval($g)][intval($b)])) {
+ return $reverseColorTable[intval($r)][intval($g)][intval($b)];
+ }
+
+ return null;
+ }
}
diff --git a/vendor/leafo/scssphp/src/Compiler.php b/vendor/scssphp/scssphp/src/Compiler.php
similarity index 52%
rename from vendor/leafo/scssphp/src/Compiler.php
rename to vendor/scssphp/scssphp/src/Compiler.php
index 637f1c1c..711d3382 100644
--- a/vendor/leafo/scssphp/src/Compiler.php
+++ b/vendor/scssphp/scssphp/src/Compiler.php
@@ -2,26 +2,27 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
-use Leafo\ScssPhp\Base\Range;
-use Leafo\ScssPhp\Block;
-use Leafo\ScssPhp\Colors;
-use Leafo\ScssPhp\Compiler\Environment;
-use Leafo\ScssPhp\Exception\CompilerException;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\SourceMap\SourceMapGenerator;
-use Leafo\ScssPhp\Type;
-use Leafo\ScssPhp\Parser;
-use Leafo\ScssPhp\Util;
+use ScssPhp\ScssPhp\Base\Range;
+use ScssPhp\ScssPhp\Block;
+use ScssPhp\ScssPhp\Cache;
+use ScssPhp\ScssPhp\Colors;
+use ScssPhp\ScssPhp\Compiler\Environment;
+use ScssPhp\ScssPhp\Exception\CompilerException;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\SourceMap\SourceMapGenerator;
+use ScssPhp\ScssPhp\Type;
+use ScssPhp\ScssPhp\Parser;
+use ScssPhp\ScssPhp\Util;
/**
* The scss compiler and parser.
@@ -98,17 +99,17 @@ class Compiler
'function' => '^',
];
- static public $true = [Type::T_KEYWORD, 'true'];
- static public $false = [Type::T_KEYWORD, 'false'];
- static public $null = [Type::T_NULL];
- static public $nullString = [Type::T_STRING, '', []];
+ static public $true = [Type::T_KEYWORD, 'true'];
+ static public $false = [Type::T_KEYWORD, 'false'];
+ static public $null = [Type::T_NULL];
+ static public $nullString = [Type::T_STRING, '', []];
static public $defaultValue = [Type::T_KEYWORD, ''];
static public $selfSelector = [Type::T_SELF];
- static public $emptyList = [Type::T_LIST, '', []];
- static public $emptyMap = [Type::T_MAP, [], []];
- static public $emptyString = [Type::T_STRING, '"', []];
- static public $with = [Type::T_KEYWORD, 'with'];
- static public $without = [Type::T_KEYWORD, 'without'];
+ static public $emptyList = [Type::T_LIST, '', []];
+ static public $emptyMap = [Type::T_MAP, [], []];
+ static public $emptyString = [Type::T_STRING, '"', []];
+ static public $with = [Type::T_KEYWORD, 'with'];
+ static public $without = [Type::T_KEYWORD, 'without'];
protected $importPaths = [''];
protected $importCache = [];
@@ -129,15 +130,15 @@ class Compiler
protected $sourceMapOptions = [];
/**
- * @var string|\Leafo\ScssPhp\Formatter
+ * @var string|\ScssPhp\ScssPhp\Formatter
*/
- protected $formatter = 'Leafo\ScssPhp\Formatter\Nested';
+ protected $formatter = 'ScssPhp\ScssPhp\Formatter\Nested';
protected $rootEnv;
protected $rootBlock;
/**
- * @var \Leafo\ScssPhp\Compiler\Environment
+ * @var \ScssPhp\ScssPhp\Compiler\Environment
*/
protected $env;
protected $scope;
@@ -145,26 +146,67 @@ class Compiler
protected $charsetSeen;
protected $sourceNames;
- private $indentLevel;
- private $commentsSeen;
- private $extends;
- private $extendsMap;
- private $parsedFiles;
- private $parser;
- private $sourceIndex;
- private $sourceLine;
- private $sourceColumn;
- private $stderr;
- private $shouldEvaluate;
- private $ignoreErrors;
+ protected $cache;
+
+ protected $indentLevel;
+ protected $extends;
+ protected $extendsMap;
+ protected $parsedFiles;
+ protected $parser;
+ protected $sourceIndex;
+ protected $sourceLine;
+ protected $sourceColumn;
+ protected $stderr;
+ protected $shouldEvaluate;
+ protected $ignoreErrors;
+
+ protected $callStack = [];
/**
* Constructor
+ *
+ * @param array|null $cacheOptions
*/
- public function __construct()
+ public function __construct($cacheOptions = null)
{
$this->parsedFiles = [];
$this->sourceNames = [];
+
+ if ($cacheOptions) {
+ $this->cache = new Cache($cacheOptions);
+ }
+
+ $this->stderr = fopen('php://stderr', 'w');
+ }
+
+ /**
+ * Get compiler options
+ *
+ * @return array
+ */
+ public function getCompileOptions()
+ {
+ $options = [
+ 'importPaths' => $this->importPaths,
+ 'registeredVars' => $this->registeredVars,
+ 'registeredFeatures' => $this->registeredFeatures,
+ 'encoding' => $this->encoding,
+ 'sourceMap' => serialize($this->sourceMap),
+ 'sourceMapOptions' => $this->sourceMapOptions,
+ 'formatter' => $this->formatter,
+ ];
+
+ return $options;
+ }
+
+ /**
+ * Set an alternative error output stream, for testing purpose only
+ *
+ * @param resource $handle
+ */
+ public function setErrorOuput($handle)
+ {
+ $this->stderr = $handle;
}
/**
@@ -179,8 +221,28 @@ class Compiler
*/
public function compile($code, $path = null)
{
+ if ($this->cache) {
+ $cacheKey = ($path ? $path : "(stdin)") . ":" . md5($code);
+ $compileOptions = $this->getCompileOptions();
+ $cache = $this->cache->getCache("compile", $cacheKey, $compileOptions);
+
+ if (is_array($cache) && isset($cache['dependencies']) && isset($cache['out'])) {
+ // check if any dependency file changed before accepting the cache
+ foreach ($cache['dependencies'] as $file => $mtime) {
+ if (! is_file($file) || filemtime($file) !== $mtime) {
+ unset($cache);
+ break;
+ }
+ }
+
+ if (isset($cache)) {
+ return $cache['out'];
+ }
+ }
+ }
+
+
$this->indentLevel = -1;
- $this->commentsSeen = [];
$this->extends = [];
$this->extendsMap = [];
$this->sourceIndex = null;
@@ -191,10 +253,9 @@ class Compiler
$this->storeEnv = null;
$this->charsetSeen = null;
$this->shouldEvaluate = null;
- $this->stderr = fopen('php://stderr', 'w');
$this->parser = $this->parserFactory($path);
- $tree = $this->parser->parse($code);
+ $tree = $this->parser->parse($code);
$this->parser = null;
$this->formatter = new $this->formatter();
@@ -235,6 +296,15 @@ class Compiler
$out .= sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl);
}
+ if ($this->cache && isset($cacheKey) && isset($compileOptions)) {
+ $v = [
+ 'dependencies' => $this->getParsedFiles(),
+ 'out' => &$out,
+ ];
+
+ $this->cache->setCache("compile", $cacheKey, $v, $compileOptions);
+ }
+
return $out;
}
@@ -243,11 +313,11 @@ class Compiler
*
* @param string $path
*
- * @return \Leafo\ScssPhp\Parser
+ * @return \ScssPhp\ScssPhp\Parser
*/
protected function parserFactory($path)
{
- $parser = new Parser($path, count($this->sourceNames), $this->encoding);
+ $parser = new Parser($path, count($this->sourceNames), $this->encoding, $this->cache);
$this->sourceNames[] = $path;
$this->addParsedFile($path);
@@ -277,9 +347,9 @@ class Compiler
/**
* Push extends
*
- * @param array $target
- * @param array $origin
- * @param \stdClass $block
+ * @param array $target
+ * @param array $origin
+ * @param array|null $block
*/
protected function pushExtends($target, $origin, $block)
{
@@ -305,17 +375,17 @@ class Compiler
* @param string $type
* @param array $selectors
*
- * @return \Leafo\ScssPhp\Formatter\OutputBlock
+ * @return \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
protected function makeOutputBlock($type, $selectors = null)
{
$out = new OutputBlock;
- $out->type = $type;
- $out->lines = [];
- $out->children = [];
- $out->parent = $this->scope;
- $out->selectors = $selectors;
- $out->depth = $this->env->depth;
+ $out->type = $type;
+ $out->lines = [];
+ $out->children = [];
+ $out->parent = $this->scope;
+ $out->selectors = $selectors;
+ $out->depth = $this->env->depth;
if ($this->env->block instanceof Block) {
$out->sourceName = $this->env->block->sourceName;
@@ -333,7 +403,7 @@ class Compiler
/**
* Compile root
*
- * @param \Leafo\ScssPhp\Block $rootBlock
+ * @param \ScssPhp\ScssPhp\Block $rootBlock
*/
protected function compileRoot(Block $rootBlock)
{
@@ -372,8 +442,8 @@ class Compiler
/**
* Flatten selectors
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
- * @param string $parentKey
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ * @param string $parentKey
*/
protected function flattenSelectors(OutputBlock $block, $parentKey = null)
{
@@ -428,6 +498,40 @@ class Compiler
}
}
+ /**
+ * Glue parts of :not( or :nth-child( ... that are in general splitted in selectors parts
+ *
+ * @param array $parts
+ *
+ * @return array
+ */
+ protected function glueFunctionSelectors($parts)
+ {
+ $new = [];
+
+ foreach ($parts as $part) {
+ if (is_array($part)) {
+ $part = $this->glueFunctionSelectors($part);
+ $new[] = $part;
+ } else {
+ // a selector part finishing with a ) is the last part of a :not( or :nth-child(
+ // and need to be joined to this
+ if (count($new) && is_string($new[count($new) - 1]) &&
+ strlen($part) && substr($part, -1) === ')' && strpos($part, '(') === false
+ ) {
+ while (count($new)>1 && substr($new[count($new) - 1], -1) !== '(') {
+ $part = array_pop($new) . $part;
+ }
+ $new[count($new) - 1] .= $part;
+ } else {
+ $new[] = $part;
+ }
+ }
+ }
+
+ return $new;
+ }
+
/**
* Match extends
*
@@ -438,32 +542,60 @@ class Compiler
*/
protected function matchExtends($selector, &$out, $from = 0, $initial = true)
{
+ static $partsPile = [];
+ $selector = $this->glueFunctionSelectors($selector);
+
+ if (count($selector) == 1 && in_array(reset($selector), $partsPile)) {
+ return;
+ }
+
+ $outRecurs = [];
foreach ($selector as $i => $part) {
if ($i < $from) {
continue;
}
- if ($this->matchExtendsSingle($part, $origin)) {
- $after = array_slice($selector, $i + 1);
- $before = array_slice($selector, 0, $i);
+ // check that we are not building an infinite loop of extensions
+ // if the new part is just including a previous part don't try to extend anymore
+ if (count($part) > 1) {
+ foreach ($partsPile as $previousPart) {
+ if (! count(array_diff($previousPart, $part))) {
+ continue 2;
+ }
+ }
+ }
+ $partsPile[] = $part;
+ if ($this->matchExtendsSingle($part, $origin, $initial)) {
+ $after = array_slice($selector, $i + 1);
+ $before = array_slice($selector, 0, $i);
list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before);
foreach ($origin as $new) {
$k = 0;
// remove shared parts
- if ($initial) {
+ if (count($new) > 1) {
while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) {
$k++;
}
}
+ if (count($nonBreakableBefore) and $k == count($new)) {
+ $k--;
+ }
$replacement = [];
$tempReplacement = $k > 0 ? array_slice($new, $k) : $new;
for ($l = count($tempReplacement) - 1; $l >= 0; $l--) {
- $slice = $tempReplacement[$l];
+ $slice = [];
+
+ foreach ($tempReplacement[$l] as $chunk) {
+ if (! in_array($chunk, $slice)) {
+ $slice[] = $chunk;
+ }
+ }
+
array_unshift($replacement, $slice);
if (! $this->isImmediateRelationshipCombinator(end($slice))) {
@@ -487,33 +619,93 @@ class Compiler
continue;
}
- $out[] = $result;
+ $this->pushOrMergeExtentedSelector($out, $result);
// recursively check for more matches
- $this->matchExtends($result, $out, count($before) + count($mergedBefore), false);
+ $startRecurseFrom = count($before) + min(count($nonBreakableBefore), count($mergedBefore));
+ if (count($origin) > 1) {
+ $this->matchExtends($result, $out, $startRecurseFrom, false);
+ } else {
+ $this->matchExtends($result, $outRecurs, $startRecurseFrom, false);
+ }
// selector sequence merging
if (! empty($before) && count($new) > 1) {
- $sharedParts = $k > 0 ? array_slice($before, 0, $k) : [];
+ $preSharedParts = $k > 0 ? array_slice($before, 0, $k) : [];
$postSharedParts = $k > 0 ? array_slice($before, $k) : $before;
- list($injectBetweenSharedParts, $nonBreakable2) = $this->extractRelationshipFromFragment($afterBefore);
+ list($betweenSharedParts, $nonBreakabl2) = $this->extractRelationshipFromFragment($afterBefore);
$result2 = array_merge(
- $sharedParts,
- $injectBetweenSharedParts,
+ $preSharedParts,
+ $betweenSharedParts,
$postSharedParts,
- $nonBreakable2,
+ $nonBreakabl2,
$nonBreakableBefore,
$replacement,
$after
);
- $out[] = $result2;
+ $this->pushOrMergeExtentedSelector($out, $result2);
+ }
+ }
+ }
+ array_pop($partsPile);
+ }
+ while (count($outRecurs)) {
+ $result = array_shift($outRecurs);
+ $this->pushOrMergeExtentedSelector($out, $result);
+ }
+ }
+
+ /**
+ * Test a part for being a pseudo selector
+ * @param string $part
+ * @param array $matches
+ * @return bool
+ */
+ protected function isPseudoSelector($part, &$matches)
+ {
+ if (strpos($part, ":") === 0
+ && preg_match(",^::?([\w-]+)\((.+)\)$,", $part, $matches)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Push extended selector except if
+ * - this is a pseudo selector
+ * - same as previous
+ * - in a white list
+ * in this case we merge the pseudo selector content
+ * @param array $out
+ * @param array $extended
+ */
+ protected function pushOrMergeExtentedSelector(&$out, $extended)
+ {
+ if (count($out) && count($extended) === 1 && count(reset($extended)) === 1) {
+ $single = reset($extended);
+ $part = reset($single);
+ if ($this->isPseudoSelector($part, $matchesExtended)
+ && in_array($matchesExtended[1], [ 'slotted' ])) {
+ $prev = end($out);
+ $prev = $this->glueFunctionSelectors($prev);
+ if (count($prev) === 1 && count(reset($prev)) === 1) {
+ $single = reset($prev);
+ $part = reset($single);
+ if ($this->isPseudoSelector($part, $matchesPrev)
+ && $matchesPrev[1] === $matchesExtended[1]) {
+ $extended = explode($matchesExtended[1] . '(', $matchesExtended[0], 2);
+ $extended[1] = $matchesPrev[2] . ", " . $extended[1];
+ $extended = implode($matchesExtended[1] . '(', $extended);
+ $extended = [ [ $extended ]];
+ array_pop($out);
}
}
}
}
+ $out[] = $extended;
}
/**
@@ -521,14 +713,20 @@ class Compiler
*
* @param array $rawSingle
* @param array $outOrigin
+ * @param bool $initial
*
* @return boolean
*/
- protected function matchExtendsSingle($rawSingle, &$outOrigin)
+ protected function matchExtendsSingle($rawSingle, &$outOrigin, $initial = true)
{
$counts = [];
$single = [];
+ // simple usual cases, no need to do the whole trick
+ if (in_array($rawSingle, [['>'],['+'],['~']])) {
+ return false;
+ }
+
foreach ($rawSingle as $part) {
// matches Number
if (! is_string($part)) {
@@ -549,20 +747,46 @@ class Compiler
$extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false;
}
- foreach ($single as $part) {
+ $outOrigin = [];
+ $found = false;
+
+ foreach ($single as $k => $part) {
if (isset($this->extendsMap[$part])) {
foreach ($this->extendsMap[$part] as $idx) {
$counts[$idx] = isset($counts[$idx]) ? $counts[$idx] + 1 : 1;
}
}
+ if ($initial
+ && $this->isPseudoSelector($part, $matches)
+ && ! in_array($matches[1], [ 'not' ])) {
+ $buffer = $matches[2];
+ $parser = $this->parserFactory(__METHOD__);
+ if ($parser->parseSelector($buffer, $subSelectors)) {
+ foreach ($subSelectors as $ksub => $subSelector) {
+ $subExtended = [];
+ $this->matchExtends($subSelector, $subExtended, 0, false);
+ if ($subExtended) {
+ $subSelectorsExtended = $subSelectors;
+ $subSelectorsExtended[$ksub] = $subExtended;
+ foreach ($subSelectorsExtended as $ksse => $sse) {
+ $subSelectorsExtended[$ksse] = $this->collapseSelectors($sse);
+ }
+ $subSelectorsExtended = implode(', ', $subSelectorsExtended);
+ $singleExtended = $single;
+ $singleExtended[$k] = str_replace("(".$buffer.")", "($subSelectorsExtended)", $part);
+ $outOrigin[] = [ $singleExtended ];
+ $found = true;
+ }
+ }
+ }
+ }
}
- $outOrigin = [];
- $found = false;
-
foreach ($counts as $idx => $count) {
list($target, $origin, /* $block */) = $this->extends[$idx];
+ $origin = $this->glueFunctionSelectors($origin);
+
// check count
if ($count !== count($target)) {
continue;
@@ -603,7 +827,6 @@ class Compiler
return $found;
}
-
/**
* Extract a relationship from the fragment.
*
@@ -613,18 +836,20 @@ class Compiler
* the rest.
*
* @param array $fragment The selector fragment maybe ending with a direction relationship combinator.
+ *
* @return array The selector without the relationship fragment if any, the relationship fragment.
*/
protected function extractRelationshipFromFragment(array $fragment)
{
$parents = [];
$children = [];
+
$j = $i = count($fragment);
for (;;) {
$children = $j != $i ? array_slice($fragment, $j, $i - $j) : [];
- $parents = array_slice($fragment, 0, $j);
- $slice = end($parents);
+ $parents = array_slice($fragment, 0, $j);
+ $slice = end($parents);
if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) {
break;
@@ -646,22 +871,25 @@ class Compiler
*/
protected function combineSelectorSingle($base, $other)
{
- $tag = [];
- $out = [];
- $wasTag = true;
+ $tag = [];
+ $out = [];
+ $wasTag = false;
- foreach ([$base, $other] as $single) {
+ foreach ([array_reverse($base), array_reverse($other)] as $single) {
foreach ($single as $part) {
- if (preg_match('/^[\[.:#]/', $part)) {
+ if (preg_match('/^[\[:]/', $part)) {
$out[] = $part;
$wasTag = false;
+ } elseif (preg_match('/^[\.#]/', $part)) {
+ array_unshift($out, $part);
+ $wasTag = false;
} elseif (preg_match('/^[^_-]/', $part)) {
$tag[] = $part;
$wasTag = true;
} elseif ($wasTag) {
$tag[count($tag) - 1] .= $part;
} else {
- $out[count($out) - 1] .= $part;
+ $out[] = $part;
}
}
}
@@ -676,19 +904,24 @@ class Compiler
/**
* Compile media
*
- * @param \Leafo\ScssPhp\Block $media
+ * @param \ScssPhp\ScssPhp\Block $media
*/
protected function compileMedia(Block $media)
{
$this->pushEnv($media);
- $mediaQuery = $this->compileMediaQuery($this->multiplyMedia($this->env));
-
- if (! empty($mediaQuery)) {
- $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]);
+ $mediaQueries = $this->compileMediaQuery($this->multiplyMedia($this->env));
+ if (! empty($mediaQueries) && $mediaQueries) {
+ $previousScope = $this->scope;
$parentScope = $this->mediaParent($this->scope);
- $parentScope->children[] = $this->scope;
+
+ foreach ($mediaQueries as $mediaQuery) {
+ $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]);
+
+ $parentScope->children[] = $this->scope;
+ $parentScope = $this->scope;
+ }
// top level properties in a media cause it to be wrapped
$needsWrap = false;
@@ -718,11 +951,35 @@ class Compiler
$wrapped->children = $media->children;
$media->children = [[Type::T_BLOCK, $wrapped]];
+
+ if (isset($this->lineNumberStyle)) {
+ $annotation = $this->makeOutputBlock(Type::T_COMMENT);
+ $annotation->depth = 0;
+
+ $file = $this->sourceNames[$media->sourceIndex];
+ $line = $media->sourceLine;
+
+ switch ($this->lineNumberStyle) {
+ case static::LINE_COMMENTS:
+ $annotation->lines[] = '/* line ' . $line
+ . ($file ? ', ' . $file : '')
+ . ' */';
+ break;
+
+ case static::DEBUG_INFO:
+ $annotation->lines[] = '@media -sass-debug-info{'
+ . ($file ? 'filename{font-family:"' . $file . '"}' : '')
+ . 'line{font-family:' . $line . '}}';
+ break;
+ }
+
+ $this->scope->children[] = $annotation;
+ }
}
$this->compileChildrenNoReturn($media->children, $this->scope);
- $this->scope = $this->scope->parent;
+ $this->scope = $previousScope;
}
$this->popEnv();
@@ -731,9 +988,9 @@ class Compiler
/**
* Media parent
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $scope
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
*
- * @return \Leafo\ScssPhp\Formatter\OutputBlock
+ * @return \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
protected function mediaParent(OutputBlock $scope)
{
@@ -751,33 +1008,42 @@ class Compiler
/**
* Compile directive
*
- * @param \Leafo\ScssPhp\Block $block
+ * @param \ScssPhp\ScssPhp\Block|array $block
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
*/
- protected function compileDirective(Block $block)
+ protected function compileDirective($directive, OutputBlock $out)
{
- $s = '@' . $block->name;
-
- if (! empty($block->value)) {
- $s .= ' ' . $this->compileValue($block->value);
- }
-
- if ($block->name === 'keyframes' || substr($block->name, -10) === '-keyframes') {
- $this->compileKeyframeBlock($block, [$s]);
+ if (is_array($directive)) {
+ $s = '@' . $directive[0];
+ if (! empty($directive[1])) {
+ $s .= ' ' . $this->compileValue($directive[1]);
+ }
+ $this->appendRootDirective($s . ';', $out);
} else {
- $this->compileNestedBlock($block, [$s]);
+ $s = '@' . $directive->name;
+
+ if (! empty($directive->value)) {
+ $s .= ' ' . $this->compileValue($directive->value);
+ }
+
+ if ($directive->name === 'keyframes' || substr($directive->name, -10) === '-keyframes') {
+ $this->compileKeyframeBlock($directive, [$s]);
+ } else {
+ $this->compileNestedBlock($directive, [$s]);
+ }
}
}
/**
* Compile at-root
*
- * @param \Leafo\ScssPhp\Block $block
+ * @param \ScssPhp\ScssPhp\Block $block
*/
protected function compileAtRoot(Block $block)
{
$env = $this->pushEnv($block);
$envs = $this->compactEnv($env);
- $without = isset($block->with) ? $this->compileWith($block->with) : static::WITH_RULE;
+ list($with, $without) = $this->compileWith(isset($block->with) ? $block->with : null);
// wrap inline selector
if ($block->selector) {
@@ -790,18 +1056,29 @@ class Compiler
$wrapped->comments = [];
$wrapped->parent = $block;
$wrapped->children = $block->children;
+ $wrapped->selfParent = $block->selfParent;
$block->children = [[Type::T_BLOCK, $wrapped]];
+ $block->selector = null;
}
- $this->env = $this->filterWithout($envs, $without);
- $newBlock = $this->spliceTree($envs, $block, $without);
+ $selfParent = $block->selfParent;
+
+ if (! $block->selfParent->selectors && isset($block->parent) && $block->parent &&
+ isset($block->parent->selectors) && $block->parent->selectors
+ ) {
+ $selfParent = $block->parent;
+ }
+
+ $this->env = $this->filterWithWithout($envs, $with, $without);
$saveScope = $this->scope;
- $this->scope = $this->rootBlock;
+ $this->scope = $this->filterScopeWithWithout($saveScope, $with, $without);
- $this->compileChild($newBlock, $this->scope);
+ // propagate selfParent to the children where they still can be useful
+ $this->compileChildrenNoReturn($block->children, $this->scope, $selfParent);
+ $this->scope = $this->completeScope($this->scope, $saveScope);
$this->scope = $saveScope;
$this->env = $this->extractEnv($envs);
@@ -809,152 +1086,190 @@ class Compiler
}
/**
- * Splice parse tree
+ * Filter at-root scope depending of with/without option
*
- * @param array $envs
- * @param \Leafo\ScssPhp\Block $block
- * @param integer $without
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+ * @param array $with
+ * @param array $without
*
- * @return array
+ * @return mixed
*/
- private function spliceTree($envs, Block $block, $without)
+ protected function filterScopeWithWithout($scope, $with, $without)
{
- $newBlock = null;
+ $filteredScopes = [];
+ $childStash = [];
- foreach ($envs as $e) {
- if (! isset($e->block)) {
- continue;
- }
-
- if ($e->block === $block) {
- continue;
- }
-
- if (isset($e->block->type) && $e->block->type === Type::T_AT_ROOT) {
- continue;
- }
-
- if ($e->block && $this->isWithout($without, $e->block)) {
- continue;
- }
-
- $b = new Block;
- $b->sourceName = $e->block->sourceName;
- $b->sourceIndex = $e->block->sourceIndex;
- $b->sourceLine = $e->block->sourceLine;
- $b->sourceColumn = $e->block->sourceColumn;
- $b->selectors = [];
- $b->comments = $e->block->comments;
- $b->parent = null;
-
- if ($newBlock) {
- $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
-
- $b->children = [[$type, $newBlock]];
-
- $newBlock->parent = $b;
- } elseif (count($block->children)) {
- foreach ($block->children as $child) {
- if ($child[0] === Type::T_BLOCK) {
- $child[1]->parent = $b;
- }
- }
-
- $b->children = $block->children;
- }
-
- if (isset($e->block->type)) {
- $b->type = $e->block->type;
- }
-
- if (isset($e->block->name)) {
- $b->name = $e->block->name;
- }
-
- if (isset($e->block->queryList)) {
- $b->queryList = $e->block->queryList;
- }
-
- if (isset($e->block->value)) {
- $b->value = $e->block->value;
- }
-
- $newBlock = $b;
+ if ($scope->type === TYPE::T_ROOT) {
+ return $scope;
}
- $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
+ // start from the root
+ while ($scope->parent && $scope->parent->type !== TYPE::T_ROOT) {
+ array_unshift($childStash, $scope);
+ $scope = $scope->parent;
+ }
- return [$type, $newBlock];
+ for (;;) {
+ if (! $scope) {
+ break;
+ }
+
+ if ($this->isWith($scope, $with, $without)) {
+ $s = clone $scope;
+ $s->children = [];
+ $s->lines = [];
+ $s->parent = null;
+
+ if ($s->type !== Type::T_MEDIA && $s->type !== Type::T_DIRECTIVE) {
+ $s->selectors = [];
+ }
+
+ $filteredScopes[] = $s;
+ }
+
+ if (count($childStash)) {
+ $scope = array_shift($childStash);
+ } elseif ($scope->children) {
+ $scope = end($scope->children);
+ } else {
+ $scope = null;
+ }
+ }
+
+ if (! count($filteredScopes)) {
+ return $this->rootBlock;
+ }
+
+ $newScope = array_shift($filteredScopes);
+ $newScope->parent = $this->rootBlock;
+
+ $this->rootBlock->children[] = $newScope;
+
+ $p = &$newScope;
+
+ while (count($filteredScopes)) {
+ $s = array_shift($filteredScopes);
+ $s->parent = $p;
+ $p->children[] = $s;
+ $newScope = &$p->children[0];
+ $p = &$p->children[0];
+ }
+
+ return $newScope;
}
/**
- * Compile @at-root's with: inclusion / without: exclusion into filter flags
+ * found missing selector from a at-root compilation in the previous scope
+ * (if at-root is just enclosing a property, the selector is in the parent tree)
*
- * @param array $with
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $previousScope
*
- * @return integer
+ * @return mixed
*/
- private function compileWith($with)
+ protected function completeScope($scope, $previousScope)
{
- static $mapping = [
- 'rule' => self::WITH_RULE,
- 'media' => self::WITH_MEDIA,
- 'supports' => self::WITH_SUPPORTS,
- 'all' => self::WITH_ALL,
- ];
+ if (! $scope->type && (! $scope->selectors || ! count($scope->selectors)) && count($scope->lines)) {
+ $scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth);
+ }
- // exclude selectors by default
- $without = static::WITH_RULE;
+ if ($scope->children) {
+ foreach ($scope->children as $k => $c) {
+ $scope->children[$k] = $this->completeScope($c, $previousScope);
+ }
+ }
- if ($this->libMapHasKey([$with, static::$with])) {
- $without = static::WITH_ALL;
+ return $scope;
+ }
- $list = $this->coerceList($this->libMapGet([$with, static::$with]));
+ /**
+ * Find a selector by the depth node in the scope
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+ * @param integer $depth
+ *
+ * @return array
+ */
+ protected function findScopeSelectors($scope, $depth)
+ {
+ if ($scope->depth === $depth && $scope->selectors) {
+ return $scope->selectors;
+ }
- foreach ($list[2] as $item) {
- $keyword = $this->compileStringContent($this->coerceString($item));
-
- if (array_key_exists($keyword, $mapping)) {
- $without &= ~($mapping[$keyword]);
+ if ($scope->children) {
+ foreach (array_reverse($scope->children) as $c) {
+ if ($s = $this->findScopeSelectors($c, $depth)) {
+ return $s;
}
}
}
- if ($this->libMapHasKey([$with, static::$without])) {
- $without = 0;
+ return [];
+ }
- $list = $this->coerceList($this->libMapGet([$with, static::$without]));
+ /**
+ * Compile @at-root's with: inclusion / without: exclusion into 2 lists uses to filter scope/env later
+ *
+ * @param array $withCondition
+ *
+ * @return array
+ */
+ protected function compileWith($withCondition)
+ {
+ // just compile what we have in 2 lists
+ $with = [];
+ $without = ['rule' => true];
- foreach ($list[2] as $item) {
- $keyword = $this->compileStringContent($this->coerceString($item));
+ if ($withCondition) {
+ if ($this->libMapHasKey([$withCondition, static::$with])) {
+ $without = []; // cancel the default
+ $list = $this->coerceList($this->libMapGet([$withCondition, static::$with]));
- if (array_key_exists($keyword, $mapping)) {
- $without |= $mapping[$keyword];
+ foreach ($list[2] as $item) {
+ $keyword = $this->compileStringContent($this->coerceString($item));
+
+ $with[$keyword] = true;
+ }
+ }
+
+ if ($this->libMapHasKey([$withCondition, static::$without])) {
+ $without = []; // cancel the default
+ $list = $this->coerceList($this->libMapGet([$withCondition, static::$without]));
+
+ foreach ($list[2] as $item) {
+ $keyword = $this->compileStringContent($this->coerceString($item));
+
+ $without[$keyword] = true;
}
}
}
- return $without;
+ return [$with, $without];
}
/**
* Filter env stack
*
* @param array $envs
- * @param integer $without
+ * @param array $with
+ * @param array $without
*
- * @return \Leafo\ScssPhp\Compiler\Environment
+ * @return \ScssPhp\ScssPhp\Compiler\Environment
*/
- private function filterWithout($envs, $without)
+ protected function filterWithWithout($envs, $with, $without)
{
$filtered = [];
foreach ($envs as $e) {
- if ($e->block && $this->isWithout($without, $e->block)) {
- continue;
- }
+ if ($e->block && ! $this->isWith($e->block, $with, $without)) {
+ $ec = clone $e;
+ $ec->block = null;
+ $ec->selectors = [];
- $filtered[] = $e;
+ $filtered[] = $ec;
+ } else {
+ $filtered[] = $e;
+ }
}
return $this->extractEnv($filtered);
@@ -963,31 +1278,76 @@ class Compiler
/**
* Filter WITH rules
*
- * @param integer $without
- * @param \Leafo\ScssPhp\Block $block
+ * @param \ScssPhp\ScssPhp\Block|\ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ * @param array $with
+ * @param array $without
*
* @return boolean
*/
- private function isWithout($without, Block $block)
+ protected function isWith($block, $with, $without)
{
- if ((($without & static::WITH_RULE) && isset($block->selectors)) ||
- (($without & static::WITH_MEDIA) &&
- isset($block->type) && $block->type === Type::T_MEDIA) ||
- (($without & static::WITH_SUPPORTS) &&
- isset($block->type) && $block->type === Type::T_DIRECTIVE &&
- isset($block->name) && $block->name === 'supports')
- ) {
- return true;
+ if (isset($block->type)) {
+ if ($block->type === Type::T_MEDIA) {
+ return $this->testWithWithout('media', $with, $without);
+ }
+
+ if ($block->type === Type::T_DIRECTIVE) {
+ if (isset($block->name)) {
+ return $this->testWithWithout($block->name, $with, $without);
+ } elseif (isset($block->selectors) && preg_match(',@(\w+),ims', json_encode($block->selectors), $m)) {
+ return $this->testWithWithout($m[1], $with, $without);
+ } else {
+ return $this->testWithWithout('???', $with, $without);
+ }
+ }
+ } elseif (isset($block->selectors)) {
+ // a selector starting with number is a keyframe rule
+ if (count($block->selectors)) {
+ $s = reset($block->selectors);
+
+ while (is_array($s)) {
+ $s = reset($s);
+ }
+
+ if (is_object($s) && $s instanceof Node\Number) {
+ return $this->testWithWithout('keyframes', $with, $without);
+ }
+ }
+
+ return $this->testWithWithout('rule', $with, $without);
}
- return false;
+ return true;
}
+ /**
+ * Test a single type of block against with/without lists
+ *
+ * @param string $what
+ * @param array $with
+ * @param array $without
+ *
+ * @return boolean
+ * true if the block should be kept, false to reject
+ */
+ protected function testWithWithout($what, $with, $without)
+ {
+
+ // if without, reject only if in the list (or 'all' is in the list)
+ if (count($without)) {
+ return (isset($without[$what]) || isset($without['all'])) ? false : true;
+ }
+
+ // otherwise reject all what is not in the with list
+ return (isset($with[$what]) || isset($with['all'])) ? true : false;
+ }
+
+
/**
* Compile keyframe block
*
- * @param \Leafo\ScssPhp\Block $block
- * @param array $selectors
+ * @param \ScssPhp\ScssPhp\Block $block
+ * @param array $selectors
*/
protected function compileKeyframeBlock(Block $block, $selectors)
{
@@ -1011,11 +1371,45 @@ class Compiler
$this->popEnv();
}
+ /**
+ * Compile nested properties lines
+ *
+ * @param \ScssPhp\ScssPhp\Block $block
+ * @param OutputBlock $out
+ */
+ protected function compileNestedPropertiesBlock(Block $block, OutputBlock $out)
+ {
+ $prefix = $this->compileValue($block->prefix) . '-';
+
+ $nested = $this->makeOutputBlock($block->type);
+ $nested->parent = $out;
+
+ if ($block->hasValue) {
+ $nested->depth = $out->depth + 1;
+ }
+
+ $out->children[] = $nested;
+
+ foreach ($block->children as $child) {
+ switch ($child[0]) {
+ case Type::T_ASSIGN:
+ array_unshift($child[1][2], $prefix);
+ break;
+
+ case Type::T_NESTED_PROPERTY:
+ array_unshift($child[1]->prefix[2], $prefix);
+ break;
+ }
+
+ $this->compileChild($child, $nested);
+ }
+ }
+
/**
* Compile nested block
*
- * @param \Leafo\ScssPhp\Block $block
- * @param array $selectors
+ * @param \ScssPhp\ScssPhp\Block $block
+ * @param array $selectors
*/
protected function compileNestedBlock(Block $block, $selectors)
{
@@ -1024,6 +1418,35 @@ class Compiler
$this->scope = $this->makeOutputBlock($block->type, $selectors);
$this->scope->parent->children[] = $this->scope;
+ // wrap assign children in a block
+ // except for @font-face
+ if ($block->type !== Type::T_DIRECTIVE || $block->name !== "font-face") {
+ // need wrapping?
+ $needWrapping = false;
+
+ foreach ($block->children as $child) {
+ if ($child[0] === Type::T_ASSIGN) {
+ $needWrapping = true;
+ break;
+ }
+ }
+
+ if ($needWrapping) {
+ $wrapped = new Block;
+ $wrapped->sourceName = $block->sourceName;
+ $wrapped->sourceIndex = $block->sourceIndex;
+ $wrapped->sourceLine = $block->sourceLine;
+ $wrapped->sourceColumn = $block->sourceColumn;
+ $wrapped->selectors = [];
+ $wrapped->comments = [];
+ $wrapped->parent = $block;
+ $wrapped->children = $block->children;
+ $wrapped->selfParent = $block->selfParent;
+
+ $block->children = [[Type::T_BLOCK, $wrapped]];
+ }
+ }
+
$this->compileChildrenNoReturn($block->children, $this->scope);
$this->scope = $this->scope->parent;
@@ -1047,7 +1470,7 @@ class Compiler
*
* @see Compiler::compileChild()
*
- * @param \Leafo\ScssPhp\Block $block
+ * @param \ScssPhp\ScssPhp\Block $block
*/
protected function compileBlock(Block $block)
{
@@ -1083,16 +1506,62 @@ class Compiler
$this->scope->children[] = $out;
if (count($block->children)) {
- $out->selectors = $this->multiplySelectors($env);
+ $out->selectors = $this->multiplySelectors($env, $block->selfParent);
- $this->compileChildrenNoReturn($block->children, $out);
+ // propagate selfParent to the children where they still can be useful
+ $selfParentSelectors = null;
+
+ if (isset($block->selfParent->selectors)) {
+ $selfParentSelectors = $block->selfParent->selectors;
+ $block->selfParent->selectors = $out->selectors;
+ }
+
+ $this->compileChildrenNoReturn($block->children, $out, $block->selfParent);
+
+ // and revert for the following children of the same block
+ if ($selfParentSelectors) {
+ $block->selfParent->selectors = $selfParentSelectors;
+ }
}
- $this->formatter->stripSemicolon($out->lines);
-
$this->popEnv();
}
+
+ /**
+ * Compile the value of a comment that can have interpolation
+ *
+ * @param array $value
+ * @param boolean $pushEnv
+ *
+ * @return array|mixed|string
+ */
+ protected function compileCommentValue($value, $pushEnv = false)
+ {
+ $c = $value[1];
+
+ if (isset($value[2])) {
+ if ($pushEnv) {
+ $this->pushEnv();
+ $storeEnv = $this->storeEnv;
+ $this->storeEnv = $this->env;
+ }
+
+ try {
+ $c = $this->compileValue($value[2]);
+ } catch (\Exception $e) {
+ // ignore error in comment compilation which are only interpolation
+ }
+
+ if ($pushEnv) {
+ $this->storeEnv = $storeEnv;
+ $this->popEnv();
+ }
+ }
+
+ return $c;
+ }
+
/**
* Compile root level comment
*
@@ -1101,7 +1570,8 @@ class Compiler
protected function compileComment($block)
{
$out = $this->makeOutputBlock(Type::T_COMMENT);
- $out->lines[] = $block[1];
+ $out->lines[] = $this->compileCommentValue($block, true);
+
$this->scope->children[] = $out;
}
@@ -1120,8 +1590,9 @@ class Compiler
// after evaluating interpolates, we might need a second pass
if ($this->shouldEvaluate) {
- $buffer = $this->collapseSelectors($selectors);
- $parser = $this->parserFactory(__METHOD__);
+ $selectors = $this->revertSelfSelector($selectors);
+ $buffer = $this->collapseSelectors($selectors);
+ $parser = $this->parserFactory(__METHOD__);
if ($parser->parseSelector($buffer, $newSelectors)) {
$selectors = array_map([$this, 'evalSelector'], $newSelectors);
@@ -1174,28 +1645,89 @@ class Compiler
/**
* Collapse selectors
*
- * @param array $selectors
+ * @param array $selectors
+ * @param boolean $selectorFormat
+ * if false return a collapsed string
+ * if true return an array description of a structured selector
*
* @return string
*/
- protected function collapseSelectors($selectors)
+ protected function collapseSelectors($selectors, $selectorFormat = false)
{
$parts = [];
foreach ($selectors as $selector) {
- $output = '';
+ $output = [];
+ $glueNext = false;
- array_walk_recursive(
- $selector,
- function ($value, $key) use (&$output) {
- $output .= $value;
+ foreach ($selector as $node) {
+ $compound = '';
+
+ array_walk_recursive(
+ $node,
+ function ($value, $key) use (&$compound) {
+ $compound .= $value;
+ }
+ );
+
+ if ($selectorFormat && $this->isImmediateRelationshipCombinator($compound)) {
+ if (count($output)) {
+ $output[count($output) - 1] .= ' ' . $compound;
+ } else {
+ $output[] = $compound;
+ }
+
+ $glueNext = true;
+ } elseif ($glueNext) {
+ $output[count($output) - 1] .= ' ' . $compound;
+ $glueNext = false;
+ } else {
+ $output[] = $compound;
}
- );
+ }
+
+ if ($selectorFormat) {
+ foreach ($output as &$o) {
+ $o = [Type::T_STRING, '', [$o]];
+ }
+
+ $output = [Type::T_LIST, ' ', $output];
+ } else {
+ $output = implode(' ', $output);
+ }
$parts[] = $output;
}
- return implode(', ', $parts);
+ if ($selectorFormat) {
+ $parts = [Type::T_LIST, ',', $parts];
+ } else {
+ $parts = implode(', ', $parts);
+ }
+
+ return $parts;
+ }
+
+ /**
+ * Parse down the selector and revert [self] to "&" before a reparsing
+ *
+ * @param array $selectors
+ *
+ * @return array
+ */
+ protected function revertSelfSelector($selectors)
+ {
+ foreach ($selectors as &$part) {
+ if (is_array($part)) {
+ if ($part === [Type::T_SELF]) {
+ $part = '&';
+ } else {
+ $part = $this->revertSelfSelector($part);
+ }
+ }
+ }
+
+ return $selectors;
}
/**
@@ -1302,16 +1834,43 @@ class Compiler
return false;
}
+ protected function pushCallStack($name = '')
+ {
+ $this->callStack[] = [
+ 'n' => $name,
+ Parser::SOURCE_INDEX => $this->sourceIndex,
+ Parser::SOURCE_LINE => $this->sourceLine,
+ Parser::SOURCE_COLUMN => $this->sourceColumn
+ ];
+
+ // infinite calling loop
+ if (count($this->callStack) > 25000) {
+ // not displayed but you can var_dump it to deep debug
+ $msg = $this->callStackMessage(true, 100);
+ $msg = "Infinite calling loop";
+
+ $this->throwError($msg);
+ }
+ }
+
+ protected function popCallStack()
+ {
+ array_pop($this->callStack);
+ }
+
/**
* Compile children and return result
*
- * @param array $stms
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
+ * @param array $stms
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+ * @param string $traceName
*
- * @return array
+ * @return array|null
*/
- protected function compileChildren($stms, OutputBlock $out)
+ protected function compileChildren($stms, OutputBlock $out, $traceName = '')
{
+ $this->pushCallStack($traceName);
+
foreach ($stms as $stm) {
$ret = $this->compileChild($stm, $out);
@@ -1319,20 +1878,38 @@ class Compiler
return $ret;
}
}
+
+ $this->popCallStack();
+
+ return null;
}
/**
* Compile children and throw exception if unexpected @return
*
- * @param array $stms
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
+ * @param array $stms
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+ * @param \ScssPhp\ScssPhp\Block $selfParent
+ * @param string $traceName
*
* @throws \Exception
*/
- protected function compileChildrenNoReturn($stms, OutputBlock $out)
+ protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null, $traceName = '')
{
+ $this->pushCallStack($traceName);
+
foreach ($stms as $stm) {
- $ret = $this->compileChild($stm, $out);
+ if ($selfParent && isset($stm[1]) && is_object($stm[1]) && $stm[1] instanceof Block) {
+ $stm[1]->selfParent = $selfParent;
+ $ret = $this->compileChild($stm, $out);
+ $stm[1]->selfParent = null;
+ } elseif ($selfParent && in_array($stm[0], [TYPE::T_INCLUDE, TYPE::T_EXTEND])) {
+ $stm['selfParent'] = $selfParent;
+ $ret = $this->compileChild($stm, $out);
+ unset($stm['selfParent']);
+ } else {
+ $ret = $this->compileChild($stm, $out);
+ }
if (isset($ret)) {
$this->throwError('@return may only be used within a function');
@@ -1340,6 +1917,74 @@ class Compiler
return;
}
}
+
+ $this->popCallStack();
+ }
+
+
+ /**
+ * evaluate media query : compile internal value keeping the structure inchanged
+ *
+ * @param array $queryList
+ *
+ * @return array
+ */
+ protected function evaluateMediaQuery($queryList)
+ {
+ static $parser = null;
+
+ $outQueryList = [];
+
+ foreach ($queryList as $kql => $query) {
+ $shouldReparse = false;
+
+ foreach ($query as $kq => $q) {
+ for ($i = 1; $i < count($q); $i++) {
+ $value = $this->compileValue($q[$i]);
+
+ // the parser had no mean to know if media type or expression if it was an interpolation
+ // so you need to reparse if the T_MEDIA_TYPE looks like anything else a media type
+ if ($q[0] == Type::T_MEDIA_TYPE &&
+ (strpos($value, '(') !== false ||
+ strpos($value, ')') !== false ||
+ strpos($value, ':') !== false ||
+ strpos($value, ',') !== false)
+ ) {
+ $shouldReparse = true;
+ }
+
+ $queryList[$kql][$kq][$i] = [Type::T_KEYWORD, $value];
+ }
+ }
+
+ if ($shouldReparse) {
+ if (is_null($parser)) {
+ $parser = $this->parserFactory(__METHOD__);
+ }
+
+ $queryString = $this->compileMediaQuery([$queryList[$kql]]);
+ $queryString = reset($queryString);
+
+ if (strpos($queryString, '@media ') === 0) {
+ $queryString = substr($queryString, 7);
+ $queries = [];
+
+ if ($parser->parseMediaQueryList($queryString, $queries)) {
+ $queries = $this->evaluateMediaQuery($queries[2]);
+
+ while (count($queries)) {
+ $outQueryList[] = array_shift($queries);
+ }
+
+ continue;
+ }
+ }
+ }
+
+ $outQueryList[] = $queryList[$kql];
+ }
+
+ return $outQueryList;
}
/**
@@ -1347,31 +1992,76 @@ class Compiler
*
* @param array $queryList
*
- * @return string
+ * @return array
*/
protected function compileMediaQuery($queryList)
{
- $out = '@media';
- $first = true;
+ $start = '@media ';
+ $default = trim($start);
+ $out = [];
+ $current = "";
foreach ($queryList as $query) {
$type = null;
$parts = [];
+ $mediaTypeOnly = true;
+
+ foreach ($query as $q) {
+ if ($q[0] !== Type::T_MEDIA_TYPE) {
+ $mediaTypeOnly = false;
+ break;
+ }
+ }
+
foreach ($query as $q) {
switch ($q[0]) {
case Type::T_MEDIA_TYPE:
- if ($type) {
- $type = $this->mergeMediaTypes(
- $type,
- array_map([$this, 'compileValue'], array_slice($q, 1))
- );
+ $newType = array_map([$this, 'compileValue'], array_slice($q, 1));
- if (empty($type)) { // merge failed
- return null;
+ // combining not and anything else than media type is too risky and should be avoided
+ if (! $mediaTypeOnly) {
+ if (in_array(Type::T_NOT, $newType) || ($type && in_array(Type::T_NOT, $type) )) {
+ if ($type) {
+ array_unshift($parts, implode(' ', array_filter($type)));
+ }
+
+ if (! empty($parts)) {
+ if (strlen($current)) {
+ $current .= $this->formatter->tagSeparator;
+ }
+
+ $current .= implode(' and ', $parts);
+ }
+
+ if ($current) {
+ $out[] = $start . $current;
+ }
+
+ $current = "";
+ $type = null;
+ $parts = [];
+ }
+ }
+
+ if ($newType === ['all'] && $default) {
+ $default = $start . 'all';
+ }
+
+ // all can be safely ignored and mixed with whatever else
+ if ($newType !== ['all']) {
+ if ($type) {
+ $type = $this->mergeMediaTypes($type, $newType);
+
+ if (empty($type)) {
+ // merge failed : ignore this query that is not valid, skip to the next one
+ $parts = [];
+ $default = ''; // if everything fail, no @media at all
+ continue 3;
+ }
+ } else {
+ $type = $newType;
}
- } else {
- $type = array_map([$this, 'compileValue'], array_slice($q, 1));
}
break;
@@ -1400,20 +2090,34 @@ class Compiler
}
if (! empty($parts)) {
- if ($first) {
- $first = false;
- $out .= ' ';
- } else {
- $out .= $this->formatter->tagSeparator;
+ if (strlen($current)) {
+ $current .= $this->formatter->tagSeparator;
}
- $out .= implode(' and ', $parts);
+ $current .= implode(' and ', $parts);
}
}
+ if ($current) {
+ $out[] = $start . $current;
+ }
+
+ // no @media type except all, and no conflict?
+ if (! $out && $default) {
+ $out[] = $default;
+ }
+
return $out;
}
+ /**
+ * Merge direct relationships between selectors
+ *
+ * @param array $selectors1
+ * @param array $selectors2
+ *
+ * @return array
+ */
protected function mergeDirectRelationships($selectors1, $selectors2)
{
if (empty($selectors1) || empty($selectors2)) {
@@ -1423,7 +2127,7 @@ class Compiler
$part1 = end($selectors1);
$part2 = end($selectors2);
- if (! $this->isImmediateRelationshipCombinator($part1[0]) || $part1 !== $part2) {
+ if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
return array_merge($selectors1, $selectors2);
}
@@ -1433,13 +2137,18 @@ class Compiler
$part1 = array_pop($selectors1);
$part2 = array_pop($selectors2);
- if ($this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
- $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged);
+ if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
+ if ($this->isImmediateRelationshipCombinator(reset($merged)[0])) {
+ array_unshift($merged, [$part1[0] . $part2[0]]);
+ $merged = array_merge($selectors1, $selectors2, $merged);
+ } else {
+ $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged);
+ }
+
break;
}
array_unshift($merged, $part1);
- array_unshift($merged, [array_pop($selectors1)[0] . array_pop($selectors2)[0]]);
} while (! empty($selectors1) && ! empty($selectors2));
return $merged;
@@ -1463,23 +2172,19 @@ class Compiler
return $type1;
}
- $m1 = '';
- $t1 = '';
-
if (count($type1) > 1) {
- $m1= strtolower($type1[0]);
- $t1= strtolower($type1[1]);
+ $m1 = strtolower($type1[0]);
+ $t1 = strtolower($type1[1]);
} else {
+ $m1 = '';
$t1 = strtolower($type1[0]);
}
- $m2 = '';
- $t2 = '';
-
if (count($type2) > 1) {
$m2 = strtolower($type2[0]);
$t2 = strtolower($type2[1]);
} else {
+ $m2 = '';
$t2 = strtolower($type2[0]);
}
@@ -1514,13 +2219,13 @@ class Compiler
/**
* Compile import; returns true if the value was something that could be imported
*
- * @param array $rawPath
- * @param array $out
- * @param boolean $once
+ * @param array $rawPath
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+ * @param boolean $once
*
* @return boolean
*/
- protected function compileImport($rawPath, $out, $once = false)
+ protected function compileImport($rawPath, OutputBlock $out, $once = false)
{
if ($rawPath[0] === Type::T_STRING) {
$path = $this->compileStringContent($rawPath);
@@ -1534,6 +2239,8 @@ class Compiler
return true;
}
+ $this->appendRootDirective('@import ' . $this->compileValue($rawPath). ';', $out);
+
return false;
}
@@ -1545,57 +2252,155 @@ class Compiler
foreach ($rawPath[2] as $path) {
if ($path[0] !== Type::T_STRING) {
+ $this->appendRootDirective('@import ' . $this->compileValue($rawPath) . ';', $out);
+
return false;
}
}
foreach ($rawPath[2] as $path) {
- $this->compileImport($path, $out);
+ $this->compileImport($path, $out, $once);
}
return true;
}
+ $this->appendRootDirective('@import ' . $this->compileValue($rawPath) . ';', $out);
+
return false;
}
+
+ /**
+ * Append a root directive like @import or @charset as near as the possible from the source code
+ * (keeping before comments, @import and @charset coming before in the source code)
+ *
+ * @param string $line
+ * @param @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+ * @param array $allowed
+ */
+ protected function appendRootDirective($line, $out, $allowed = [Type::T_COMMENT])
+ {
+ $root = $out;
+
+ while ($root->parent) {
+ $root = $root->parent;
+ }
+
+ $i = 0;
+
+ while ($i < count($root->children)) {
+ if (! isset($root->children[$i]->type) || ! in_array($root->children[$i]->type, $allowed)) {
+ break;
+ }
+
+ $i++;
+ }
+
+ // remove incompatible children from the bottom of the list
+ $saveChildren = [];
+
+ while ($i < count($root->children)) {
+ $saveChildren[] = array_pop($root->children);
+ }
+
+ // insert the directive as a comment
+ $child = $this->makeOutputBlock(Type::T_COMMENT);
+ $child->lines[] = $line;
+ $child->sourceName = $this->sourceNames[$this->sourceIndex];
+ $child->sourceLine = $this->sourceLine;
+ $child->sourceColumn = $this->sourceColumn;
+
+ $root->children[] = $child;
+
+ // repush children
+ while (count($saveChildren)) {
+ $root->children[] = array_pop($saveChildren);
+ }
+ }
+
+ /**
+ * Append lines to the current output block:
+ * directly to the block or through a child if necessary
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+ * @param string $type
+ * @param string|mixed $line
+ */
+ protected function appendOutputLine(OutputBlock $out, $type, $line)
+ {
+ $outWrite = &$out;
+
+ if ($type === Type::T_COMMENT) {
+ $parent = $out->parent;
+
+ if (end($parent->children) !== $out) {
+ $outWrite = &$parent->children[count($parent->children) - 1];
+ }
+ }
+
+ // check if it's a flat output or not
+ if (count($out->children)) {
+ $lastChild = &$out->children[count($out->children) - 1];
+
+ if ($lastChild->depth === $out->depth && is_null($lastChild->selectors) && ! count($lastChild->children)) {
+ $outWrite = $lastChild;
+ } else {
+ $nextLines = $this->makeOutputBlock($type);
+ $nextLines->parent = $out;
+ $nextLines->depth = $out->depth;
+
+ $out->children[] = $nextLines;
+ $outWrite = &$nextLines;
+ }
+ }
+
+ $outWrite->lines[] = $line;
+ }
+
/**
* Compile child; returns a value to halt execution
*
- * @param array $child
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
+ * @param array $child
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
*
* @return array
*/
protected function compileChild($child, OutputBlock $out)
{
- $this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
- $this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
- $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
+ if (isset($child[Parser::SOURCE_LINE])) {
+ $this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
+ $this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
+ $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
+ } elseif (is_array($child) && isset($child[1]->sourceLine)) {
+ $this->sourceIndex = $child[1]->sourceIndex;
+ $this->sourceLine = $child[1]->sourceLine;
+ $this->sourceColumn = $child[1]->sourceColumn;
+ } elseif (! empty($out->sourceLine) && ! empty($out->sourceName)) {
+ $this->sourceLine = $out->sourceLine;
+ $this->sourceIndex = array_search($out->sourceName, $this->sourceNames);
+ $this->sourceColumn = $out->sourceColumn;
+
+ if ($this->sourceIndex === false) {
+ $this->sourceIndex = null;
+ }
+ }
switch ($child[0]) {
case Type::T_SCSSPHP_IMPORT_ONCE:
- list(, $rawPath) = $child;
+ $rawPath = $this->reduce($child[1]);
- $rawPath = $this->reduce($rawPath);
-
- if (! $this->compileImport($rawPath, $out, true)) {
- $out->lines[] = '@import ' . $this->compileValue($rawPath) . ';';
- }
+ $this->compileImport($rawPath, $out, true);
break;
case Type::T_IMPORT:
- list(, $rawPath) = $child;
+ $rawPath = $this->reduce($child[1]);
- $rawPath = $this->reduce($rawPath);
-
- if (! $this->compileImport($rawPath, $out)) {
- $out->lines[] = '@import ' . $this->compileValue($rawPath) . ';';
- }
+ $this->compileImport($rawPath, $out);
break;
case Type::T_DIRECTIVE:
- $this->compileDirective($child[1]);
+ $this->compileDirective($child[1], $out);
break;
case Type::T_AT_ROOT:
@@ -1613,8 +2418,7 @@ class Compiler
case Type::T_CHARSET:
if (! $this->charsetSeen) {
$this->charsetSeen = true;
-
- $out->lines[] = '@charset ' . $this->compileValue($child[1]) . ';';
+ $this->appendRootDirective('@charset ' . $this->compileValue($child[1]) . ';', $out);
}
break;
@@ -1622,35 +2426,98 @@ class Compiler
list(, $name, $value) = $child;
if ($name[0] === Type::T_VARIABLE) {
- $flags = isset($child[3]) ? $child[3] : [];
+ $flags = isset($child[3]) ? $child[3] : [];
$isDefault = in_array('!default', $flags);
- $isGlobal = in_array('!global', $flags);
+ $isGlobal = in_array('!global', $flags);
if ($isGlobal) {
- $this->set($name[1], $this->reduce($value), false, $this->rootEnv);
+ $this->set($name[1], $this->reduce($value), false, $this->rootEnv, $value);
break;
}
$shouldSet = $isDefault &&
- (($result = $this->get($name[1], false)) === null
- || $result === static::$null);
+ (is_null($result = $this->get($name[1], false)) ||
+ $result === static::$null);
if (! $isDefault || $shouldSet) {
- $this->set($name[1], $this->reduce($value));
+ $this->set($name[1], $this->reduce($value), true, null, $value);
}
break;
}
$compiledName = $this->compileValue($name);
- // handle shorthand syntax: size / line-height
- if ($compiledName === 'font') {
- if ($value[0] === Type::T_EXPRESSION && $value[1] === '/') {
- $value = $this->expToString($value);
- } elseif ($value[0] === Type::T_LIST) {
- foreach ($value[2] as &$item) {
+ // handle shorthand syntaxes : size / line-height...
+ if (in_array($compiledName, ['font', 'grid-row', 'grid-column', 'border-radius'])) {
+ if ($value[0] === Type::T_VARIABLE) {
+ // if the font value comes from variable, the content is already reduced
+ // (i.e., formulas were already calculated), so we need the original unreduced value
+ $value = $this->get($value[1], true, null, true);
+ }
+
+ $shorthandValue=&$value;
+
+ $shorthandDividerNeedsUnit = false;
+ $maxListElements = null;
+ $maxShorthandDividers = 1;
+
+ switch ($compiledName) {
+ case 'border-radius':
+ $maxListElements = 4;
+ $shorthandDividerNeedsUnit = true;
+ break;
+ }
+
+ if ($compiledName === 'font' and $value[0] === Type::T_LIST && $value[1]==',') {
+ // this is the case if more than one font is given: example: "font: 400 1em/1.3 arial,helvetica"
+ // we need to handle the first list element
+ $shorthandValue=&$value[2][0];
+ }
+
+ if ($shorthandValue[0] === Type::T_EXPRESSION && $shorthandValue[1] === '/') {
+ $revert = true;
+
+ if ($shorthandDividerNeedsUnit) {
+ $divider = $shorthandValue[3];
+
+ if (is_array($divider)) {
+ $divider = $this->reduce($divider, true);
+ }
+
+ if (intval($divider->dimension) and !count($divider->units)) {
+ $revert = false;
+ }
+ }
+
+ if ($revert) {
+ $shorthandValue = $this->expToString($shorthandValue);
+ }
+ } elseif ($shorthandValue[0] === Type::T_LIST) {
+ foreach ($shorthandValue[2] as &$item) {
if ($item[0] === Type::T_EXPRESSION && $item[1] === '/') {
- $item = $this->expToString($item);
+ if ($maxShorthandDividers > 0) {
+ $revert = true;
+ // if the list of values is too long, this has to be a shorthand,
+ // otherwise it could be a real division
+ if (is_null($maxListElements) or count($shorthandValue[2]) <= $maxListElements) {
+ if ($shorthandDividerNeedsUnit) {
+ $divider = $item[3];
+
+ if (is_array($divider)) {
+ $divider = $this->reduce($divider, true);
+ }
+
+ if (intval($divider->dimension) and !count($divider->units)) {
+ $revert = false;
+ }
+ }
+ }
+
+ if ($revert) {
+ $item = $this->expToString($item);
+ $maxShorthandDividers--;
+ }
+ }
}
}
}
@@ -1668,10 +2535,11 @@ class Compiler
$compiledValue = $this->compileValue($value);
- $out->lines[] = $this->formatter->property(
+ $line = $this->formatter->property(
$compiledName,
$compiledValue
);
+ $this->appendOutputLine($out, Type::T_ASSIGN, $line);
break;
case Type::T_COMMENT:
@@ -1680,27 +2548,32 @@ class Compiler
break;
}
- $out->lines[] = $child[1];
+ $line = $this->compileCommentValue($child, true);
+ $this->appendOutputLine($out, Type::T_COMMENT, $line);
break;
case Type::T_MIXIN:
case Type::T_FUNCTION:
list(, $block) = $child;
-
- $this->set(static::$namespaces[$block->type] . $block->name, $block);
+ // the block need to be able to go up to it's parent env to resolve vars
+ $block->parentEnv = $this->getStoreEnv();
+ $this->set(static::$namespaces[$block->type] . $block->name, $block, true);
break;
case Type::T_EXTEND:
- list(, $selectors) = $child;
-
- foreach ($selectors as $sel) {
+ foreach ($child[1] as $sel) {
$results = $this->evalSelectors([$sel]);
foreach ($results as $result) {
// only use the first one
$result = current($result);
+ $selectors = $out->selectors;
- $this->pushExtends($result, $out->selectors, $child);
+ if (! $selectors && isset($child['selfParent'])) {
+ $selectors = $this->multiplySelectors($this->env, $child['selfParent']);
+ }
+
+ $this->pushExtends($result, $selectors, $child);
}
}
break;
@@ -1827,31 +2700,12 @@ class Compiler
return $this->reduce($child[1], true);
case Type::T_NESTED_PROPERTY:
- list(, $prop) = $child;
-
- $prefixed = [];
- $prefix = $this->compileValue($prop->prefix) . '-';
-
- foreach ($prop->children as $child) {
- switch ($child[0]) {
- case Type::T_ASSIGN:
- array_unshift($child[1][2], $prefix);
- break;
-
- case Type::T_NESTED_PROPERTY:
- array_unshift($child[1]->prefix[2], $prefix);
- break;
- }
-
- $prefixed[] = $child;
- }
-
- $this->compileChildrenNoReturn($prefixed, $out);
+ $this->compileNestedPropertiesBlock($child[1], $out);
break;
case Type::T_INCLUDE:
// including a mixin
- list(, $name, $argValues, $content) = $child;
+ list(, $name, $argValues, $content, $argUsing) = $child;
$mixin = $this->get(static::$namespaces['mixin'] . $name, false);
@@ -1869,10 +2723,43 @@ class Compiler
$storeEnv = $this->storeEnv;
$this->storeEnv = $this->env;
- if (isset($content)) {
- $content->scope = $callingScope;
+ // Find the parent selectors in the env to be able to know what '&' refers to in the mixin
+ // and assign this fake parent to childs
+ $selfParent = null;
- $this->setRaw(static::$namespaces['special'] . 'content', $content, $this->env);
+ if (isset($child['selfParent']) && isset($child['selfParent']->selectors)) {
+ $selfParent = $child['selfParent'];
+ } else {
+ $parentSelectors = $this->multiplySelectors($this->env);
+
+ if ($parentSelectors) {
+ $parent = new Block();
+ $parent->selectors = $parentSelectors;
+
+ foreach ($mixin->children as $k => $child) {
+ if (isset($child[1]) && is_object($child[1]) && $child[1] instanceof Block) {
+ $mixin->children[$k][1]->parent = $parent;
+ }
+ }
+ }
+ }
+
+ // clone the stored content to not have its scope spoiled by a further call to the same mixin
+ // i.e., recursive @include of the same mixin
+ if (isset($content)) {
+ $copyContent = clone $content;
+ $copyContent->scope = clone $callingScope;
+
+ $this->setRaw(static::$namespaces['special'] . 'content', $copyContent, $this->env);
+ } else {
+ $this->setRaw(static::$namespaces['special'] . 'content', null, $this->env);
+ }
+
+ // save the "using" argument list for applying it to when "@content" is invoked
+ if (isset($argUsing)) {
+ $this->setRaw(static::$namespaces['special'] . 'using', $argUsing, $this->env);
+ } else {
+ $this->setRaw(static::$namespaces['special'] . 'using', null, $this->env);
}
if (isset($mixin->args)) {
@@ -1881,7 +2768,13 @@ class Compiler
$this->env->marker = 'mixin';
- $this->compileChildrenNoReturn($mixin->children, $out);
+ if (! empty($mixin->parentEnv)) {
+ $this->env->declarationScopeParent = $mixin->parentEnv;
+ } else {
+ $this->throwError("@mixin $name() without parentEnv");
+ }
+
+ $this->compileChildrenNoReturn($mixin->children, $out, $selfParent, $this->env->marker . " " . $name);
$this->storeEnv = $storeEnv;
@@ -1889,19 +2782,35 @@ class Compiler
break;
case Type::T_MIXIN_CONTENT:
- $content = $this->get(static::$namespaces['special'] . 'content', false, $this->getStoreEnv())
- ?: $this->get(static::$namespaces['special'] . 'content', false, $this->env);
+ $env = isset($this->storeEnv) ? $this->storeEnv : $this->env;
+ $content = $this->get(static::$namespaces['special'] . 'content', false, $env);
+ $argUsing = $this->get(static::$namespaces['special'] . 'using', false, $env);
+ $argContent = $child[1];
if (! $content) {
$content = new \stdClass();
- $content->scope = new \stdClass();
- $content->children = $this->storeEnv->parent->block->children;
+ $content->scope = new \stdClass();
+ $content->children = $env->parent->block->children;
break;
}
$storeEnv = $this->storeEnv;
+ $varsUsing = [];
+
+ if (isset($argUsing) && isset($argContent)) {
+ // Get the arguments provided for the content with the names provided in the "using" argument list
+ $this->storeEnv = $this->env;
+ $varsUsing = $this->applyArguments($argUsing, $argContent, false);
+ }
+
+ // restore the scope from the @content
$this->storeEnv = $content->scope;
+ // append the vars from using if any
+ foreach ($varsUsing as $name => $val) {
+ $this->set($name, $val, true, $this->storeEnv);
+ }
+
$this->compileChildrenNoReturn($content->children, $out);
$this->storeEnv = $storeEnv;
@@ -1910,25 +2819,31 @@ class Compiler
case Type::T_DEBUG:
list(, $value) = $child;
- $line = $this->sourceLine;
+ $fname = $this->sourceNames[$this->sourceIndex];
+ $line = $this->sourceLine;
$value = $this->compileValue($this->reduce($value, true));
- fwrite($this->stderr, "Line $line DEBUG: $value\n");
+
+ fwrite($this->stderr, "File $fname on line $line DEBUG: $value\n");
break;
case Type::T_WARN:
list(, $value) = $child;
- $line = $this->sourceLine;
+ $fname = $this->sourceNames[$this->sourceIndex];
+ $line = $this->sourceLine;
$value = $this->compileValue($this->reduce($value, true));
- fwrite($this->stderr, "Line $line WARN: $value\n");
+
+ fwrite($this->stderr, "File $fname on line $line WARN: $value\n");
break;
case Type::T_ERROR:
list(, $value) = $child;
- $line = $this->sourceLine;
+ $fname = $this->sourceNames[$this->sourceIndex];
+ $line = $this->sourceLine;
$value = $this->compileValue($this->reduce($value, true));
- $this->throwError("Line $line ERROR: $value\n");
+
+ $this->throwError("File $fname on line $line ERROR: $value\n");
break;
case Type::T_CONTROL:
@@ -1973,7 +2888,7 @@ class Compiler
*
* @param array $value
*
- * @return array
+ * @return boolean
*/
protected function isTruthy($value)
{
@@ -2004,7 +2919,7 @@ class Compiler
switch ($value[0]) {
case Type::T_EXPRESSION:
if ($value[1] === '/') {
- return $this->shouldEval($value[2], $value[3]);
+ return $this->shouldEval($value[2]) || $this->shouldEval($value[3]);
}
// fall-thru
@@ -2022,13 +2937,15 @@ class Compiler
* @param array $value
* @param boolean $inExp
*
- * @return array|\Leafo\ScssPhp\Node\Number
+ * @return null|string|array|\ScssPhp\ScssPhp\Node\Number
*/
protected function reduce($value, $inExp = false)
{
- list($type) = $value;
+ if (is_null($value)) {
+ return null;
+ }
- switch ($type) {
+ switch ($value[0]) {
case Type::T_EXPRESSION:
list(, $op, $left, $right, $inParens) = $value;
@@ -2042,16 +2959,15 @@ class Compiler
}
// special case: looks like css shorthand
- if ($opName == 'div' && ! $inParens && ! $inExp && isset($right[2])
- && (($right[0] !== Type::T_NUMBER && $right[2] != '')
- || ($right[0] === Type::T_NUMBER && ! $right->unitless()))
+ if ($opName == 'div' && ! $inParens && ! $inExp && isset($right[2]) &&
+ (($right[0] !== Type::T_NUMBER && $right[2] != '') ||
+ ($right[0] === Type::T_NUMBER && ! $right->unitless()))
) {
return $this->expToString($value);
}
- $left = $this->coerceForExpression($left);
+ $left = $this->coerceForExpression($left);
$right = $this->coerceForExpression($right);
-
$ltype = $left[0];
$rtype = $right[0];
@@ -2161,9 +3077,7 @@ class Compiler
return [Type::T_STRING, '', [$op, $exp]];
case Type::T_VARIABLE:
- list(, $name) = $value;
-
- return $this->reduce($this->get($name));
+ return $this->reduce($this->get($value[1]));
case Type::T_LIST:
foreach ($value[2] as &$item) {
@@ -2195,12 +3109,20 @@ class Compiler
case Type::T_INTERPOLATE:
$value[1] = $this->reduce($value[1]);
+ if ($inExp) {
+ return $value[1];
+ }
+
return $value;
case Type::T_FUNCTION_CALL:
- list(, $name, $argValues) = $value;
+ return $this->fncall($value[1], $value[2]);
- return $this->fncall($name, $argValues);
+ case Type::T_SELF:
+ $selfSelector = $this->multiplySelectors($this->env);
+ $selfSelector = $this->collapseSelectors($selfSelector, true);
+
+ return $selfSelector;
default:
return $value;
@@ -2215,7 +3137,7 @@ class Compiler
*
* @return array|null
*/
- private function fncall($name, $argValues)
+ protected function fncall($name, $argValues)
{
// SCSS @function
if ($this->callScssFunction($name, $argValues, $returnValue)) {
@@ -2261,9 +3183,8 @@ class Compiler
public function normalizeValue($value)
{
$value = $this->coerceForExpression($this->reduce($value));
- list($type) = $value;
- switch ($type) {
+ switch ($value[0]) {
case Type::T_LIST:
$value = $this->extractInterpolation($value);
@@ -2275,10 +3196,14 @@ class Compiler
$value[2][$key] = $this->normalizeValue($item);
}
+ if (! empty($value['enclosing'])) {
+ unset($value['enclosing']);
+ }
+
return $value;
case Type::T_STRING:
- return [$type, '"', [$this->compileStringContent($value)]];
+ return [$value[0], '"', [$this->compileStringContent($value)]];
case Type::T_NUMBER:
return $value->normalize();
@@ -2297,7 +3222,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
protected function opAddNumberNumber($left, $right)
{
@@ -2310,7 +3235,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
protected function opMulNumberNumber($left, $right)
{
@@ -2323,7 +3248,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
protected function opSubNumberNumber($left, $right)
{
@@ -2336,7 +3261,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return array|\Leafo\ScssPhp\Node\Number
+ * @return array|\ScssPhp\ScssPhp\Node\Number
*/
protected function opDivNumberNumber($left, $right)
{
@@ -2353,7 +3278,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
protected function opModNumberNumber($left, $right)
{
@@ -2366,7 +3291,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return array
+ * @return array|null
*/
protected function opAdd($left, $right)
{
@@ -2389,6 +3314,8 @@ class Compiler
return $strRight;
}
+
+ return null;
}
/**
@@ -2398,15 +3325,21 @@ class Compiler
* @param array $right
* @param boolean $shouldEval
*
- * @return array
+ * @return array|null
*/
protected function opAnd($left, $right, $shouldEval)
{
+ $truthy = ($left === static::$null || $right === static::$null) ||
+ ($left === static::$false || $left === static::$true) &&
+ ($right === static::$false || $right === static::$true);
+
if (! $shouldEval) {
- return;
+ if (! $truthy) {
+ return null;
+ }
}
- if ($left !== static::$false and $left !== static::$null) {
+ if ($left !== static::$false && $left !== static::$null) {
return $this->reduce($right, true);
}
@@ -2420,15 +3353,21 @@ class Compiler
* @param array $right
* @param boolean $shouldEval
*
- * @return array
+ * @return array|null
*/
protected function opOr($left, $right, $shouldEval)
{
+ $truthy = ($left === static::$null || $right === static::$null) ||
+ ($left === static::$false || $left === static::$true) &&
+ ($right === static::$false || $right === static::$true);
+
if (! $shouldEval) {
- return;
+ if (! $truthy) {
+ return null;
+ }
}
- if ($left !== static::$false and $left !== static::$null) {
+ if ($left !== static::$false && $left !== static::$null) {
return $left;
}
@@ -2639,7 +3578,7 @@ class Compiler
* @param array $left
* @param array $right
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
protected function opCmpNumberNumber($left, $right)
{
@@ -2677,15 +3616,13 @@ class Compiler
*
* @param array $value
*
- * @return string
+ * @return string|array
*/
public function compileValue($value)
{
$value = $this->reduce($value);
- list($type) = $value;
-
- switch ($type) {
+ switch ($value[0]) {
case Type::T_KEYWORD:
return $value[1];
@@ -2696,14 +3633,38 @@ class Compiler
// [4] - optional alpha component
list(, $r, $g, $b) = $value;
- $r = round($r);
- $g = round($g);
- $b = round($b);
+ $r = $this->compileRGBAValue($r);
+ $g = $this->compileRGBAValue($g);
+ $b = $this->compileRGBAValue($b);
- if (count($value) === 5 && $value[4] !== 1) { // rgba
- $a = new Node\Number($value[4], '');
+ if (count($value) === 5) {
+ $alpha = $this->compileRGBAValue($value[4], true);
- return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')';
+ if (! is_numeric($alpha) || $alpha < 1) {
+ $colorName = Colors::RGBaToColorName($r, $g, $b, $alpha);
+
+ if (! is_null($colorName)) {
+ return $colorName;
+ }
+
+ if (is_numeric($alpha)) {
+ $a = new Node\Number($alpha, '');
+ } else {
+ $a = $alpha;
+ }
+
+ return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')';
+ }
+ }
+
+ if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b)) {
+ return 'rgb(' . $r . ', ' . $g . ', ' . $b . ')';
+ }
+
+ $colorName = Colors::RGBaToColorName($r, $g, $b);
+
+ if (! is_null($colorName)) {
+ return $colorName;
}
$h = sprintf('#%02x%02x%02x', $r, $g, $b);
@@ -2734,9 +3695,28 @@ class Compiler
}
list(, $delim, $items) = $value;
+ $pre = $post = "";
+ if (! empty($value['enclosing'])) {
+ switch ($value['enclosing']) {
+ case 'parent':
+ //$pre = "(";
+ //$post = ")";
+ break;
+ case 'forced_parent':
+ $pre = "(";
+ $post = ")";
+ break;
+ case 'bracket':
+ case 'forced_bracket':
+ $pre = "[";
+ $post = "]";
+ break;
+ }
+ }
+ $prefix_value = '';
if ($delim !== ' ') {
- $delim .= ' ';
+ $prefix_value = ' ';
}
$filtered = [];
@@ -2746,14 +3726,18 @@ class Compiler
continue;
}
- $filtered[] = $this->compileValue($item);
+ $compiled = $this->compileValue($item);
+ if ($prefix_value && strlen($compiled)) {
+ $compiled = $prefix_value . $compiled;
+ }
+ $filtered[] = $compiled;
}
- return implode("$delim", $filtered);
+ return $pre . substr(implode("$delim", $filtered), strlen($prefix_value)) . $post;
case Type::T_MAP:
- $keys = $value[1];
- $values = $value[2];
+ $keys = $value[1];
+ $values = $value[2];
$filtered = [];
for ($i = 0, $s = count($keys); $i < $s; $i++) {
@@ -2771,20 +3755,29 @@ class Compiler
list(, $interpolate, $left, $right) = $value;
list(,, $whiteLeft, $whiteRight) = $interpolate;
+ $delim = $left[1];
+
+ if ($delim && $delim !== ' ' && ! $whiteLeft) {
+ $delim .= ' ';
+ }
+
$left = count($left[2]) > 0 ?
- $this->compileValue($left) . $whiteLeft : '';
+ $this->compileValue($left) . $delim . $whiteLeft: '';
+
+ $delim = $right[1];
+
+ if ($delim && $delim !== ' ') {
+ $delim .= ' ';
+ }
$right = count($right[2]) > 0 ?
- $whiteRight . $this->compileValue($right) : '';
+ $whiteRight . $delim . $this->compileValue($right) : '';
return $left . $this->compileValue($interpolate) . $right;
case Type::T_INTERPOLATE:
- // raw parse node
- list(, $exp) = $value;
-
// strip quotes if it's a string
- $reduced = $this->reduce($exp);
+ $reduced = $this->reduce($value[1]);
switch ($reduced[0]) {
case Type::T_LIST:
@@ -2808,6 +3801,7 @@ class Compiler
}
$temp = $this->compileValue([Type::T_KEYWORD, $item]);
+
if ($temp[0] === Type::T_STRING) {
$filtered[] = $this->compileStringContent($temp);
} elseif ($temp[0] === Type::T_KEYWORD) {
@@ -2833,8 +3827,11 @@ class Compiler
case Type::T_NULL:
return 'null';
+ case Type::T_COMMENT:
+ return $this->compileCommentValue($value);
+
default:
- $this->throwError("unknown value type: $type");
+ $this->throwError("unknown value type: ".json_encode($value));
}
}
@@ -2898,44 +3895,70 @@ class Compiler
/**
* Find the final set of selectors
*
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param \ScssPhp\ScssPhp\Block $selfParent
*
* @return array
*/
- protected function multiplySelectors(Environment $env)
+ protected function multiplySelectors(Environment $env, $selfParent = null)
{
$envs = $this->compactEnv($env);
$selectors = [];
$parentSelectors = [[]];
+ $selfParentSelectors = null;
+
+ if (! is_null($selfParent) && $selfParent->selectors) {
+ $selfParentSelectors = $this->evalSelectors($selfParent->selectors);
+ }
+
while ($env = array_pop($envs)) {
if (empty($env->selectors)) {
continue;
}
- $selectors = [];
+ $selectors = $env->selectors;
- foreach ($env->selectors as $selector) {
- foreach ($parentSelectors as $parent) {
- $selectors[] = $this->joinSelectors($parent, $selector);
+ do {
+ $stillHasSelf = false;
+ $prevSelectors = $selectors;
+ $selectors = [];
+
+ foreach ($prevSelectors as $selector) {
+ foreach ($parentSelectors as $parent) {
+ if ($selfParentSelectors) {
+ foreach ($selfParentSelectors as $selfParent) {
+ // if no '&' in the selector, each call will give same result, only add once
+ $s = $this->joinSelectors($parent, $selector, $stillHasSelf, $selfParent);
+ $selectors[serialize($s)] = $s;
+ }
+ } else {
+ $s = $this->joinSelectors($parent, $selector, $stillHasSelf);
+ $selectors[serialize($s)] = $s;
+ }
+ }
}
- }
+ } while ($stillHasSelf);
$parentSelectors = $selectors;
}
+ $selectors = array_values($selectors);
+
return $selectors;
}
/**
* Join selectors; looks for & to replace, or append parent before child
*
- * @param array $parent
- * @param array $child
- *
+ * @param array $parent
+ * @param array $child
+ * @param boolean &$stillHasSelf
+ * @param array $selfParentSelectors
+
* @return array
*/
- protected function joinSelectors($parent, $child)
+ protected function joinSelectors($parent, $child, &$stillHasSelf, $selfParentSelectors = null)
{
$setSelf = false;
$out = [];
@@ -2944,16 +3967,35 @@ class Compiler
$newPart = [];
foreach ($part as $p) {
- if ($p === static::$selfSelector) {
+ // only replace & once and should be recalled to be able to make combinations
+ if ($p === static::$selfSelector && $setSelf) {
+ $stillHasSelf = true;
+ }
+
+ if ($p === static::$selfSelector && ! $setSelf) {
$setSelf = true;
- foreach ($parent as $i => $parentPart) {
+ if (is_null($selfParentSelectors)) {
+ $selfParentSelectors = $parent;
+ }
+
+ foreach ($selfParentSelectors as $i => $parentPart) {
if ($i > 0) {
$out[] = $newPart;
$newPart = [];
}
foreach ($parentPart as $pp) {
+ if (is_array($pp)) {
+ $flatten = [];
+
+ array_walk_recursive($pp, function ($a) use (&$flatten) {
+ $flatten[] = $a;
+ });
+
+ $pp = implode($flatten);
+ }
+
$newPart[] = $pp;
}
}
@@ -2971,8 +4013,8 @@ class Compiler
/**
* Multiply media
*
- * @param \Leafo\ScssPhp\Compiler\Environment $env
- * @param array $childQueries
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param array $childQueries
*
* @return array
*/
@@ -2993,7 +4035,15 @@ class Compiler
? $env->block->queryList
: [[[Type::T_MEDIA_VALUE, $env->block->value]]];
- if ($childQueries === null) {
+ $store = [$this->env, $this->storeEnv];
+
+ $this->env = $env;
+ $this->storeEnv = null;
+ $parentQueries = $this->evaluateMediaQuery($parentQueries);
+
+ list($this->env, $this->storeEnv) = $store;
+
+ if (is_null($childQueries)) {
$childQueries = $parentQueries;
} else {
$originalQueries = $childQueries;
@@ -3001,7 +4051,11 @@ class Compiler
foreach ($parentQueries as $parentQuery) {
foreach ($originalQueries as $childQuery) {
- $childQueries []= array_merge($parentQuery, $childQuery);
+ $childQueries[] = array_merge(
+ $parentQuery,
+ [[Type::T_MEDIA_TYPE, [Type::T_KEYWORD, 'all']]],
+ $childQuery
+ );
}
}
}
@@ -3012,11 +4066,11 @@ class Compiler
/**
* Convert env linked list to stack
*
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
*
* @return array
*/
- private function compactEnv(Environment $env)
+ protected function compactEnv(Environment $env)
{
for ($envs = []; $env; $env = $env->parent) {
$envs[] = $env;
@@ -3030,9 +4084,9 @@ class Compiler
*
* @param array $envs
*
- * @return \Leafo\ScssPhp\Compiler\Environment
+ * @return \ScssPhp\ScssPhp\Compiler\Environment
*/
- private function extractEnv($envs)
+ protected function extractEnv($envs)
{
for ($env = null; $e = array_pop($envs);) {
$e->parent = $env;
@@ -3045,9 +4099,9 @@ class Compiler
/**
* Push environment
*
- * @param \Leafo\ScssPhp\Block $block
+ * @param \ScssPhp\ScssPhp\Block $block
*
- * @return \Leafo\ScssPhp\Compiler\Environment
+ * @return \ScssPhp\ScssPhp\Compiler\Environment
*/
protected function pushEnv(Block $block = null)
{
@@ -3073,7 +4127,7 @@ class Compiler
/**
* Get store environment
*
- * @return \Leafo\ScssPhp\Compiler\Environment
+ * @return \ScssPhp\ScssPhp\Compiler\Environment
*/
protected function getStoreEnv()
{
@@ -3083,12 +4137,13 @@ class Compiler
/**
* Set variable
*
- * @param string $name
- * @param mixed $value
- * @param boolean $shadow
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param string $name
+ * @param mixed $value
+ * @param boolean $shadow
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param mixed $valueUnreduced
*/
- protected function set($name, $value, $shadow = false, Environment $env = null)
+ protected function set($name, $value, $shadow = false, Environment $env = null, $valueUnreduced = null)
{
$name = $this->normalizeName($name);
@@ -3097,20 +4152,21 @@ class Compiler
}
if ($shadow) {
- $this->setRaw($name, $value, $env);
+ $this->setRaw($name, $value, $env, $valueUnreduced);
} else {
- $this->setExisting($name, $value, $env);
+ $this->setExisting($name, $value, $env, $valueUnreduced);
}
}
/**
* Set existing variable
*
- * @param string $name
- * @param mixed $value
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param string $name
+ * @param mixed $value
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param mixed $valueUnreduced
*/
- protected function setExisting($name, $value, Environment $env)
+ protected function setExisting($name, $value, Environment $env, $valueUnreduced = null)
{
$storeEnv = $env;
@@ -3135,18 +4191,27 @@ class Compiler
}
$env->store[$name] = $value;
+
+ if ($valueUnreduced) {
+ $env->storeUnreduced[$name] = $valueUnreduced;
+ }
}
/**
* Set raw variable
*
- * @param string $name
- * @param mixed $value
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param string $name
+ * @param mixed $value
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param mixed $valueUnreduced
*/
- protected function setRaw($name, $value, Environment $env)
+ protected function setRaw($name, $value, Environment $env, $valueUnreduced = null)
{
$env->store[$name] = $value;
+
+ if ($valueUnreduced) {
+ $env->storeUnreduced[$name] = $valueUnreduced;
+ }
}
/**
@@ -3154,13 +4219,14 @@ class Compiler
*
* @api
*
- * @param string $name
- * @param boolean $shouldThrow
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param string $name
+ * @param boolean $shouldThrow
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+ * @param boolean $unreduced
*
- * @return mixed
+ * @return mixed|null
*/
- public function get($name, $shouldThrow = true, Environment $env = null)
+ public function get($name, $shouldThrow = true, Environment $env = null, $unreduced = false)
{
$normalizedName = $this->normalizeName($name);
$specialContentKey = static::$namespaces['special'] . 'content';
@@ -3169,22 +4235,34 @@ class Compiler
$env = $this->getStoreEnv();
}
- $nextIsRoot = false;
$hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%';
+ $maxDepth = 10000;
+
for (;;) {
+ if ($maxDepth-- <= 0) {
+ break;
+ }
+
if (array_key_exists($normalizedName, $env->store)) {
+ if ($unreduced && isset($env->storeUnreduced[$normalizedName])) {
+ return $env->storeUnreduced[$normalizedName];
+ }
+
return $env->store[$normalizedName];
}
if (! $hasNamespace && isset($env->marker)) {
- if (! $nextIsRoot && ! empty($env->store[$specialContentKey])) {
+ if (! empty($env->store[$specialContentKey])) {
$env = $env->store[$specialContentKey]->scope;
- $nextIsRoot = true;
continue;
}
- $env = $this->rootEnv;
+ if (! empty($env->declarationScopeParent)) {
+ $env = $env->declarationScopeParent;
+ } else {
+ $env = $this->rootEnv;
+ }
continue;
}
@@ -3196,23 +4274,24 @@ class Compiler
}
if ($shouldThrow) {
- $this->throwError("Undefined variable \$$name");
+ $this->throwError("Undefined variable \$$name" . ($maxDepth <= 0 ? " (infinite recursion)" : ""));
}
// found nothing
+ return null;
}
/**
* Has variable?
*
- * @param string $name
- * @param \Leafo\ScssPhp\Compiler\Environment $env
+ * @param string $name
+ * @param \ScssPhp\ScssPhp\Compiler\Environment $env
*
* @return boolean
*/
protected function has($name, Environment $env = null)
{
- return $this->get($name, false, $env) !== null;
+ return ! is_null($this->get($name, false, $env));
}
/**
@@ -3286,7 +4365,7 @@ class Compiler
*/
public function addParsedFile($path)
{
- if (isset($path) && file_exists($path)) {
+ if (isset($path) && is_file($path)) {
$this->parsedFiles[realpath($path)] = filemtime($path);
}
}
@@ -3308,7 +4387,7 @@ class Compiler
*
* @api
*
- * @param string $path
+ * @param string|callable $path
*/
public function addImportPath($path)
{
@@ -3430,10 +4509,10 @@ class Compiler
/**
* Import file
*
- * @param string $path
- * @param array $out
+ * @param string $path
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
*/
- protected function importFile($path, $out)
+ protected function importFile($path, OutputBlock $out)
{
// see if tree is cached
$realPath = realpath($path);
@@ -3451,6 +4530,7 @@ class Compiler
}
$pi = pathinfo($path);
+
array_unshift($this->importPaths, $pi['dirname']);
$this->compileChildrenNoReturn($tree->children, $out);
array_shift($this->importPaths);
@@ -3470,9 +4550,9 @@ class Compiler
$urls = [];
// for "normal" scss imports (ignore vanilla css and external requests)
- if (! preg_match('/\.css$|^https?:\/\//', $url)) {
+ if (! preg_match('~\.css$|^https?://~', $url)) {
// try both normal and the _partial filename
- $urls = [$url, preg_replace('/[^\/]+$/', '_\0', $url)];
+ $urls = [$url, preg_replace('~[^/]+$~', '_\0', $url)];
}
$hasExtension = preg_match('/[.]s?css$/', $url);
@@ -3481,12 +4561,15 @@ class Compiler
if (is_string($dir)) {
// check urls for normal import paths
foreach ($urls as $full) {
- $full = $dir
- . (! empty($dir) && substr($dir, -1) !== '/' ? '/' : '')
- . $full;
+ $separator = (
+ ! empty($dir) &&
+ substr($dir, -1) !== '/' &&
+ substr($full, 0, 1) !== '/'
+ ) ? '/' : '';
+ $full = $dir . $separator . $full;
- if ($this->fileExists($file = $full . '.scss') ||
- ($hasExtension && $this->fileExists($file = $full))
+ if (is_file($file = $full . '.scss') ||
+ ($hasExtension && is_file($file = $full))
) {
return $file;
}
@@ -3495,7 +4578,7 @@ class Compiler
// check custom callback for import path
$file = call_user_func($dir, $url);
- if ($file !== null) {
+ if (! is_null($file)) {
return $file;
}
}
@@ -3523,11 +4606,13 @@ class Compiler
*
* @param boolean $ignoreErrors
*
- * @return \Leafo\ScssPhp\Compiler
+ * @return \ScssPhp\ScssPhp\Compiler
*/
public function setIgnoreErrors($ignoreErrors)
{
$this->ignoreErrors = $ignoreErrors;
+
+ return $this;
}
/**
@@ -3537,7 +4622,7 @@ class Compiler
*
* @param string $msg Message with optional sprintf()-style vararg parameters
*
- * @throws \Leafo\ScssPhp\Exception\CompilerException
+ * @throws \ScssPhp\ScssPhp\Exception\CompilerException
*/
public function throwError($msg)
{
@@ -3545,16 +4630,62 @@ class Compiler
return;
}
+ $line = $this->sourceLine;
+ $column = $this->sourceColumn;
+
+ $loc = isset($this->sourceNames[$this->sourceIndex])
+ ? $this->sourceNames[$this->sourceIndex] . " on line $line, at column $column"
+ : "line: $line, column: $column";
+
if (func_num_args() > 1) {
$msg = call_user_func_array('sprintf', func_get_args());
}
- $line = $this->sourceLine;
- $msg = "$msg: line: $line";
+ $msg = "$msg: $loc";
+
+ $callStackMsg = $this->callStackMessage();
+
+ if ($callStackMsg) {
+ $msg .= "\nCall Stack:\n" . $callStackMsg;
+ }
throw new CompilerException($msg);
}
+ /**
+ * Beautify call stack for output
+ *
+ * @param boolean $all
+ * @param null $limit
+ *
+ * @return string
+ */
+ protected function callStackMessage($all = false, $limit = null)
+ {
+ $callStackMsg = [];
+ $ncall = 0;
+
+ if ($this->callStack) {
+ foreach (array_reverse($this->callStack) as $call) {
+ if ($all || (isset($call['n']) && $call['n'])) {
+ $msg = "#" . $ncall++ . " " . $call['n'] . " ";
+ $msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]])
+ ? $this->sourceNames[$call[Parser::SOURCE_INDEX]]
+ : '(unknown file)');
+ $msg .= " on line " . $call[Parser::SOURCE_LINE];
+
+ $callStackMsg[] = $msg;
+
+ if (! is_null($limit) && $ncall > $limit) {
+ break;
+ }
+ }
+ }
+ }
+
+ return implode("\n", $callStackMsg);
+ }
+
/**
* Handle import loop
*
@@ -3565,6 +4696,10 @@ class Compiler
protected function handleImportLoop($name)
{
for ($env = $this->env; $env; $env = $env->parent) {
+ if (! $env->block) {
+ continue;
+ }
+
$file = $this->sourceNames[$env->block->sourceIndex];
if (realpath($file) === $name) {
@@ -3574,18 +4709,6 @@ class Compiler
}
}
- /**
- * Does file exist?
- *
- * @param string $name
- *
- * @return boolean
- */
- protected function fileExists($name)
- {
- return file_exists($name) && is_file($name);
- }
-
/**
* Call SCSS @function
*
@@ -3619,8 +4742,13 @@ class Compiler
$tmp->children = [];
$this->env->marker = 'function';
+ if (! empty($func->parentEnv)) {
+ $this->env->declarationScopeParent = $func->parentEnv;
+ } else {
+ $this->throwError("@function $name() without parentEnv");
+ }
- $ret = $this->compileChildren($func->children, $tmp);
+ $ret = $this->compileChildren($func->children, $tmp, $this->env->marker . " " . $name);
$this->storeEnv = $storeEnv;
@@ -3655,11 +4783,17 @@ class Compiler
return false;
}
- @list($sorted, $kwargs) = $this->sortArgs($prototype, $args);
+ @list($sorted, $kwargs) = $this->sortNativeFunctionArgs($libName, $prototype, $args);
if ($name !== 'if' && $name !== 'call') {
+ $inExp = true;
+
+ if ($name === 'join') {
+ $inExp = false;
+ }
+
foreach ($sorted as &$val) {
- $val = $this->reduce($val, true);
+ $val = $this->reduce($val, $inExp);
}
}
@@ -3697,62 +4831,170 @@ class Compiler
/**
* Sorts keyword arguments
*
- * @param array $prototype
- * @param array $args
+ * @param string $functionName
+ * @param array $prototypes
+ * @param array $args
*
* @return array
*/
- protected function sortArgs($prototype, $args)
+ protected function sortNativeFunctionArgs($functionName, $prototypes, $args)
{
- $keyArgs = [];
- $posArgs = [];
+ static $parser = null;
- // separate positional and keyword arguments
- foreach ($args as $arg) {
- list($key, $value) = $arg;
+ if (! isset($prototypes)) {
+ $keyArgs = [];
+ $posArgs = [];
- $key = $key[1];
+ // separate positional and keyword arguments
+ foreach ($args as $arg) {
+ list($key, $value) = $arg;
- if (empty($key)) {
- $posArgs[] = empty($arg[2]) ? $value : $arg;
- } else {
- $keyArgs[$key] = $value;
+ $key = $key[1];
+
+ if (empty($key)) {
+ $posArgs[] = empty($arg[2]) ? $value : $arg;
+ } else {
+ $keyArgs[$key] = $value;
+ }
}
- }
- if (! isset($prototype)) {
return [$posArgs, $keyArgs];
}
- // copy positional args
- $finalArgs = array_pad($posArgs, count($prototype), null);
+ // specific cases ?
+ if (in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) {
+ // notation 100 127 255 / 0 is in fact a simple list of 4 values
+ foreach ($args as $k => $arg) {
+ if ($arg[1][0] === Type::T_LIST && count($arg[1][2]) === 3) {
+ $last = end($arg[1][2]);
- // overwrite positional args with keyword args
- foreach ($prototype as $i => $names) {
- foreach ((array) $names as $name) {
- if (isset($keyArgs[$name])) {
- $finalArgs[$i] = $keyArgs[$name];
+ if ($last[0] === Type::T_EXPRESSION && $last[1] === '/') {
+ array_pop($arg[1][2]);
+ $arg[1][2][] = $last[2];
+ $arg[1][2][] = $last[3];
+ $args[$k] = $arg;
+ }
}
}
}
+ $finalArgs = [];
+
+ if (! is_array(reset($prototypes))) {
+ $prototypes = [$prototypes];
+ }
+
+ $keyArgs = [];
+
+ // trying each prototypes
+ $prototypeHasMatch = false;
+ $exceptionMessage = '';
+
+ foreach ($prototypes as $prototype) {
+ $argDef = [];
+
+ foreach ($prototype as $i => $p) {
+ $default = null;
+ $p = explode(':', $p, 2);
+ $name = array_shift($p);
+
+ if (count($p)) {
+ $p = trim(reset($p));
+
+ if ($p === 'null') {
+ // differentiate this null from the static::$null
+ $default = [Type::T_KEYWORD, 'null'];
+ } else {
+ if (is_null($parser)) {
+ $parser = $this->parserFactory(__METHOD__);
+ }
+
+ $parser->parseValue($p, $default);
+ }
+ }
+
+ $isVariable = false;
+
+ if (substr($name, -3) === '...') {
+ $isVariable = true;
+ $name = substr($name, 0, -3);
+ }
+
+ $argDef[] = [$name, $default, $isVariable];
+ }
+
+ try {
+ $vars = $this->applyArguments($argDef, $args, false, false);
+
+ // ensure all args are populated
+ foreach ($prototype as $i => $p) {
+ $name = explode(':', $p)[0];
+
+ if (! isset($finalArgs[$i])) {
+ $finalArgs[$i] = null;
+ }
+ }
+
+ // apply positional args
+ foreach (array_values($vars) as $i => $val) {
+ $finalArgs[$i] = $val;
+ }
+
+ $keyArgs = array_merge($keyArgs, $vars);
+ $prototypeHasMatch = true;
+
+ // overwrite positional args with keyword args
+ foreach ($prototype as $i => $p) {
+ $name = explode(':', $p)[0];
+
+ if (isset($keyArgs[$name])) {
+ $finalArgs[$i] = $keyArgs[$name];
+ }
+
+ // special null value as default: translate to real null here
+ if ($finalArgs[$i] === [Type::T_KEYWORD, 'null']) {
+ $finalArgs[$i] = null;
+ }
+ }
+ // should we break if this prototype seems fulfilled?
+ } catch (CompilerException $e) {
+ $exceptionMessage = $e->getMessage();
+ }
+ }
+
+ if ($exceptionMessage && ! $prototypeHasMatch) {
+ $this->throwError($exceptionMessage);
+ }
+
return [$finalArgs, $keyArgs];
}
/**
* Apply argument values per definition
*
- * @param array $argDef
- * @param array $argValues
+ * @param array $argDef
+ * @param array $argValues
+ * @param boolean $storeInEnv
+ * @param boolean $reduce
+ * only used if $storeInEnv = false
+ *
+ * @return array
*
* @throws \Exception
*/
- protected function applyArguments($argDef, $argValues)
+ protected function applyArguments($argDef, $argValues, $storeInEnv = true, $reduce = true)
{
- $storeEnv = $this->getStoreEnv();
+ $output = [];
+ if (is_array($argValues) && count($argValues) && end($argValues) === static::$null) {
+ array_pop($argValues);
+ }
- $env = new Environment;
- $env->store = $storeEnv->store;
+ if ($storeInEnv) {
+ $storeEnv = $this->getStoreEnv();
+
+ $env = new Environment;
+ $env->store = $storeEnv->store;
+ }
$hasVariable = false;
$args = [];
@@ -3764,37 +5006,64 @@ class Compiler
$hasVariable |= $isVariable;
}
- $keywordArgs = [];
+ $splatSeparator = null;
+ $keywordArgs = [];
$deferredKeywordArgs = [];
- $remaining = [];
+ $remaining = [];
+ $hasKeywordArgument = false;
// assign the keyword args
foreach ((array) $argValues as $arg) {
if (! empty($arg[0])) {
- if (! isset($args[$arg[0][1]])) {
+ $hasKeywordArgument = true;
+
+ $name = $arg[0][1];
+ if (! isset($args[$name])) {
+ foreach (array_keys($args) as $an) {
+ if (str_replace("_", "-", $an) === str_replace("_", "-", $name)) {
+ $name = $an;
+ break;
+ }
+ }
+ }
+ if (! isset($args[$name]) || $args[$name][3]) {
if ($hasVariable) {
- $deferredKeywordArgs[$arg[0][1]] = $arg[1];
+ $deferredKeywordArgs[$name] = $arg[1];
} else {
$this->throwError("Mixin or function doesn't have an argument named $%s.", $arg[0][1]);
break;
}
- } elseif ($args[$arg[0][1]][0] < count($remaining)) {
+ } elseif ($args[$name][0] < count($remaining)) {
$this->throwError("The argument $%s was passed both by position and by name.", $arg[0][1]);
break;
} else {
- $keywordArgs[$arg[0][1]] = $arg[1];
+ $keywordArgs[$name] = $arg[1];
}
- } elseif (count($keywordArgs)) {
- $this->throwError('Positional arguments must come before keyword arguments.');
- break;
} elseif ($arg[2] === true) {
$val = $this->reduce($arg[1], true);
if ($val[0] === Type::T_LIST) {
foreach ($val[2] as $name => $item) {
if (! is_numeric($name)) {
- $keywordArgs[$name] = $item;
+ if (! isset($args[$name])) {
+ foreach (array_keys($args) as $an) {
+ if (str_replace("_", "-", $an) === str_replace("_", "-", $name)) {
+ $name = $an;
+ break;
+ }
+ }
+ }
+
+ if ($hasVariable) {
+ $deferredKeywordArgs[$name] = $item;
+ } else {
+ $keywordArgs[$name] = $item;
+ }
} else {
+ if (is_null($splatSeparator)) {
+ $splatSeparator = $val[1];
+ }
+
$remaining[] = $item;
}
}
@@ -3804,14 +5073,34 @@ class Compiler
$item = $val[2][$i];
if (! is_numeric($name)) {
- $keywordArgs[$name] = $item;
+ if (! isset($args[$name])) {
+ foreach (array_keys($args) as $an) {
+ if (str_replace("_", "-", $an) === str_replace("_", "-", $name)) {
+ $name = $an;
+ break;
+ }
+ }
+ }
+
+ if ($hasVariable) {
+ $deferredKeywordArgs[$name] = $item;
+ } else {
+ $keywordArgs[$name] = $item;
+ }
} else {
+ if (is_null($splatSeparator)) {
+ $splatSeparator = $val[1];
+ }
+
$remaining[] = $item;
}
}
} else {
$remaining[] = $val;
}
+ } elseif ($hasKeywordArgument) {
+ $this->throwError('Positional arguments must come before keyword arguments.');
+ break;
} else {
$remaining[] = $arg[1];
}
@@ -3821,7 +5110,7 @@ class Compiler
list($i, $name, $default, $isVariable) = $arg;
if ($isVariable) {
- $val = [Type::T_LIST, ',', [], $isVariable];
+ $val = [Type::T_LIST, is_null($splatSeparator) ? ',' : $splatSeparator , [], $isVariable];
for ($count = count($remaining); $i < $count; $i++) {
$val[2][] = $remaining[$i];
@@ -3841,10 +5130,16 @@ class Compiler
break;
}
- $this->set($name, $this->reduce($val, true), true, $env);
+ if ($storeInEnv) {
+ $this->set($name, $this->reduce($val, true), true, $env);
+ } else {
+ $output[$name] = ($reduce ? $this->reduce($val, true) : $val);
+ }
}
- $storeEnv->store = $env->store;
+ if ($storeInEnv) {
+ $storeEnv->store = $env->store;
+ }
foreach ($args as $arg) {
list($i, $name, $default, $isVariable) = $arg;
@@ -3853,8 +5148,14 @@ class Compiler
continue;
}
- $this->set($name, $this->reduce($default, true), true);
+ if ($storeInEnv) {
+ $this->set($name, $this->reduce($default, true), true);
+ } else {
+ $output[$name] = ($reduce ? $this->reduce($default, true) : $default);
+ }
}
+
+ return $output;
}
/**
@@ -3862,9 +5163,9 @@ class Compiler
*
* @param mixed $value
*
- * @return array|\Leafo\ScssPhp\Node\Number
+ * @return array|\ScssPhp\ScssPhp\Node\Number
*/
- private function coerceValue($value)
+ protected function coerceValue($value)
{
if (is_array($value) || $value instanceof \ArrayAccess) {
return $value;
@@ -3874,7 +5175,7 @@ class Compiler
return $this->toBool($value);
}
- if ($value === null) {
+ if (is_null($value)) {
return static::$null;
}
@@ -3886,30 +5187,14 @@ class Compiler
return static::$emptyString;
}
- if (preg_match('/^(#([0-9a-f]{6})|#([0-9a-f]{3}))$/i', $value, $m)) {
- $color = [Type::T_COLOR];
-
- if (isset($m[3])) {
- $num = hexdec($m[3]);
-
- foreach ([3, 2, 1] as $i) {
- $t = $num & 0xf;
- $color[$i] = $t << 4 | $t;
- $num >>= 4;
- }
- } else {
- $num = hexdec($m[2]);
-
- foreach ([3, 2, 1] as $i) {
- $color[$i] = $num & 0xff;
- $num >>= 8;
- }
- }
+ $value = [Type::T_KEYWORD, $value];
+ $color = $this->coerceColor($value);
+ if ($color) {
return $color;
}
- return [Type::T_KEYWORD, $value];
+ return $value;
}
/**
@@ -3925,7 +5210,9 @@ class Compiler
return $item;
}
- if ($item === static::$emptyList) {
+ if ($item[0] === static::$emptyList[0]
+ && $item[1] === static::$emptyList[1]
+ && $item[2] === static::$emptyList[2]) {
return static::$emptyMap;
}
@@ -3955,10 +5242,21 @@ class Compiler
$key = $keys[$i];
$value = $values[$i];
+ switch ($key[0]) {
+ case Type::T_LIST:
+ case Type::T_MAP:
+ case Type::T_STRING:
+ break;
+
+ default:
+ $key = [Type::T_KEYWORD, $this->compileStringContent($this->coerceString($key))];
+ break;
+ }
+
$list[] = [
Type::T_LIST,
'',
- [[Type::T_KEYWORD, $this->compileStringContent($this->coerceString($key))], $value]
+ [$key, $value]
];
}
@@ -3991,21 +5289,106 @@ class Compiler
*
* @return array|null
*/
- protected function coerceColor($value)
+ protected function coerceColor($value, $inRGBFunction = false)
{
switch ($value[0]) {
case Type::T_COLOR:
+ for ($i = 1; $i <= 3; $i++) {
+ if (! is_numeric($value[$i])) {
+ $cv = $this->compileRGBAValue($value[$i]);
+
+ if (! is_numeric($cv)) {
+ return null;
+ }
+
+ $value[$i] = $cv;
+ }
+
+ if (isset($value[4])) {
+ if (! is_numeric($value[4])) {
+ $cv = $this->compileRGBAValue($value[4], true);
+
+ if (! is_numeric($cv)) {
+ return null;
+ }
+
+ $value[4] = $cv;
+ }
+ }
+ }
+
return $value;
+ case Type::T_LIST:
+ if ($inRGBFunction) {
+ if (count($value[2]) == 3 || count($value[2]) == 4) {
+ $color = $value[2];
+ array_unshift($color, Type::T_COLOR);
+
+ return $this->coerceColor($color);
+ }
+ }
+
+ return null;
+
case Type::T_KEYWORD:
+ if (! is_string($value[1])) {
+ return null;
+ }
+
$name = strtolower($value[1]);
+ // hexa color?
+ if (preg_match('/^#([0-9a-f]+)$/i', $name, $m)) {
+ $nofValues = strlen($m[1]);
- if (isset(Colors::$cssColors[$name])) {
- $rgba = explode(',', Colors::$cssColors[$name]);
+ if (in_array($nofValues, [3, 4, 6, 8])) {
+ $nbChannels = 3;
+ $color = [];
+ $num = hexdec($m[1]);
+ switch ($nofValues) {
+ case 4:
+ $nbChannels = 4;
+ // then continuing with the case 3:
+ case 3:
+ for ($i = 0; $i < $nbChannels; $i++) {
+ $t = $num & 0xf;
+ array_unshift($color, $t << 4 | $t);
+ $num >>= 4;
+ }
+
+ break;
+
+ case 8:
+ $nbChannels = 4;
+ // then continuing with the case 6:
+ case 6:
+ for ($i = 0; $i < $nbChannels; $i++) {
+ array_unshift($color, $num & 0xff);
+ $num >>= 8;
+ }
+
+ break;
+ }
+
+ if ($nbChannels === 4) {
+ if ($color[3] === 255) {
+ $color[3] = 1; // fully opaque
+ } else {
+ $color[3] = round($color[3] / 255, 3);
+ }
+ }
+
+ array_unshift($color, Type::T_COLOR);
+
+ return $color;
+ }
+ }
+
+ if ($rgba = Colors::colorNameToRGBa($name)) {
return isset($rgba[3])
- ? [Type::T_COLOR, (int) $rgba[0], (int) $rgba[1], (int) $rgba[2], (int) $rgba[3]]
- : [Type::T_COLOR, (int) $rgba[0], (int) $rgba[1], (int) $rgba[2]];
+ ? [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2], $rgba[3]]
+ : [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2]];
}
return null;
@@ -4014,6 +5397,88 @@ class Compiler
return null;
}
+ /**
+ * @param integer|\ScssPhp\ScssPhp\Node\Number $value
+ * @param boolean $isAlpha
+ *
+ * @return integer|mixed
+ */
+ protected function compileRGBAValue($value, $isAlpha = false)
+ {
+ if ($isAlpha) {
+ return $this->compileColorPartValue($value, 0, 1, false);
+ }
+
+ return $this->compileColorPartValue($value, 0, 255, true);
+ }
+
+ /**
+ * @param mixed $value
+ * @param integer|float $min
+ * @param integer|float $max
+ * @param boolean $isInt
+ * @param boolean $clamp
+ * @param boolean $modulo
+ *
+ * @return integer|mixed
+ */
+ protected function compileColorPartValue($value, $min, $max, $isInt = true, $clamp = true, $modulo = false)
+ {
+ if (! is_numeric($value)) {
+ if (is_array($value)) {
+ $reduced = $this->reduce($value);
+
+ if (is_object($reduced) && $value->type === Type::T_NUMBER) {
+ $value = $reduced;
+ }
+ }
+
+ if (is_object($value) && $value->type === Type::T_NUMBER) {
+ $num = $value->dimension;
+
+ if (count($value->units)) {
+ $unit = array_keys($value->units);
+ $unit = reset($unit);
+
+ switch ($unit) {
+ case '%':
+ $num *= $max / 100;
+ break;
+ default:
+ break;
+ }
+ }
+
+ $value = $num;
+ } elseif (is_array($value)) {
+ $value = $this->compileValue($value);
+ }
+ }
+
+ if (is_numeric($value)) {
+ if ($isInt) {
+ $value = round($value);
+ }
+
+ if ($clamp) {
+ $value = min($max, max($min, $value));
+ }
+
+ if ($modulo) {
+ $value = $value % $max;
+
+ // still negative?
+ while ($value < $min) {
+ $value += $max;
+ }
+ }
+
+ return $value;
+ }
+
+ return $value;
+ }
+
/**
* Coerce value to string
*
@@ -4066,7 +5531,7 @@ class Compiler
$value = $this->coerceMap($value);
if ($value[0] !== Type::T_MAP) {
- $this->throwError('expecting map');
+ $this->throwError('expecting map, %s received', $value[0]);
}
return $value;
@@ -4086,7 +5551,7 @@ class Compiler
public function assertList($value)
{
if ($value[0] !== Type::T_LIST) {
- $this->throwError('expecting list');
+ $this->throwError('expecting list, %s received', $value[0]);
}
return $value;
@@ -4109,7 +5574,7 @@ class Compiler
return $color;
}
- $this->throwError('expecting color');
+ $this->throwError('expecting color, %s received', $value[0]);
}
/**
@@ -4126,7 +5591,7 @@ class Compiler
public function assertNumber($value)
{
if ($value[0] !== Type::T_NUMBER) {
- $this->throwError('expecting number');
+ $this->throwError('expecting number, %s received', $value[0]);
}
return $value[1];
@@ -4203,7 +5668,7 @@ class Compiler
*
* @return float
*/
- private function hueToRGB($m1, $m2, $h)
+ protected function hueToRGB($m1, $m2, $h)
{
if ($h < 0) {
$h += 1;
@@ -4261,46 +5726,27 @@ class Compiler
// Built in functions
- //protected static $libCall = ['name', 'args...'];
+ protected static $libCall = ['name', 'args...'];
protected function libCall($args, $kwargs)
{
$name = $this->compileStringContent($this->coerceString($this->reduce(array_shift($args), true)));
+ $callArgs = [];
- $posArgs = [];
-
- foreach ($args as $arg) {
- if (empty($arg[0])) {
- if ($arg[2] === true) {
- $tmp = $this->reduce($arg[1]);
-
- if ($tmp[0] === Type::T_LIST) {
- foreach ($tmp[2] as $item) {
- $posArgs[] = [null, $item, false];
- }
- } else {
- $posArgs[] = [null, $tmp, true];
- }
-
- continue;
- }
-
- $posArgs[] = [null, $this->reduce($arg), false];
- continue;
+ // $kwargs['args'] is [Type::T_LIST, ',', [..]]
+ foreach ($kwargs['args'][2] as $varname => $arg) {
+ if (is_numeric($varname)) {
+ $varname = null;
+ } else {
+ $varname = [ 'var', $varname];
}
- $posArgs[] = [null, $arg, false];
+ $callArgs[] = [$varname, $arg, false];
}
- if (count($kwargs)) {
- foreach ($kwargs as $key => $value) {
- $posArgs[] = [[Type::T_VARIABLE, $key], $value, false];
- }
- }
-
- return $this->reduce([Type::T_FUNCTION_CALL, $name, $posArgs]);
+ return $this->reduce([Type::T_FUNCTION_CALL, $name, $callArgs]);
}
- protected static $libIf = ['condition', 'if-true', 'if-false'];
+ protected static $libIf = ['condition', 'if-true', 'if-false:'];
protected function libIf($args)
{
list($cond, $t, $f) = $args;
@@ -4344,30 +5790,68 @@ class Compiler
return false === $key ? static::$null : $key + 1;
}
- protected static $libRgb = ['red', 'green', 'blue'];
- protected function libRgb($args)
+ protected static $libRgb = [
+ ['color'],
+ ['color', 'alpha'],
+ ['channels'],
+ ['red', 'green', 'blue'],
+ ['red', 'green', 'blue', 'alpha'] ];
+ protected function libRgb($args, $kwargs, $funcName = 'rgb')
{
- list($r, $g, $b) = $args;
+ switch (count($args)) {
+ case 1:
+ if (! $color = $this->coerceColor($args[0], true)) {
+ $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+ }
+ break;
- return [Type::T_COLOR, $r[1], $g[1], $b[1]];
+ case 3:
+ $color = [Type::T_COLOR, $args[0], $args[1], $args[2]];
+
+ if (! $color = $this->coerceColor($color)) {
+ $color = [Type::T_STRING, '', [$funcName .'(', $args[0], ', ', $args[1], ', ', $args[2], ')']];
+ }
+
+ return $color;
+
+ case 2:
+ if ($color = $this->coerceColor($args[0], true)) {
+ $alpha = $this->compileRGBAValue($args[1], true);
+
+ if (is_numeric($alpha)) {
+ $color[4] = $alpha;
+ } else {
+ $color = [Type::T_STRING, '',
+ [$funcName . '(', $color[1], ', ', $color[2], ', ', $color[3], ', ', $alpha, ')']];
+ }
+ } else {
+ $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+ }
+ break;
+
+ case 4:
+ default:
+ $color = [Type::T_COLOR, $args[0], $args[1], $args[2], $args[3]];
+
+ if (! $color = $this->coerceColor($color)) {
+ $color = [Type::T_STRING, '',
+ [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']];
+ }
+ break;
+ }
+
+ return $color;
}
protected static $libRgba = [
- ['red', 'color'],
- 'green', 'blue', 'alpha'];
- protected function libRgba($args)
+ ['color'],
+ ['color', 'alpha'],
+ ['channels'],
+ ['red', 'green', 'blue'],
+ ['red', 'green', 'blue', 'alpha'] ];
+ protected function libRgba($args, $kwargs)
{
- if ($color = $this->coerceColor($args[0])) {
- $num = isset($args[3]) ? $args[3] : $args[1];
- $alpha = $this->assertNumber($num);
- $color[4] = $alpha;
-
- return $color;
- }
-
- list($r, $g, $b, $a) = $args;
-
- return [Type::T_COLOR, $r[1], $g[1], $b[1], $a[1]];
+ return $this->libRgb($args, $kwargs, 'rgba');
}
// helper function for adjust_color, change_color, and scale_color
@@ -4375,21 +5859,25 @@ class Compiler
{
$color = $this->assertColor($args[0]);
- foreach ([1, 2, 3, 7] as $i) {
- if (isset($args[$i])) {
- $val = $this->assertNumber($args[$i]);
- $ii = $i === 7 ? 4 : $i; // alpha
- $color[$ii] = call_user_func($fn, isset($color[$ii]) ? $color[$ii] : 0, $val, $i);
+ foreach ([1 => 1, 2 => 2, 3 => 3, 7 => 4] as $iarg => $irgba) {
+ if (isset($args[$iarg])) {
+ $val = $this->assertNumber($args[$iarg]);
+
+ if (! isset($color[$irgba])) {
+ $color[$irgba] = (($irgba < 4) ? 0 : 1);
+ }
+
+ $color[$irgba] = call_user_func($fn, $color[$irgba], $val, $iarg);
}
}
- if (isset($args[4]) || isset($args[5]) || isset($args[6])) {
+ if (! empty($args[4]) || ! empty($args[5]) || ! empty($args[6])) {
$hsl = $this->toHSL($color[1], $color[2], $color[3]);
- foreach ([4, 5, 6] as $i) {
- if (isset($args[$i])) {
- $val = $this->assertNumber($args[$i]);
- $hsl[$i - 3] = call_user_func($fn, $hsl[$i - 3], $val, $i);
+ foreach ([4 => 1, 5 => 2, 6 => 3] as $iarg => $ihsl) {
+ if (! empty($args[$iarg])) {
+ $val = $this->assertNumber($args[$iarg]);
+ $hsl[$ihsl] = call_user_func($fn, $hsl[$ihsl], $val, $iarg);
}
}
@@ -4406,8 +5894,8 @@ class Compiler
}
protected static $libAdjustColor = [
- 'color', 'red', 'green', 'blue',
- 'hue', 'saturation', 'lightness', 'alpha'
+ 'color', 'red:null', 'green:null', 'blue:null',
+ 'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
];
protected function libAdjustColor($args)
{
@@ -4417,8 +5905,8 @@ class Compiler
}
protected static $libChangeColor = [
- 'color', 'red', 'green', 'blue',
- 'hue', 'saturation', 'lightness', 'alpha'
+ 'color', 'red:null', 'green:null', 'blue:null',
+ 'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
];
protected function libChangeColor($args)
{
@@ -4428,8 +5916,8 @@ class Compiler
}
protected static $libScaleColor = [
- 'color', 'red', 'green', 'blue',
- 'hue', 'saturation', 'lightness', 'alpha'
+ 'color', 'red:null', 'green:null', 'blue:null',
+ 'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
];
protected function libScaleColor($args)
{
@@ -4472,7 +5960,7 @@ class Compiler
$color = $this->coerceColor($args[0]);
$color[4] = isset($color[4]) ? round(255 * $color[4]) : 255;
- return sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3]);
+ return [Type::T_STRING, '', [sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3])]];
}
protected static $libRed = ['color'];
@@ -4523,7 +6011,7 @@ class Compiler
}
// mix two colors
- protected static $libMix = ['color-1', 'color-2', 'weight'];
+ protected static $libMix = ['color-1', 'color-2', 'weight:0.5'];
protected function libMix($args)
{
list($first, $second, $weight) = $args;
@@ -4559,25 +6047,56 @@ class Compiler
return $this->fixColor($new);
}
- protected static $libHsl = ['hue', 'saturation', 'lightness'];
- protected function libHsl($args)
+ protected static $libHsl =[
+ ['channels'],
+ ['hue', 'saturation', 'lightness'],
+ ['hue', 'saturation', 'lightness', 'alpha'] ];
+ protected function libHsl($args, $kwargs, $funcName = 'hsl')
{
- list($h, $s, $l) = $args;
+ if (count($args) == 1) {
+ if ($args[0][0] !== Type::T_LIST || count($args[0][2]) < 3 || count($args[0][2]) > 4) {
+ return [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+ }
- return $this->toRGB($h[1], $s[1], $l[1]);
- }
+ $args = $args[0][2];
+ }
- protected static $libHsla = ['hue', 'saturation', 'lightness', 'alpha'];
- protected function libHsla($args)
- {
- list($h, $s, $l, $a) = $args;
+ $hue = $this->compileColorPartValue($args[0], 0, 360, false, false, true);
+ $saturation = $this->compileColorPartValue($args[1], 0, 100, false);
+ $lightness = $this->compileColorPartValue($args[2], 0, 100, false);
- $color = $this->toRGB($h[1], $s[1], $l[1]);
- $color[4] = $a[1];
+ $alpha = null;
+
+ if (count($args) === 4) {
+ $alpha = $this->compileColorPartValue($args[3], 0, 100, false);
+
+ if (! is_numeric($hue) || ! is_numeric($saturation) || ! is_numeric($lightness) || ! is_numeric($alpha)) {
+ return [Type::T_STRING, '',
+ [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']];
+ }
+ } else {
+ if (! is_numeric($hue) || ! is_numeric($saturation) || ! is_numeric($lightness)) {
+ return [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']];
+ }
+ }
+
+ $color = $this->toRGB($hue, $saturation, $lightness);
+
+ if (! is_null($alpha)) {
+ $color[4] = $alpha;
+ }
return $color;
}
+ protected static $libHsla = [
+ ['channels'],
+ ['hue', 'saturation', 'lightness', 'alpha:1'] ];
+ protected function libHsla($args, $kwargs)
+ {
+ return $this->libHsl($args, $kwargs, 'hsla');
+ }
+
protected static $libHue = ['color'];
protected function libHue($args)
{
@@ -4645,7 +6164,7 @@ class Compiler
return $this->adjustHsl($color, 3, -$amount);
}
- protected static $libSaturate = ['color', 'amount'];
+ protected static $libSaturate = [['color', 'amount'], ['number']];
protected function libSaturate($args)
{
$value = $args[0];
@@ -4687,21 +6206,32 @@ class Compiler
return $this->adjustHsl($this->assertColor($args[0]), 1, 180);
}
- protected static $libInvert = ['color'];
+ protected static $libInvert = ['color', 'weight:1'];
protected function libInvert($args)
{
- $value = $args[0];
+ list($value, $weight) = $args;
+
+ if (! isset($weight)) {
+ $weight = 1;
+ } else {
+ $weight = $this->coercePercent($weight);
+ }
if ($value[0] === Type::T_NUMBER) {
return null;
}
$color = $this->assertColor($value);
- $color[1] = 255 - $color[1];
- $color[2] = 255 - $color[2];
- $color[3] = 255 - $color[3];
+ $inverted = $color;
+ $inverted[1] = 255 - $inverted[1];
+ $inverted[2] = 255 - $inverted[2];
+ $inverted[3] = 255 - $inverted[3];
- return $color;
+ if ($weight < 1) {
+ return $this->libMix([$inverted, $color, [Type::T_NUMBER, $weight]]);
+ }
+
+ return $inverted;
}
// increases opacity by amount
@@ -4810,7 +6340,7 @@ class Compiler
$min = null;
foreach ($numbers as $key => $number) {
- if (null === $min || $number[1] <= $min[1]) {
+ if (is_null($min) || $number[1] <= $min[1]) {
$min = [$key, $number[1]];
}
}
@@ -4824,7 +6354,7 @@ class Compiler
$max = null;
foreach ($numbers as $key => $number) {
- if (null === $max || $number[1] >= $max[1]) {
+ if (is_null($max) || $number[1] >= $max[1]) {
$max = [$key, $number[1]];
}
}
@@ -4841,9 +6371,9 @@ class Compiler
*/
protected function getNormalizedNumbers($args)
{
- $unit = null;
+ $unit = null;
$originalUnit = null;
- $numbers = [];
+ $numbers = [];
foreach ($args as $key => $item) {
if ($item[0] !== Type::T_NUMBER) {
@@ -4853,7 +6383,7 @@ class Compiler
$number = $item->normalize();
- if (null === $unit) {
+ if (is_null($unit)) {
$unit = $number[2];
$originalUnit = $item->unitStr();
} elseif ($number[1] && $unit !== $number[2]) {
@@ -4925,7 +6455,7 @@ class Compiler
if (! isset($list[2][$n])) {
$this->throwError('Invalid argument for "n"');
- return;
+ return null;
}
$list[2][$n] = $args[2];
@@ -4937,11 +6467,15 @@ class Compiler
protected function libMapGet($args)
{
$map = $this->assertMap($args[0]);
- $key = $this->compileStringContent($this->coerceString($args[1]));
+ $key = $args[1];
- for ($i = count($map[1]) - 1; $i >= 0; $i--) {
- if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
- return $map[2][$i];
+ if (! is_null($key)) {
+ $key = $this->compileStringContent($this->coerceString($key));
+
+ for ($i = count($map[1]) - 1; $i >= 0; $i--) {
+ if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
+ return $map[2][$i];
+ }
}
}
@@ -5036,6 +6570,18 @@ class Compiler
return [Type::T_MAP, $keys, $values];
}
+ protected static $libIsBracketed = ['list'];
+ protected function libIsBracketed($args)
+ {
+ $list = $args[0];
+ $this->coerceList($list, ' ');
+ if (! empty($list['enclosing']) && $list['enclosing'] === 'bracket') {
+ return true;
+ }
+ return false;
+ }
+
+
protected function listSeparatorForJoin($list1, $sep)
{
if (! isset($sep)) {
@@ -5047,26 +6593,56 @@ class Compiler
return ',';
case 'space':
- return '';
+ return ' ';
default:
return $list1[1];
}
}
- protected static $libJoin = ['list1', 'list2', 'separator'];
+ protected static $libJoin = ['list1', 'list2', 'separator:null', 'bracketed:auto'];
protected function libJoin($args)
{
- list($list1, $list2, $sep) = $args;
+ list($list1, $list2, $sep, $bracketed) = $args;
$list1 = $this->coerceList($list1, ' ');
$list2 = $this->coerceList($list2, ' ');
- $sep = $this->listSeparatorForJoin($list1, $sep);
+ $sep = $this->listSeparatorForJoin($list1, $sep);
- return [Type::T_LIST, $sep, array_merge($list1[2], $list2[2])];
+ if ($bracketed === static::$true) {
+ $bracketed = true;
+ } elseif ($bracketed === static::$false) {
+ $bracketed = false;
+ } elseif ($bracketed === [Type::T_KEYWORD, 'auto']) {
+ $bracketed = 'auto';
+ } elseif ($bracketed === static::$null) {
+ $bracketed = false;
+ } else {
+ $bracketed = $this->compileValue($bracketed);
+ $bracketed = ! ! $bracketed;
+ if ($bracketed === true) {
+ $bracketed = true;
+ }
+ }
+
+ if ($bracketed === 'auto') {
+ $bracketed = false;
+ if (! empty($list1['enclosing']) && $list1['enclosing'] === 'bracket') {
+ $bracketed = true;
+ }
+ }
+
+ $res = [Type::T_LIST, $sep, array_merge($list1[2], $list2[2])];
+ if (isset($list1['enclosing'])) {
+ $res['enlcosing'] = $list1['enclosing'];
+ }
+ if ($bracketed) {
+ $res['enclosing'] = 'bracket';
+ }
+ return $res;
}
- protected static $libAppend = ['list', 'val', 'separator'];
+ protected static $libAppend = ['list', 'val', 'separator:null'];
protected function libAppend($args)
{
list($list1, $value, $sep) = $args;
@@ -5074,13 +6650,17 @@ class Compiler
$list1 = $this->coerceList($list1, ' ');
$sep = $this->listSeparatorForJoin($list1, $sep);
- return [Type::T_LIST, $sep, array_merge($list1[2], [$value])];
+ $res = [Type::T_LIST, $sep, array_merge($list1[2], [$value])];
+ if (isset($list1['enclosing'])) {
+ $res['enclosing'] = $list1['enclosing'];
+ }
+ return $res;
}
protected function libZip($args)
{
- foreach ($args as $arg) {
- $this->assertList($arg);
+ foreach ($args as $key => $arg) {
+ $args[$key] = $this->coerceList($arg);
}
$lists = [];
@@ -5163,7 +6743,7 @@ class Compiler
) {
$this->throwError('Invalid argument(s) for "comparable"');
- return;
+ return null;
}
$number1 = $number1->normalize();
@@ -5211,10 +6791,10 @@ class Compiler
return new Node\Number(strlen($stringContent), '');
}
- protected static $libStrSlice = ['string', 'start-at', 'end-at'];
+ protected static $libStrSlice = ['string', 'start-at', 'end-at:-1'];
protected function libStrSlice($args)
{
- if (isset($args[2]) && $args[2][1] == 0) {
+ if (isset($args[2]) && ! $args[2][1]) {
return static::$nullString;
}
@@ -5227,7 +6807,7 @@ class Compiler
$start--;
}
- $end = (int) $args[2][1];
+ $end = isset($args[2]) ? (int) $args[2][1] : -1;
$length = $end < 0 ? $end + 1 : ($end > 0 ? $end - $start : $end);
$string[2] = $length
@@ -5343,7 +6923,7 @@ class Compiler
if ($n < 1) {
$this->throwError("limit must be greater than or equal to 1");
- return;
+ return null;
}
return new Node\Number(mt_rand(1, $n), '');
@@ -5365,13 +6945,670 @@ class Compiler
return [Type::T_STRING, '', ['u' . str_pad(base_convert($id, 10, 36), 8, '0', STR_PAD_LEFT)]];
}
+ protected function inspectFormatValue($value, $force_enclosing_display = false)
+ {
+ if ($value === static::$null) {
+ $value = [Type::T_KEYWORD, 'null'];
+ }
+ $stringValue = [$value];
+ if ($value[0] === Type::T_LIST) {
+ if (end($value[2]) === static::$null) {
+ array_pop($value[2]);
+ $value[2][] = [Type::T_STRING, '', ['']];
+ $force_enclosing_display = true;
+ }
+ if (! empty($value['enclosing'])) {
+ if ($force_enclosing_display
+ || ($value['enclosing'] === 'bracket' )
+ || !count($value[2])) {
+ $value['enclosing'] = 'forced_'.$value['enclosing'];
+ $force_enclosing_display = true;
+ }
+ }
+ foreach ($value[2] as $k => $listelement) {
+ $value[2][$k] = $this->inspectFormatValue($listelement, $force_enclosing_display);
+ }
+ $stringValue = [$value];
+ }
+
+ return [Type::T_STRING, '', $stringValue];
+ }
+
protected static $libInspect = ['value'];
protected function libInspect($args)
{
- if ($args[0] === static::$null) {
- return [Type::T_KEYWORD, 'null'];
+ $value = $args[0];
+ return $this->inspectFormatValue($value);
+ }
+
+ /**
+ * Preprocess selector args
+ *
+ * @param array $arg
+ *
+ * @return array|boolean
+ */
+ protected function getSelectorArg($arg)
+ {
+ static $parser = null;
+
+ if (is_null($parser)) {
+ $parser = $this->parserFactory(__METHOD__);
}
- return $args[0];
+ $arg = $this->libUnquote([$arg]);
+ $arg = $this->compileValue($arg);
+
+ $parsedSelector = [];
+
+ if ($parser->parseSelector($arg, $parsedSelector)) {
+ $selector = $this->evalSelectors($parsedSelector);
+ $gluedSelector = $this->glueFunctionSelectors($selector);
+
+ return $gluedSelector;
+ }
+
+ return false;
+ }
+
+ /**
+ * Postprocess selector to output in right format
+ *
+ * @param array $selectors
+ *
+ * @return string
+ */
+ protected function formatOutputSelector($selectors)
+ {
+ $selectors = $this->collapseSelectors($selectors, true);
+
+ return $selectors;
+ }
+
+ protected static $libIsSuperselector = ['super', 'sub'];
+ protected function libIsSuperselector($args)
+ {
+ list($super, $sub) = $args;
+
+ $super = $this->getSelectorArg($super);
+ $sub = $this->getSelectorArg($sub);
+
+ return $this->isSuperSelector($super, $sub);
+ }
+
+ /**
+ * Test a $super selector again $sub
+ *
+ * @param array $super
+ * @param array $sub
+ *
+ * @return boolean
+ */
+ protected function isSuperSelector($super, $sub)
+ {
+ // one and only one selector for each arg
+ if (! $super || count($super) !== 1) {
+ $this->throwError("Invalid super selector for isSuperSelector()");
+ }
+
+ if (! $sub || count($sub) !== 1) {
+ $this->throwError("Invalid sub selector for isSuperSelector()");
+ }
+
+ $super = reset($super);
+ $sub = reset($sub);
+
+ $i = 0;
+ $nextMustMatch = false;
+
+ foreach ($super as $node) {
+ $compound = '';
+
+ array_walk_recursive(
+ $node,
+ function ($value, $key) use (&$compound) {
+ $compound .= $value;
+ }
+ );
+
+ if ($this->isImmediateRelationshipCombinator($compound)) {
+ if ($node !== $sub[$i]) {
+ return false;
+ }
+
+ $nextMustMatch = true;
+ $i++;
+ } else {
+ while ($i < count($sub) && ! $this->isSuperPart($node, $sub[$i])) {
+ if ($nextMustMatch) {
+ return false;
+ }
+
+ $i++;
+ }
+
+ if ($i >= count($sub)) {
+ return false;
+ }
+
+ $nextMustMatch = false;
+ $i++;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Test a part of super selector again a part of sub selector
+ *
+ * @param array $superParts
+ * @param array $subParts
+ *
+ * @return boolean
+ */
+ protected function isSuperPart($superParts, $subParts)
+ {
+ $i = 0;
+
+ foreach ($superParts as $superPart) {
+ while ($i < count($subParts) && $subParts[$i] !== $superPart) {
+ $i++;
+ }
+
+ if ($i >= count($subParts)) {
+ return false;
+ }
+
+ $i++;
+ }
+
+ return true;
+ }
+
+ protected static $libSelectorAppend = ['selector...'];
+ protected function libSelectorAppend($args)
+ {
+ // get the selector... list
+ $args = reset($args);
+ $args = $args[2];
+
+ if (count($args) < 1) {
+ $this->throwError("selector-append() needs at least 1 argument");
+ }
+
+ $selectors = array_map([$this, 'getSelectorArg'], $args);
+
+ return $this->formatOutputSelector($this->selectorAppend($selectors));
+ }
+
+ /**
+ * Append parts of the last selector in the list to the previous, recursively
+ *
+ * @param array $selectors
+ *
+ * @return array
+ *
+ * @throws \ScssPhp\ScssPhp\Exception\CompilerException
+ */
+ protected function selectorAppend($selectors)
+ {
+ $lastSelectors = array_pop($selectors);
+
+ if (! $lastSelectors) {
+ $this->throwError("Invalid selector list in selector-append()");
+ }
+
+ while (count($selectors)) {
+ $previousSelectors = array_pop($selectors);
+
+ if (! $previousSelectors) {
+ $this->throwError("Invalid selector list in selector-append()");
+ }
+
+ // do the trick, happening $lastSelector to $previousSelector
+ $appended = [];
+
+ foreach ($lastSelectors as $lastSelector) {
+ $previous = $previousSelectors;
+
+ foreach ($lastSelector as $lastSelectorParts) {
+ foreach ($lastSelectorParts as $lastSelectorPart) {
+ foreach ($previous as $i => $previousSelector) {
+ foreach ($previousSelector as $j => $previousSelectorParts) {
+ $previous[$i][$j][] = $lastSelectorPart;
+ }
+ }
+ }
+ }
+
+ foreach ($previous as $ps) {
+ $appended[] = $ps;
+ }
+ }
+
+ $lastSelectors = $appended;
+ }
+
+ return $lastSelectors;
+ }
+
+ protected static $libSelectorExtend = ['selectors', 'extendee', 'extender'];
+ protected function libSelectorExtend($args)
+ {
+ list($selectors, $extendee, $extender) = $args;
+
+ $selectors = $this->getSelectorArg($selectors);
+ $extendee = $this->getSelectorArg($extendee);
+ $extender = $this->getSelectorArg($extender);
+
+ if (! $selectors || ! $extendee || ! $extender) {
+ $this->throwError("selector-extend() invalid arguments");
+ }
+
+ $extended = $this->extendOrReplaceSelectors($selectors, $extendee, $extender);
+
+ return $this->formatOutputSelector($extended);
+ }
+
+ protected static $libSelectorReplace = ['selectors', 'original', 'replacement'];
+ protected function libSelectorReplace($args)
+ {
+ list($selectors, $original, $replacement) = $args;
+
+ $selectors = $this->getSelectorArg($selectors);
+ $original = $this->getSelectorArg($original);
+ $replacement = $this->getSelectorArg($replacement);
+
+ if (! $selectors || ! $original || ! $replacement) {
+ $this->throwError("selector-replace() invalid arguments");
+ }
+
+ $replaced = $this->extendOrReplaceSelectors($selectors, $original, $replacement, true);
+
+ return $this->formatOutputSelector($replaced);
+ }
+
+ /**
+ * Extend/replace in selectors
+ * used by selector-extend and selector-replace that use the same logic
+ *
+ * @param array $selectors
+ * @param array $extendee
+ * @param array $extender
+ * @param boolean $replace
+ *
+ * @return array
+ */
+ protected function extendOrReplaceSelectors($selectors, $extendee, $extender, $replace = false)
+ {
+ $saveExtends = $this->extends;
+ $saveExtendsMap = $this->extendsMap;
+
+ $this->extends = [];
+ $this->extendsMap = [];
+
+ foreach ($extendee as $es) {
+ // only use the first one
+ $this->pushExtends(reset($es), $extender, null);
+ }
+
+ $extended = [];
+
+ foreach ($selectors as $selector) {
+ if (! $replace) {
+ $extended[] = $selector;
+ }
+
+ $n = count($extended);
+
+ $this->matchExtends($selector, $extended);
+
+ // if didnt match, keep the original selector if we are in a replace operation
+ if ($replace and count($extended) === $n) {
+ $extended[] = $selector;
+ }
+ }
+
+ $this->extends = $saveExtends;
+ $this->extendsMap = $saveExtendsMap;
+
+ return $extended;
+ }
+
+ protected static $libSelectorNest = ['selector...'];
+ protected function libSelectorNest($args)
+ {
+ // get the selector... list
+ $args = reset($args);
+ $args = $args[2];
+
+ if (count($args) < 1) {
+ $this->throwError("selector-nest() needs at least 1 argument");
+ }
+
+ $selectorsMap = array_map([$this, 'getSelectorArg'], $args);
+ $envs = [];
+
+ foreach ($selectorsMap as $selectors) {
+ $env = new Environment();
+ $env->selectors = $selectors;
+
+ $envs[] = $env;
+ }
+
+ $envs = array_reverse($envs);
+ $env = $this->extractEnv($envs);
+ $outputSelectors = $this->multiplySelectors($env);
+
+ return $this->formatOutputSelector($outputSelectors);
+ }
+
+ protected static $libSelectorParse = ['selectors'];
+ protected function libSelectorParse($args)
+ {
+ $selectors = reset($args);
+ $selectors = $this->getSelectorArg($selectors);
+
+ return $this->formatOutputSelector($selectors);
+ }
+
+ protected static $libSelectorUnify = ['selectors1', 'selectors2'];
+ protected function libSelectorUnify($args)
+ {
+ list($selectors1, $selectors2) = $args;
+
+ $selectors1 = $this->getSelectorArg($selectors1);
+ $selectors2 = $this->getSelectorArg($selectors2);
+
+ if (! $selectors1 || ! $selectors2) {
+ $this->throwError("selector-unify() invalid arguments");
+ }
+
+ // only consider the first compound of each
+ $compound1 = reset($selectors1);
+ $compound2 = reset($selectors2);
+
+ // unify them and that's it
+ $unified = $this->unifyCompoundSelectors($compound1, $compound2);
+
+ return $this->formatOutputSelector($unified);
+ }
+
+ /**
+ * The selector-unify magic as its best
+ * (at least works as expected on test cases)
+ *
+ * @param array $compound1
+ * @param array $compound2
+ *
+ * @return array|mixed
+ */
+ protected function unifyCompoundSelectors($compound1, $compound2)
+ {
+ if (! count($compound1)) {
+ return $compound2;
+ }
+
+ if (! count($compound2)) {
+ return $compound1;
+ }
+
+ // check that last part are compatible
+ $lastPart1 = array_pop($compound1);
+ $lastPart2 = array_pop($compound2);
+ $last = $this->mergeParts($lastPart1, $lastPart2);
+
+ if (! $last) {
+ return [[]];
+ }
+
+ $unifiedCompound = [$last];
+ $unifiedSelectors = [$unifiedCompound];
+
+ // do the rest
+ while (count($compound1) || count($compound2)) {
+ $part1 = end($compound1);
+ $part2 = end($compound2);
+
+ if ($part1 && ($match2 = $this->matchPartInCompound($part1, $compound2))) {
+ list($compound2, $part2, $after2) = $match2;
+
+ if ($after2) {
+ $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after2);
+ }
+
+ $c = $this->mergeParts($part1, $part2);
+ $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]);
+
+ $part1 = $part2 = null;
+
+ array_pop($compound1);
+ }
+
+ if ($part2 && ($match1 = $this->matchPartInCompound($part2, $compound1))) {
+ list($compound1, $part1, $after1) = $match1;
+
+ if ($after1) {
+ $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after1);
+ }
+
+ $c = $this->mergeParts($part2, $part1);
+ $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]);
+
+ $part1 = $part2 = null;
+
+ array_pop($compound2);
+ }
+
+ $new = [];
+
+ if ($part1 && $part2) {
+ array_pop($compound1);
+ array_pop($compound2);
+
+ $s = $this->prependSelectors($unifiedSelectors, [$part2]);
+ $new = array_merge($new, $this->prependSelectors($s, [$part1]));
+ $s = $this->prependSelectors($unifiedSelectors, [$part1]);
+ $new = array_merge($new, $this->prependSelectors($s, [$part2]));
+ } elseif ($part1) {
+ array_pop($compound1);
+
+ $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part1]));
+ } elseif ($part2) {
+ array_pop($compound2);
+
+ $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part2]));
+ }
+
+ if ($new) {
+ $unifiedSelectors = $new;
+ }
+ }
+
+ return $unifiedSelectors;
+ }
+
+ /**
+ * Prepend each selector from $selectors with $parts
+ *
+ * @param array $selectors
+ * @param array $parts
+ *
+ * @return array
+ */
+ protected function prependSelectors($selectors, $parts)
+ {
+ $new = [];
+
+ foreach ($selectors as $compoundSelector) {
+ array_unshift($compoundSelector, $parts);
+
+ $new[] = $compoundSelector;
+ }
+
+ return $new;
+ }
+
+ /**
+ * Try to find a matching part in a compound:
+ * - with same html tag name
+ * - with some class or id or something in common
+ *
+ * @param array $part
+ * @param array $compound
+ *
+ * @return array|boolean
+ */
+ protected function matchPartInCompound($part, $compound)
+ {
+ $partTag = $this->findTagName($part);
+ $before = $compound;
+ $after = [];
+
+ // try to find a match by tag name first
+ while (count($before)) {
+ $p = array_pop($before);
+
+ if ($partTag && $partTag !== '*' && $partTag == $this->findTagName($p)) {
+ return [$before, $p, $after];
+ }
+
+ $after[] = $p;
+ }
+
+ // try again matching a non empty intersection and a compatible tagname
+ $before = $compound;
+ $after = [];
+
+ while (count($before)) {
+ $p = array_pop($before);
+
+ if ($this->checkCompatibleTags($partTag, $this->findTagName($p))) {
+ if (count(array_intersect($part, $p))) {
+ return [$before, $p, $after];
+ }
+ }
+
+ $after[] = $p;
+ }
+
+ return false;
+ }
+
+ /**
+ * Merge two part list taking care that
+ * - the html tag is coming first - if any
+ * - the :something are coming last
+ *
+ * @param array $parts1
+ * @param array $parts2
+ *
+ * @return array
+ */
+ protected function mergeParts($parts1, $parts2)
+ {
+ $tag1 = $this->findTagName($parts1);
+ $tag2 = $this->findTagName($parts2);
+ $tag = $this->checkCompatibleTags($tag1, $tag2);
+
+ // not compatible tags
+ if ($tag === false) {
+ return [];
+ }
+
+ if ($tag) {
+ if ($tag1) {
+ $parts1 = array_diff($parts1, [$tag1]);
+ }
+
+ if ($tag2) {
+ $parts2 = array_diff($parts2, [$tag2]);
+ }
+ }
+
+ $mergedParts = array_merge($parts1, $parts2);
+ $mergedOrderedParts = [];
+
+ foreach ($mergedParts as $part) {
+ if (strpos($part, ':') === 0) {
+ $mergedOrderedParts[] = $part;
+ }
+ }
+
+ $mergedParts = array_diff($mergedParts, $mergedOrderedParts);
+ $mergedParts = array_merge($mergedParts, $mergedOrderedParts);
+
+ if ($tag) {
+ array_unshift($mergedParts, $tag);
+ }
+
+ return $mergedParts;
+ }
+
+ /**
+ * Check the compatibility between two tag names:
+ * if both are defined they should be identical or one has to be '*'
+ *
+ * @param string $tag1
+ * @param string $tag2
+ *
+ * @return array|boolean
+ */
+ protected function checkCompatibleTags($tag1, $tag2)
+ {
+ $tags = [$tag1, $tag2];
+ $tags = array_unique($tags);
+ $tags = array_filter($tags);
+
+ if (count($tags) > 1) {
+ $tags = array_diff($tags, ['*']);
+ }
+
+ // not compatible nodes
+ if (count($tags) > 1) {
+ return false;
+ }
+
+ return $tags;
+ }
+
+ /**
+ * Find the html tag name in a selector parts list
+ *
+ * @param array $parts
+ *
+ * @return mixed|string
+ */
+ protected function findTagName($parts)
+ {
+ foreach ($parts as $part) {
+ if (! preg_match('/^[\[.:#%_-]/', $part)) {
+ return $part;
+ }
+ }
+
+ return '';
+ }
+
+ protected static $libSimpleSelectors = ['selector'];
+ protected function libSimpleSelectors($args)
+ {
+ $selector = reset($args);
+ $selector = $this->getSelectorArg($selector);
+
+ // remove selectors list layer, keeping the first one
+ $selector = reset($selector);
+
+ // remove parts list layer, keeping the first part
+ $part = reset($selector);
+
+ $listParts = [];
+
+ foreach ($part as $p) {
+ $listParts[] = [Type::T_STRING, '', [$p]];
+ }
+
+ return [Type::T_LIST, ',', $listParts];
}
}
diff --git a/vendor/leafo/scssphp/src/Compiler/Environment.php b/vendor/scssphp/scssphp/src/Compiler/Environment.php
similarity index 58%
rename from vendor/leafo/scssphp/src/Compiler/Environment.php
rename to vendor/scssphp/scssphp/src/Compiler/Environment.php
index fe309dd3..03eb86a5 100644
--- a/vendor/leafo/scssphp/src/Compiler/Environment.php
+++ b/vendor/scssphp/scssphp/src/Compiler/Environment.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Compiler;
+namespace ScssPhp\ScssPhp\Compiler;
/**
* Compiler environment
@@ -19,12 +19,12 @@ namespace Leafo\ScssPhp\Compiler;
class Environment
{
/**
- * @var \Leafo\ScssPhp\Block
+ * @var \ScssPhp\ScssPhp\Block
*/
public $block;
/**
- * @var \Leafo\ScssPhp\Compiler\Environment
+ * @var \ScssPhp\ScssPhp\Compiler\Environment
*/
public $parent;
@@ -33,6 +33,11 @@ class Environment
*/
public $store;
+ /**
+ * @var array
+ */
+ public $storeUnreduced;
+
/**
* @var integer
*/
diff --git a/vendor/leafo/scssphp/src/Exception/CompilerException.php b/vendor/scssphp/scssphp/src/Exception/CompilerException.php
similarity index 65%
rename from vendor/leafo/scssphp/src/Exception/CompilerException.php
rename to vendor/scssphp/scssphp/src/Exception/CompilerException.php
index 7ca2e2b3..a9d134fc 100644
--- a/vendor/leafo/scssphp/src/Exception/CompilerException.php
+++ b/vendor/scssphp/scssphp/src/Exception/CompilerException.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Exception;
+namespace ScssPhp\ScssPhp\Exception;
/**
* Compiler exception
diff --git a/vendor/leafo/scssphp/src/Exception/ParserException.php b/vendor/scssphp/scssphp/src/Exception/ParserException.php
similarity index 64%
rename from vendor/leafo/scssphp/src/Exception/ParserException.php
rename to vendor/scssphp/scssphp/src/Exception/ParserException.php
index 6d64335f..2fa12dd7 100644
--- a/vendor/leafo/scssphp/src/Exception/ParserException.php
+++ b/vendor/scssphp/scssphp/src/Exception/ParserException.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Exception;
+namespace ScssPhp\ScssPhp\Exception;
/**
* Parser Exception
diff --git a/vendor/leafo/scssphp/src/Exception/RangeException.php b/vendor/scssphp/scssphp/src/Exception/RangeException.php
similarity index 64%
rename from vendor/leafo/scssphp/src/Exception/RangeException.php
rename to vendor/scssphp/scssphp/src/Exception/RangeException.php
index 3ba6bf14..ee36c97e 100644
--- a/vendor/leafo/scssphp/src/Exception/RangeException.php
+++ b/vendor/scssphp/scssphp/src/Exception/RangeException.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Exception;
+namespace ScssPhp\ScssPhp\Exception;
/**
* Range exception
diff --git a/vendor/leafo/scssphp/src/Exception/ServerException.php b/vendor/scssphp/scssphp/src/Exception/ServerException.php
similarity index 64%
rename from vendor/leafo/scssphp/src/Exception/ServerException.php
rename to vendor/scssphp/scssphp/src/Exception/ServerException.php
index d0ed0842..d4a207af 100644
--- a/vendor/leafo/scssphp/src/Exception/ServerException.php
+++ b/vendor/scssphp/scssphp/src/Exception/ServerException.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Exception;
+namespace ScssPhp\ScssPhp\Exception;
/**
* Server Exception
diff --git a/vendor/leafo/scssphp/src/Formatter.php b/vendor/scssphp/scssphp/src/Formatter.php
similarity index 63%
rename from vendor/leafo/scssphp/src/Formatter.php
rename to vendor/scssphp/scssphp/src/Formatter.php
index b4f90aa9..e1777045 100644
--- a/vendor/leafo/scssphp/src/Formatter.php
+++ b/vendor/scssphp/scssphp/src/Formatter.php
@@ -2,17 +2,17 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-use Leafo\ScssPhp\SourceMap\SourceMapGenerator;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\SourceMap\SourceMapGenerator;
/**
* Base formatter
@@ -62,7 +62,7 @@ abstract class Formatter
public $keepSemicolons;
/**
- * @var \Leafo\ScssPhp\Formatter\OutputBlock
+ * @var \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
protected $currentBlock;
@@ -77,10 +77,15 @@ abstract class Formatter
protected $currentColumn;
/**
- * @var \Leafo\ScssPhp\SourceMap\SourceMapGenerator
+ * @var \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator
*/
protected $sourceMapGenerator;
+ /**
+ * @var string
+ */
+ protected $strippedSemicolon;
+
/**
* Initialize formatter
*
@@ -113,30 +118,10 @@ abstract class Formatter
return rtrim($name) . $this->assignSeparator . $value . ';';
}
- /**
- * Strip semi-colon appended by property(); it's a separator, not a terminator
- *
- * @api
- *
- * @param array $lines
- */
- public function stripSemicolon(&$lines)
- {
- if ($this->keepSemicolons) {
- return;
- }
-
- if (($count = count($lines))
- && substr($lines[$count - 1], -1) === ';'
- ) {
- $lines[$count - 1] = substr($lines[$count - 1], 0, -1);
- }
- }
-
/**
* Output lines inside a block
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockLines(OutputBlock $block)
{
@@ -154,7 +139,7 @@ abstract class Formatter
/**
* Output block selectors
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockSelectors(OutputBlock $block)
{
@@ -168,7 +153,7 @@ abstract class Formatter
/**
* Output block children
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockChildren(OutputBlock $block)
{
@@ -180,7 +165,7 @@ abstract class Formatter
/**
* Output non-empty block
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function block(OutputBlock $block)
{
@@ -209,6 +194,10 @@ abstract class Formatter
if (! empty($block->selectors)) {
$this->indentLevel--;
+ if (! $this->keepSemicolons) {
+ $this->strippedSemicolon = '';
+ }
+
if (empty($block->children)) {
$this->write($this->break);
}
@@ -217,13 +206,41 @@ abstract class Formatter
}
}
+ /**
+ * Test and clean safely empty children
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ *
+ * @return boolean
+ */
+ protected function testEmptyChildren($block)
+ {
+ $isEmpty = empty($block->lines);
+
+ if ($block->children) {
+ foreach ($block->children as $k => &$child) {
+ if (! $this->testEmptyChildren($child)) {
+ $isEmpty = false;
+ continue;
+ }
+
+ if ($child->type === Type::T_MEDIA || $child->type === Type::T_DIRECTIVE) {
+ $child->children = [];
+ $child->selectors = null;
+ }
+ }
+ }
+
+ return $isEmpty;
+ }
+
/**
* Entry point to formatting a block
*
* @api
*
- * @param \Leafo\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree
- * @param \Leafo\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree
+ * @param \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator
*
* @return string
*/
@@ -232,11 +249,13 @@ abstract class Formatter
$this->sourceMapGenerator = null;
if ($sourceMapGenerator) {
- $this->currentLine = 1;
- $this->currentColumn = 0;
+ $this->currentLine = 1;
+ $this->currentColumn = 0;
$this->sourceMapGenerator = $sourceMapGenerator;
}
+ $this->testEmptyChildren($block);
+
ob_start();
$this->block($block);
@@ -247,16 +266,39 @@ abstract class Formatter
}
/**
+ * Output content
+ *
* @param string $str
*/
protected function write($str)
{
+ if (! empty($this->strippedSemicolon)) {
+ echo $this->strippedSemicolon;
+
+ $this->strippedSemicolon = '';
+ }
+
+ /*
+ * Maybe Strip semi-colon appended by property(); it's a separator, not a terminator
+ * will be striped for real before a closing, otherwise displayed unchanged starting the next write
+ */
+ if (! $this->keepSemicolons &&
+ $str &&
+ (strpos($str, ';') !== false) &&
+ (substr($str, -1) === ';')
+ ) {
+ $str = substr($str, 0, -1);
+
+ $this->strippedSemicolon = ';';
+ }
+
if ($this->sourceMapGenerator) {
$this->sourceMapGenerator->addMapping(
$this->currentLine,
$this->currentColumn,
$this->currentBlock->sourceLine,
- $this->currentBlock->sourceColumn - 1, //columns from parser are off by one
+ //columns from parser are off by one
+ $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0,
$this->currentBlock->sourceName
);
diff --git a/vendor/leafo/scssphp/src/Formatter/Compact.php b/vendor/scssphp/scssphp/src/Formatter/Compact.php
similarity index 81%
rename from vendor/leafo/scssphp/src/Formatter/Compact.php
rename to vendor/scssphp/scssphp/src/Formatter/Compact.php
index 4efa1a08..591f0c92 100644
--- a/vendor/leafo/scssphp/src/Formatter/Compact.php
+++ b/vendor/scssphp/scssphp/src/Formatter/Compact.php
@@ -2,16 +2,16 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter;
/**
* Compact formatter
diff --git a/vendor/leafo/scssphp/src/Formatter/Compressed.php b/vendor/scssphp/scssphp/src/Formatter/Compressed.php
similarity index 64%
rename from vendor/leafo/scssphp/src/Formatter/Compressed.php
rename to vendor/scssphp/scssphp/src/Formatter/Compressed.php
index 1faa7e11..ec4722ea 100644
--- a/vendor/leafo/scssphp/src/Formatter/Compressed.php
+++ b/vendor/scssphp/scssphp/src/Formatter/Compressed.php
@@ -2,17 +2,17 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Compressed formatter
@@ -59,4 +59,23 @@ class Compressed extends Formatter
$this->write($this->break);
}
}
+
+ /**
+ * Output block selectors
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ */
+ protected function blockSelectors(OutputBlock $block)
+ {
+ $inner = $this->indentStr();
+
+ $this->write(
+ $inner
+ . implode(
+ $this->tagSeparator,
+ str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
+ )
+ . $this->open . $this->break
+ );
+ }
}
diff --git a/vendor/leafo/scssphp/src/Formatter/Crunched.php b/vendor/scssphp/scssphp/src/Formatter/Crunched.php
similarity index 61%
rename from vendor/leafo/scssphp/src/Formatter/Crunched.php
rename to vendor/scssphp/scssphp/src/Formatter/Crunched.php
index 42d77b5f..51ccb516 100644
--- a/vendor/leafo/scssphp/src/Formatter/Crunched.php
+++ b/vendor/scssphp/scssphp/src/Formatter/Crunched.php
@@ -2,17 +2,17 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Crunched formatter
@@ -57,4 +57,23 @@ class Crunched extends Formatter
$this->write($this->break);
}
}
+
+ /**
+ * Output block selectors
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ */
+ protected function blockSelectors(OutputBlock $block)
+ {
+ $inner = $this->indentStr();
+
+ $this->write(
+ $inner
+ . implode(
+ $this->tagSeparator,
+ str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
+ )
+ . $this->open . $this->break
+ );
+ }
}
diff --git a/vendor/leafo/scssphp/src/Formatter/Debug.php b/vendor/scssphp/scssphp/src/Formatter/Debug.php
similarity index 92%
rename from vendor/leafo/scssphp/src/Formatter/Debug.php
rename to vendor/scssphp/scssphp/src/Formatter/Debug.php
index bfcbf41a..94e70c81 100644
--- a/vendor/leafo/scssphp/src/Formatter/Debug.php
+++ b/vendor/scssphp/scssphp/src/Formatter/Debug.php
@@ -2,17 +2,17 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Debug formatter
diff --git a/vendor/leafo/scssphp/src/Formatter/Expanded.php b/vendor/scssphp/scssphp/src/Formatter/Expanded.php
similarity index 81%
rename from vendor/leafo/scssphp/src/Formatter/Expanded.php
rename to vendor/scssphp/scssphp/src/Formatter/Expanded.php
index d8c1e887..9549c6cf 100644
--- a/vendor/leafo/scssphp/src/Formatter/Expanded.php
+++ b/vendor/scssphp/scssphp/src/Formatter/Expanded.php
@@ -2,17 +2,17 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Expanded formatter
@@ -55,7 +55,7 @@ class Expanded extends Formatter
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
- $block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
+ $block->lines[$index] = preg_replace('/[\r\n]+/', $glue, $line);
}
}
diff --git a/vendor/scssphp/scssphp/src/Formatter/Nested.php b/vendor/scssphp/scssphp/src/Formatter/Nested.php
new file mode 100644
index 00000000..f9e7f037
--- /dev/null
+++ b/vendor/scssphp/scssphp/src/Formatter/Nested.php
@@ -0,0 +1,228 @@
+
+ */
+class Nested extends Formatter
+{
+ /**
+ * @var integer
+ */
+ private $depth;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct()
+ {
+ $this->indentLevel = 0;
+ $this->indentChar = ' ';
+ $this->break = "\n";
+ $this->open = ' {';
+ $this->close = ' }';
+ $this->tagSeparator = ', ';
+ $this->assignSeparator = ': ';
+ $this->keepSemicolons = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function indentStr()
+ {
+ $n = $this->depth - 1;
+
+ return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function blockLines(OutputBlock $block)
+ {
+ $inner = $this->indentStr();
+
+ $glue = $this->break . $inner;
+
+ foreach ($block->lines as $index => $line) {
+ if (substr($line, 0, 2) === '/*') {
+ $block->lines[$index] = preg_replace('/[\r\n]+/', $glue, $line);
+ }
+ }
+
+ $this->write($inner . implode($glue, $block->lines));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function block(OutputBlock $block)
+ {
+ static $depths;
+ static $downLevel;
+ static $closeBlock;
+ static $previousEmpty;
+ static $previousHasSelector;
+
+ if ($block->type === 'root') {
+ $depths = [ 0 ];
+ $downLevel = '';
+ $closeBlock = '';
+ $this->depth = 0;
+ $previousEmpty = false;
+ $previousHasSelector = false;
+ }
+
+ $isMediaOrDirective = in_array($block->type, [Type::T_DIRECTIVE, Type::T_MEDIA]);
+ $isSupport = ($block->type === Type::T_DIRECTIVE
+ && $block->selectors && strpos(implode('', $block->selectors), '@supports') !== false);
+
+ while ($block->depth < end($depths) || ($block->depth == 1 && end($depths) == 1)) {
+ array_pop($depths);
+ $this->depth--;
+
+ if (! $this->depth && ($block->depth <= 1 || (! $this->indentLevel && $block->type === Type::T_COMMENT)) &&
+ (($block->selectors && ! $isMediaOrDirective) || $previousHasSelector)
+ ) {
+ $downLevel = $this->break;
+ }
+
+ if (empty($block->lines) && empty($block->children)) {
+ $previousEmpty = true;
+ }
+ }
+
+ if (empty($block->lines) && empty($block->children)) {
+ return;
+ }
+
+ $this->currentBlock = $block;
+
+ if (! empty($block->lines) || (! empty($block->children) && ($this->depth < 1 || $isSupport))) {
+ if ($block->depth > end($depths)) {
+ if (! $previousEmpty || $this->depth < 1) {
+ $this->depth++;
+ $depths[] = $block->depth;
+ } else {
+ // keep the current depth unchanged but take the block depth as a new reference for following blocks
+ array_pop($depths);
+ $depths[] = $block->depth;
+ }
+ }
+ }
+
+ $previousEmpty = ($block->type === Type::T_COMMENT);
+ $previousHasSelector = false;
+
+ if (! empty($block->selectors)) {
+ if ($closeBlock) {
+ $this->write($closeBlock);
+ $closeBlock = '';
+ }
+
+ if ($downLevel) {
+ $this->write($downLevel);
+ $downLevel = '';
+ }
+
+ $this->blockSelectors($block);
+
+ $this->indentLevel++;
+ }
+
+ if (! empty($block->lines)) {
+ if ($closeBlock) {
+ $this->write($closeBlock);
+ $closeBlock = '';
+ }
+
+ if ($downLevel) {
+ $this->write($downLevel);
+ $downLevel = '';
+ }
+
+ $this->blockLines($block);
+
+ $closeBlock = $this->break;
+ }
+
+ if (! empty($block->children)) {
+ if ($this->depth > 0 && ($isMediaOrDirective || ! $this->hasFlatChild($block))) {
+ array_pop($depths);
+
+ $this->depth--;
+ $this->blockChildren($block);
+ $this->depth++;
+
+ $depths[] = $block->depth;
+ } else {
+ $this->blockChildren($block);
+ }
+ }
+
+ // reclear to not be spoiled by children if T_DIRECTIVE
+ if ($block->type === Type::T_DIRECTIVE) {
+ $previousHasSelector = false;
+ }
+
+ if (! empty($block->selectors)) {
+ $this->indentLevel--;
+
+ if (! $this->keepSemicolons) {
+ $this->strippedSemicolon = '';
+ }
+
+ $this->write($this->close);
+
+ $closeBlock = $this->break;
+
+ if ($this->depth > 1 && ! empty($block->children)) {
+ array_pop($depths);
+ $this->depth--;
+ }
+
+ if (! $isMediaOrDirective) {
+ $previousHasSelector = true;
+ }
+ }
+
+ if ($block->type === 'root') {
+ $this->write($this->break);
+ }
+ }
+
+ /**
+ * Block has flat child
+ *
+ * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+ *
+ * @return boolean
+ */
+ private function hasFlatChild($block)
+ {
+ foreach ($block->children as $child) {
+ if (empty($child->selectors)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/leafo/scssphp/src/Formatter/OutputBlock.php b/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php
similarity index 80%
rename from vendor/leafo/scssphp/src/Formatter/OutputBlock.php
rename to vendor/scssphp/scssphp/src/Formatter/OutputBlock.php
index 5eb589c9..3e6fd928 100644
--- a/vendor/leafo/scssphp/src/Formatter/OutputBlock.php
+++ b/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Formatter;
+namespace ScssPhp\ScssPhp\Formatter;
/**
* Output block
@@ -44,7 +44,7 @@ class OutputBlock
public $children;
/**
- * @var \Leafo\ScssPhp\Formatter\OutputBlock
+ * @var \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
public $parent;
diff --git a/vendor/leafo/scssphp/src/Node.php b/vendor/scssphp/scssphp/src/Node.php
similarity index 79%
rename from vendor/leafo/scssphp/src/Node.php
rename to vendor/scssphp/scssphp/src/Node.php
index b9f7945a..dab565a6 100644
--- a/vendor/leafo/scssphp/src/Node.php
+++ b/vendor/scssphp/scssphp/src/Node.php
@@ -2,14 +2,14 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
/**
* Base node
diff --git a/vendor/leafo/scssphp/src/Node/Number.php b/vendor/scssphp/scssphp/src/Node/Number.php
similarity index 93%
rename from vendor/leafo/scssphp/src/Node/Number.php
rename to vendor/scssphp/scssphp/src/Node/Number.php
index 42c16803..acbabff7 100644
--- a/vendor/leafo/scssphp/src/Node/Number.php
+++ b/vendor/scssphp/scssphp/src/Node/Number.php
@@ -2,18 +2,18 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp\Node;
+namespace ScssPhp\ScssPhp\Node;
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\Type;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\Type;
/**
* Dimension + optional units
@@ -100,7 +100,7 @@ class Number extends Node implements \ArrayAccess
*
* @param array $units
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
public function coerce($units)
{
@@ -123,7 +123,7 @@ class Number extends Node implements \ArrayAccess
/**
* Normalize number
*
- * @return \Leafo\ScssPhp\Node\Number
+ * @return \ScssPhp\ScssPhp\Node\Number
*/
public function normalize()
{
@@ -141,17 +141,17 @@ class Number extends Node implements \ArrayAccess
public function offsetExists($offset)
{
if ($offset === -3) {
- return $this->sourceColumn !== null;
+ return ! is_null($this->sourceColumn);
}
if ($offset === -2) {
- return $this->sourceLine !== null;
+ return ! is_null($this->sourceLine);
}
- if ($offset === -1
- || $offset === 0
- || $offset === 1
- || $offset === 2
+ if ($offset === -1 ||
+ $offset === 0 ||
+ $offset === 1 ||
+ $offset === 2
) {
return true;
}
@@ -259,7 +259,7 @@ class Number extends Node implements \ArrayAccess
/**
* Output number
*
- * @param \Leafo\ScssPhp\Compiler $compiler
+ * @param \ScssPhp\ScssPhp\Compiler $compiler
*
* @return string
*/
diff --git a/vendor/leafo/scssphp/src/Parser.php b/vendor/scssphp/scssphp/src/Parser.php
similarity index 57%
rename from vendor/leafo/scssphp/src/Parser.php
rename to vendor/scssphp/scssphp/src/Parser.php
index de86f094..6a30af12 100644
--- a/vendor/leafo/scssphp/src/Parser.php
+++ b/vendor/scssphp/scssphp/src/Parser.php
@@ -2,20 +2,21 @@
/**
* SCSSPHP
*
- * @copyright 2012-2018 Leaf Corcoran
+ * @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
- * @link http://leafo.github.io/scssphp
+ * @link http://scssphp.github.io/scssphp
*/
-namespace Leafo\ScssPhp;
+namespace ScssPhp\ScssPhp;
-use Leafo\ScssPhp\Block;
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Exception\ParserException;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\Type;
+use ScssPhp\ScssPhp\Block;
+use ScssPhp\ScssPhp\Cache;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Exception\ParserException;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\Type;
/**
* Parser
@@ -53,6 +54,8 @@ class Parser
protected static $operatorPattern;
protected static $whitePattern;
+ protected $cache;
+
private $sourceName;
private $sourceIndex;
private $sourcePositions;
@@ -61,27 +64,32 @@ class Parser
private $env;
private $inParens;
private $eatWhiteDefault;
+ private $discardComments;
private $buffer;
private $utf8;
private $encoding;
private $patternModifiers;
+ private $commentsSeen;
/**
* Constructor
*
* @api
*
- * @param string $sourceName
- * @param integer $sourceIndex
- * @param string $encoding
+ * @param string $sourceName
+ * @param integer $sourceIndex
+ * @param string $encoding
+ * @param \ScssPhp\ScssPhp\Cache $cache
*/
- public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8')
+ public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8', $cache = null)
{
$this->sourceName = $sourceName ?: '(stdin)';
$this->sourceIndex = $sourceIndex;
$this->charset = null;
$this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8';
$this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
+ $this->commentsSeen = [];
+ $this->discardComments = false;
if (empty(static::$operatorPattern)) {
static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=\>|\<\=?|and|or)';
@@ -95,6 +103,10 @@ class Parser
? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS'
: '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS';
}
+
+ if ($cache) {
+ $this->cache = $cache;
+ }
}
/**
@@ -116,13 +128,15 @@ class Parser
*
* @param string $msg
*
- * @throws \Leafo\ScssPhp\Exception\ParserException
+ * @throws \ScssPhp\ScssPhp\Exception\ParserException
*/
public function throwParseError($msg = 'parse error')
{
- list($line, /* $column */) = $this->getSourcePosition($this->count);
+ list($line, $column) = $this->getSourcePosition($this->count);
- $loc = empty($this->sourceName) ? "line: $line" : "$this->sourceName on line $line";
+ $loc = empty($this->sourceName)
+ ? "line: $line, column: $column"
+ : "$this->sourceName on line $line, at column $column";
if ($this->peek("(.*?)(\n|$)", $m, $this->count)) {
throw new ParserException("$msg: failed at `$m[1]` $loc");
@@ -138,10 +152,23 @@ class Parser
*
* @param string $buffer
*
- * @return \Leafo\ScssPhp\Block
+ * @return \ScssPhp\ScssPhp\Block
*/
public function parse($buffer)
{
+ if ($this->cache) {
+ $cacheKey = $this->sourceName . ":" . md5($buffer);
+ $parseOptions = [
+ 'charset' => $this->charset,
+ 'utf8' => $this->utf8,
+ ];
+ $v = $this->cache->getCache("parse", $cacheKey, $parseOptions);
+
+ if (! is_null($v)) {
+ return $v;
+ }
+ }
+
// strip BOM (byte order marker)
if (substr($buffer, 0, 3) === "\xef\xbb\xbf") {
$buffer = substr($buffer, 3);
@@ -177,10 +204,12 @@ class Parser
array_unshift($this->env->children, $this->charset);
}
- $this->env->isRoot = true;
-
$this->restoreEncoding();
+ if ($this->cache) {
+ $this->cache->setCache("parse", $cacheKey, $this->env, $parseOptions);
+ }
+
return $this->env;
}
@@ -189,8 +218,8 @@ class Parser
*
* @api
*
- * @param string $buffer
- * @param string $out
+ * @param string $buffer
+ * @param string|array $out
*
* @return boolean
*/
@@ -216,8 +245,8 @@ class Parser
*
* @api
*
- * @param string $buffer
- * @param string $out
+ * @param string $buffer
+ * @param string|array $out
*
* @return boolean
*/
@@ -238,6 +267,33 @@ class Parser
return $selector;
}
+ /**
+ * Parse a media Query
+ *
+ * @api
+ *
+ * @param string $buffer
+ * @param string|array $out
+ *
+ * @return boolean
+ */
+ public function parseMediaQueryList($buffer, &$out)
+ {
+ $this->count = 0;
+ $this->env = null;
+ $this->inParens = false;
+ $this->eatWhiteDefault = true;
+ $this->buffer = (string) $buffer;
+
+ $this->saveEncoding();
+
+ $isMediaQuery = $this->mediaQueryList($out);
+
+ $this->restoreEncoding();
+
+ return $isMediaQuery;
+ }
+
/**
* Parse a single chunk off the head of the buffer and append it to the
* current parse environment.
@@ -271,7 +327,7 @@ class Parser
* the buffer position will be left at an invalid state. In order to
* avoid this, Compiler::seek() is used to remember and set buffer positions.
*
- * Before parsing a chain, use $s = $this->seek() to remember the current
+ * Before parsing a chain, use $s = $this->count to remember the current
* position into $s. Then if a chain fails, use $this->seek($s) to
* go back where we started.
*
@@ -279,25 +335,28 @@ class Parser
*/
protected function parseChunk()
{
- $s = $this->seek();
+ $s = $this->count;
// the directives
if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] === '@') {
- if ($this->literal('@at-root') &&
+ if ($this->literal('@at-root', 8) &&
($this->selectors($selector) || true) &&
($this->map($with) || true) &&
- $this->literal('{')
+ (($this->matchChar('(')
+ && $this->interpolation($with)
+ && $this->matchChar(')')) || true) &&
+ $this->matchChar('{', false)
) {
$atRoot = $this->pushSpecialBlock(Type::T_AT_ROOT, $s);
$atRoot->selector = $selector;
- $atRoot->with = $with;
+ $atRoot->with = $with;
return true;
}
$this->seek($s);
- if ($this->literal('@media') && $this->mediaQueryList($mediaQueryList) && $this->literal('{')) {
+ if ($this->literal('@media', 6) && $this->mediaQueryList($mediaQueryList) && $this->matchChar('{', false)) {
$media = $this->pushSpecialBlock(Type::T_MEDIA, $s);
$media->queryList = $mediaQueryList[2];
@@ -306,10 +365,10 @@ class Parser
$this->seek($s);
- if ($this->literal('@mixin') &&
+ if ($this->literal('@mixin', 6) &&
$this->keyword($mixinName) &&
($this->argumentDef($args) || true) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
$mixin = $this->pushSpecialBlock(Type::T_MIXIN, $s);
$mixin->name = $mixinName;
@@ -320,15 +379,24 @@ class Parser
$this->seek($s);
- if ($this->literal('@include') &&
+ if ($this->literal('@include', 8) &&
$this->keyword($mixinName) &&
- ($this->literal('(') &&
+ ($this->matchChar('(') &&
($this->argValues($argValues) || true) &&
- $this->literal(')') || true) &&
+ $this->matchChar(')') || true) &&
($this->end() ||
- $this->literal('{') && $hasBlock = true)
+ ($this->literal('using', 5) &&
+ $this->argumentDef($argUsing) &&
+ ($this->end() || $this->matchChar('{') && $hasBlock = true)) ||
+ $this->matchChar('{') && $hasBlock = true)
) {
- $child = [Type::T_INCLUDE, $mixinName, isset($argValues) ? $argValues : null, null];
+ $child = [
+ Type::T_INCLUDE,
+ $mixinName,
+ isset($argValues) ? $argValues : null,
+ null,
+ isset($argUsing) ? $argUsing : null
+ ];
if (! empty($hasBlock)) {
$include = $this->pushSpecialBlock(Type::T_INCLUDE, $s);
@@ -342,7 +410,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@scssphp-import-once') &&
+ if ($this->literal('@scssphp-import-once', 20) &&
$this->valueList($importPath) &&
$this->end()
) {
@@ -353,7 +421,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@import') &&
+ if ($this->literal('@import', 7) &&
$this->valueList($importPath) &&
$this->end()
) {
@@ -364,7 +432,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@import') &&
+ if ($this->literal('@import', 7) &&
$this->url($importPath) &&
$this->end()
) {
@@ -375,7 +443,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@extend') &&
+ if ($this->literal('@extend', 7) &&
$this->selectors($selectors) &&
$this->end()
) {
@@ -388,10 +456,10 @@ class Parser
$this->seek($s);
- if ($this->literal('@function') &&
+ if ($this->literal('@function', 9) &&
$this->keyword($fnName) &&
$this->argumentDef($args) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
$func = $this->pushSpecialBlock(Type::T_FUNCTION, $s);
$func->name = $fnName;
@@ -402,7 +470,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@break') && $this->end()) {
+ if ($this->literal('@break', 6) && $this->end()) {
$this->append([Type::T_BREAK], $s);
return true;
@@ -410,7 +478,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@continue') && $this->end()) {
+ if ($this->literal('@continue', 9) && $this->end()) {
$this->append([Type::T_CONTINUE], $s);
return true;
@@ -418,8 +486,7 @@ class Parser
$this->seek($s);
-
- if ($this->literal('@return') && ($this->valueList($retVal) || true) && $this->end()) {
+ if ($this->literal('@return', 7) && ($this->valueList($retVal) || true) && $this->end()) {
$this->append([Type::T_RETURN, isset($retVal) ? $retVal : [Type::T_NULL]], $s);
return true;
@@ -427,11 +494,11 @@ class Parser
$this->seek($s);
- if ($this->literal('@each') &&
+ if ($this->literal('@each', 5) &&
$this->genericList($varNames, 'variable', ',', false) &&
- $this->literal('in') &&
+ $this->literal('in', 2) &&
$this->valueList($list) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
$each = $this->pushSpecialBlock(Type::T_EACH, $s);
@@ -446,9 +513,9 @@ class Parser
$this->seek($s);
- if ($this->literal('@while') &&
+ if ($this->literal('@while', 6) &&
$this->expression($cond) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
$while = $this->pushSpecialBlock(Type::T_WHILE, $s);
$while->cond = $cond;
@@ -458,19 +525,19 @@ class Parser
$this->seek($s);
- if ($this->literal('@for') &&
+ if ($this->literal('@for', 4) &&
$this->variable($varName) &&
- $this->literal('from') &&
+ $this->literal('from', 4) &&
$this->expression($start) &&
- ($this->literal('through') ||
- ($forUntil = true && $this->literal('to'))) &&
+ ($this->literal('through', 7) ||
+ ($forUntil = true && $this->literal('to', 2))) &&
$this->expression($end) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
$for = $this->pushSpecialBlock(Type::T_FOR, $s);
- $for->var = $varName[1];
+ $for->var = $varName[1];
$for->start = $start;
- $for->end = $end;
+ $for->end = $end;
$for->until = isset($forUntil);
return true;
@@ -478,9 +545,15 @@ class Parser
$this->seek($s);
- if ($this->literal('@if') && $this->valueList($cond) && $this->literal('{')) {
+ if ($this->literal('@if', 3) && $this->valueList($cond) && $this->matchChar('{', false)) {
$if = $this->pushSpecialBlock(Type::T_IF, $s);
- $if->cond = $cond;
+ while ($cond[0] === Type::T_LIST
+ && !empty($cond['enclosing'])
+ && $cond['enclosing'] === 'parent'
+ && count($cond[2]) == 1) {
+ $cond = reset($cond[2]);
+ }
+ $if->cond = $cond;
$if->cases = [];
return true;
@@ -488,7 +561,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@debug') &&
+ if ($this->literal('@debug', 6) &&
$this->valueList($value) &&
$this->end()
) {
@@ -499,7 +572,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@warn') &&
+ if ($this->literal('@warn', 5) &&
$this->valueList($value) &&
$this->end()
) {
@@ -510,7 +583,7 @@ class Parser
$this->seek($s);
- if ($this->literal('@error') &&
+ if ($this->literal('@error', 6) &&
$this->valueList($value) &&
$this->end()
) {
@@ -521,8 +594,15 @@ class Parser
$this->seek($s);
- if ($this->literal('@content') && $this->end()) {
- $this->append([Type::T_MIXIN_CONTENT], $s);
+ #if ($this->literal('@content', 8))
+
+ if ($this->literal('@content', 8) &&
+ ($this->end() ||
+ $this->matchChar('(') &&
+ $this->argValues($argContent) &&
+ $this->matchChar(')') &&
+ $this->end())) {
+ $this->append([Type::T_MIXIN_CONTENT, isset($argContent) ? $argContent : null], $s);
return true;
}
@@ -534,10 +614,10 @@ class Parser
if (isset($last) && $last[0] === Type::T_IF) {
list(, $if) = $last;
- if ($this->literal('@else')) {
- if ($this->literal('{')) {
+ if ($this->literal('@else', 5)) {
+ if ($this->matchChar('{', false)) {
$else = $this->pushSpecialBlock(Type::T_ELSE, $s);
- } elseif ($this->literal('if') && $this->valueList($cond) && $this->literal('{')) {
+ } elseif ($this->literal('if', 2) && $this->valueList($cond) && $this->matchChar('{', false)) {
$else = $this->pushSpecialBlock(Type::T_ELSEIF, $s);
$else->cond = $cond;
}
@@ -554,7 +634,7 @@ class Parser
}
// only retain the first @charset directive encountered
- if ($this->literal('@charset') &&
+ if ($this->literal('@charset', 8) &&
$this->valueList($charset) &&
$this->end()
) {
@@ -575,11 +655,24 @@ class Parser
$this->seek($s);
+ if ($this->literal('@supports', 9) &&
+ ($t1=$this->supportsQuery($supportQuery)) &&
+ ($t2=$this->matchChar('{', false))
+ ) {
+ $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s);
+ $directive->name = 'supports';
+ $directive->value = $supportQuery;
+
+ return true;
+ }
+
+ $this->seek($s);
+
// doesn't match built in directive, do generic one
- if ($this->literal('@', false) &&
+ if ($this->matchChar('@', false) &&
$this->keyword($dirName) &&
($this->variable($dirValue) || $this->openString('{', $dirValue) || true) &&
- $this->literal('{')
+ $this->matchChar('{', false)
) {
if ($dirName === 'media') {
$directive = $this->pushSpecialBlock(Type::T_MEDIA, $s);
@@ -597,13 +690,26 @@ class Parser
$this->seek($s);
+ // maybe it's a generic blockless directive
+ if ($this->matchChar('@', false) &&
+ $this->keyword($dirName) &&
+ $this->valueList($dirValue) &&
+ $this->end()
+ ) {
+ $this->append([Type::T_DIRECTIVE, [$dirName, $dirValue]], $s);
+
+ return true;
+ }
+
+ $this->seek($s);
+
return false;
}
// property shortcut
// captures most properties before having to parse a selector
if ($this->keyword($name, false) &&
- $this->literal(': ') &&
+ $this->literal(': ', 2) &&
$this->valueList($value) &&
$this->end()
) {
@@ -617,7 +723,7 @@ class Parser
// variable assigns
if ($this->variable($name) &&
- $this->literal(':') &&
+ $this->matchChar(':') &&
$this->valueList($value) &&
$this->end()
) {
@@ -631,31 +737,42 @@ class Parser
$this->seek($s);
// misc
- if ($this->literal('-->')) {
+ if ($this->literal('-->', 3)) {
return true;
}
// opening css block
- if ($this->selectors($selectors) && $this->literal('{')) {
+ if ($this->selectors($selectors) && $this->matchChar('{', false)) {
$this->pushBlock($selectors, $s);
+ if ($this->eatWhiteDefault) {
+ $this->whitespace();
+ $this->append(null); // collect comments at the beginning if needed
+ }
+
return true;
}
$this->seek($s);
// property assign, or nested assign
- if ($this->propertyName($name) && $this->literal(':')) {
+ if ($this->propertyName($name) && $this->matchChar(':')) {
$foundSomething = false;
if ($this->valueList($value)) {
+ if (empty($this->env->parent)) {
+ $this->throwParseError('expected "{"');
+ }
+
$this->append([Type::T_ASSIGN, $name, $value], $s);
$foundSomething = true;
}
- if ($this->literal('{')) {
+ if ($this->matchChar('{', false)) {
$propBlock = $this->pushSpecialBlock(Type::T_NESTED_PROPERTY, $s);
$propBlock->prefix = $name;
+ $propBlock->hasValue = $foundSomething;
+
$foundSomething = true;
} elseif ($foundSomething) {
$foundSomething = $this->end();
@@ -669,9 +786,15 @@ class Parser
$this->seek($s);
// closing a block
- if ($this->literal('}')) {
+ if ($this->matchChar('}', false)) {
$block = $this->popBlock();
+ if (! isset($block->type) || $block->type !== Type::T_IF) {
+ if ($this->env->parent) {
+ $this->append(null); // collect comments before next statement if needed
+ }
+ }
+
if (isset($block->type) && $block->type === Type::T_INCLUDE) {
$include = $block->child;
unset($block->child);
@@ -682,12 +805,21 @@ class Parser
$this->append([$type, $block], $s);
}
+ // collect comments just after the block closing if needed
+ if ($this->eatWhiteDefault) {
+ $this->whitespace();
+
+ if ($this->env->comments) {
+ $this->append(null);
+ }
+ }
+
return true;
}
// extra stuff
- if ($this->literal(';') ||
- $this->literal('