public function testTestCreateForCouldNotLexValue() { $exception = ExpressionLanguageExceptionFactory::createForCouldNotLexValue('foo'); $this->assertEquals('Could not lex the value "foo".', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertNull($exception->getPrevious()); }
/** * Parses "10x @user*", "<randomNumber(0, 10)x @user<{param}>*", etc. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : DynamicArrayValue { parent::parse($token); if (1 !== preg_match(self::REGEX, $token->getValue(), $matches)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } return new DynamicArrayValue((int) $this->parser->parse($matches['quantifier']), $this->parser->parse($matches['elements'])); }
/** * Parses '<<', '@@'... * * {@inheritdoc} */ public function parse(Token $token) : string { $value = $token->getValue(); if ('' === $value) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } return $this->tokenizer->detokenize(substr($value, 1)); }
/** * Parses expressions such as '$username'. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) { try { return new VariableValue(substr($token->getValue(), 1)); } catch (\TypeError $error) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $error); } }
/** * Parses expressions such as '60%? foo: bar'. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : OptionalValue { parent::parse($token); if (1 !== preg_match(self::REGEX, $token->getValue(), $matches)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } return new OptionalValue($this->parser->parse($matches['quantifier']), $this->parser->parse(trim($matches['first_member'])), array_key_exists('second_member', $matches) ? $this->parser->parse($matches['second_member']) : null); }
/** * Parses expressions such as "@user". * * {@inheritdoc} */ public function parse(Token $token) : FixtureReferenceValue { $value = $token->getValue(); try { return new FixtureReferenceValue(substr($value, 1)); } catch (\InvalidArgumentException $exception) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $exception); } }
/** * @inheritdoc */ public function parse(Token $token) { foreach ($this->parsers as $parser) { if ($parser->canParse($token)) { return $parser->parse($token); } } throw ExpressionLanguageExceptionFactory::createForNoParserFoundForToken($token); }
/** * Parses expressions such as '$username'. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) { $value = $token->getValue(); $fixtureId = substr($value, 1, strlen($value) - 2); if (false === $fixtureId) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } return FixtureMatchReferenceValue::createWildcardReference($fixtureId); }
/** * Parses '<{paramKey}>', '<{nested_<{param}>}>', etc. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : ParameterValue { $value = $token->getValue(); try { $paramKey = substr($value, 2, strlen($value) - 4); return new ParameterValue($paramKey); } catch (\TypeError $error) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $error); } }
/** * @param Token $token * * @throws ParseException * * @return RangeName * * @example * "@user{1..10}" => new RangeName('user', 1, 10) */ private function buildRange(Token $token) : RangeName { $matches = []; $name = substr($token->getValue(), 1); if (1 !== preg_match(self::REGEX, (string) $name, $matches)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $reference = str_replace(sprintf('{%s}', $matches['range']), $this->token, $name); return new RangeName($reference, (int) $matches['from'], (int) $matches['to']); }
/** * Parses '<{paramKey}>', '<{nested_<{param}>}>'. * * {@inheritdoc} */ public function parse(Token $token) : array { parent::parse($token); $value = $token->getValue(); try { $elements = substr($value, 1, strlen($value) - 2); return $this->parseElements($this->parser, $elements); } catch (\TypeError $error) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $error); } }
/** * Lex a value with the mask "@X" where X is a valid possible reference * * {@inheritdoc} * * @throws LexException */ public function lex(string $value) : array { foreach (self::PATTERNS as $pattern => $tokenTypeConstant) { if (1 === preg_match($pattern, $value, $matches)) { if (null === $tokenTypeConstant) { throw InvalidArgumentExceptionFactory::createForInvalidExpressionLanguageToken($value); } return [new Token($matches[0], new TokenType($tokenTypeConstant))]; } } throw ExpressionLanguageExceptionFactory::createForCouldNotLexValue($value); }
/** * Parses tokens values like "@user->username". * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : FixturePropertyValue { parent::parse($token); $explodedValue = explode('->', $token->getValue()); if (count($explodedValue) !== 2) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $reference = $this->parser->parse($explodedValue[0]); if (false === $reference instanceof ValueInterface) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } return new FixturePropertyValue($reference, $explodedValue[1]); }
/** * Parses tokens values like "@user->getUserName()". * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : FixtureMethodCallValue { parent::parse($token); $explodedValue = explode('->', $token->getValue()); if (count($explodedValue) !== 2) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $reference = $this->parser->parse($explodedValue[0]); $method = $this->parser->parse(sprintf('<%s>', $explodedValue[1])); if ($reference instanceof FixtureReferenceValue && $method instanceof FunctionCallValue) { return new FixtureMethodCallValue($reference, $method); } throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); }
/** * @param Token $token * * @throws ParseException * * @return string[] * * @example * "@user_{alice, bob}" => ['user_alice', 'user_bob'] */ private function buildReferences(Token $token) : array { $matches = []; $name = (string) substr($token->getValue(), 1); if (1 !== preg_match(self::REGEX, $name, $matches)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $listElements = preg_split('/\\s*,\\s*/', $matches['list']); $references = []; foreach ($listElements as $element) { $fixtureId = str_replace(sprintf('{%s}', $matches['list']), $element, $name); $references[] = new FixtureReferenceValue($fixtureId); } return $references; }
/** * Parses expressions such as "@username->getName()". * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) { parent::parse($token); $values = preg_split('/->/', $token->getValue()); if (2 !== count($values)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $fixture = $this->parser->parse($values[0]); $method = $this->parser->parse(sprintf('<%s>', $values[1])); try { return new FixtureMethodCallValue($fixture, $method); } catch (\TypeError $exception) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $exception); } }
/** * @param LexerInterface $referenceLexer * @param string $valueFragment * * @throws LexException * * @return Token[] */ private function lexFragment(LexerInterface $referenceLexer, string $valueFragment) : array { foreach (self::PATTERNS as $pattern => $tokenTypeConstant) { if (1 === preg_match($pattern, $valueFragment, $matches)) { if (null === $tokenTypeConstant) { throw InvalidArgumentExceptionFactory::createForInvalidExpressionLanguageToken($valueFragment); } $match = $matches[1]; if (self::REFERENCE_LEXER === $tokenTypeConstant) { return $referenceLexer->lex($match); } return [new Token($match, new TokenType($tokenTypeConstant))]; } } throw ExpressionLanguageExceptionFactory::createForCouldNotLexValue($valueFragment); }
/** * Parses expressions such as '<foo()>', '<foo(arg1, arg2)>'. * * {@inheritdoc} * * @throws ParseException */ public function parse(Token $token) : FunctionCallValue { parent::parse($token); if (1 !== preg_match(self::REGEX, $token->getValue(), $matches)) { throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token); } $function = $matches['function']; if ('identity' === $function) { $arguments = [new EvaluatedValue($matches['arguments'])]; } elseif ('current' === $function) { $arguments = [new ValueForCurrentValue()]; } else { $arguments = $this->parseArguments($this->parser, trim($matches['arguments'])); } return new FunctionCallValue($function, $arguments); }
/** * Handle cases like '<f()> <g()>' by trying to break down the token. * * {@inheritdoc} * * @throws LexException * @TODO: handle redundant ListValue tokens * * @return FunctionCallValue|ListValue */ public function parse(Token $token) { parent::parse($token); $split = preg_split(self::REGEX, $token->getValue(), 2, PREG_SPLIT_DELIM_CAPTURE + PREG_SPLIT_NO_EMPTY); $splitSize = count($split); if (1 === $splitSize) { return $this->functionTokenParser->parse($token); } if (3 !== count($split) && 4 !== count($split)) { throw ExpressionLanguageExceptionFactory::createForCouldNotLexValue($token->getValue()); } $values = [$this->parser->parse($split[0] . $split[1])]; if (3 === $splitSize) { $values[] = $this->parser->parse('<' . $split[2]); } if (4 === $splitSize) { $values[] = $this->parser->parse($split[2]); $values[] = $this->parser->parse('<' . $split[3]); } return $this->mergeValues($values); }
/** * Regroup tokens together by detecting when the function starts, closes or when it is nested. * * @param string $originalValue * @param array $tokens * * @return array */ private function buildTree(string $originalValue, array $tokens) : array { $tree = []; $functions = []; foreach ($tokens as $key => $value) { if ($this->tokenizer->isOpeningToken($value)) { $functions[$key] = null; // The value here is ignored continue; } if ($this->tokenizer->isClosingToken($value)) { if (false === $this->tokenizer->isTheLastFunction($functions)) { end($functions); $lastFunctionKey = key($functions); if (null === $lastFunctionKey) { throw ExpressionLanguageExceptionFactory::createForMalformedFunction($originalValue); } unset($functions[$lastFunctionKey]); continue; } end($functions); $lastFunctionKey = key($functions); $this->append($tree, $tokens, $lastFunctionKey, $key); unset($functions[$lastFunctionKey]); continue; } if ($this->tokenizer->functionIsNotClosed($functions)) { continue; } $tree[] = $value; } if ([] !== $functions) { throw ExpressionLanguageExceptionFactory::createForMalformedFunction($originalValue); } return $tree; }
/** * @inheritdoc */ public function parse(Token $token) { if (null === $this->parser) { throw ExpressionLanguageExceptionFactory::createForExpectedMethodCallOnlyIfHasAParser(__METHOD__); } }