Skip to content

Allow to mark JSON properties & XML nodes as optional #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 2, 2017

Conversation

teklakct
Copy link
Contributor

@teklakct teklakct commented Jul 27, 2017

What has been done

  • added optional expander

useless for scalar matchers

  • allows to mark JSON properties & XML nodes as optional

should resolve #93
optional() expander is also available for ArrayMatcher due to JsonMatcher & XmlMatcher is created using ArrayMatcher. There's no a simple way to exclude optional() expander functionality from ArrayMatcher

  • added test cases for MatcherTest
  • Matcher/Pattern/Pattern now have new method hasExpander(string $expanderName): bool

Other's

Also return type declaration was added for for Pattern inteface.

@teklakct teklakct mentioned this pull request Jul 27, 2017
return array_filter($notExistingKeys, function ($pattern) use ($values) {
try {
$typePattern = $this->parser->parse($pattern);
} catch (\Exception $e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not catch generic exception

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. What do you think about Coduo\PHPMatcher\Exception\Exception? When parsing pattern there could be thrown a UnknownExpanderException or UnknownExpanderException so we should catch them all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catching Coduo\PHPMatcher\Exception\Exception sounds good

public function hasExpander(string $expanderName)
{
foreach ($this->expanders as $expander) {
if (!$this->expanderInitializer->hasExpanderDefinition($expanderName)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, why do we need to use expanderInitializer? Can't we check if expander deos not exists in $this->expanders field?

Copy link
Contributor Author

@teklakct teklakct Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid not. Until hasExpander checks if expander exist using its name (simple string - key in $expanderDefinitions list) but in $this->expanders there is a expander instances. I think using expnaderInitializer is better than using some kind of regexp to check if the class name matches with $expanderName. These also should be some rules name new expanders.

I have tried, without success, not to used expanderInitializer. Do you have a better idea?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case I would rather like to expose expanderName from expander instance than inject expander initializer here

Copy link
Contributor Author

@teklakct teklakct Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ok, I'll try with that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any easiest way to expand expander name than add getName to expander interface PatternExpander::getName()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding getName sounds good

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or you can add PatternExpander::is($name) instead of getName - that should fit better in this case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we use constants for expander name , there is no need to use getName neither is($name) I'll revert changes to PatternExpander interface

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is because constant can't be a part of interface. Please add both is($name) and the constant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case, I propose to I add abstract Expander class with is($name). What do you think about that? Are there any disadvantages to using abstract expander?

@@ -179,9 +180,13 @@ private function findNotExistingKeys($pattern, $values)
$notExistingKeys = array_diff_key($pattern, $values);

return array_filter($notExistingKeys, function ($pattern) use ($values) {
if (is_array($pattern)) {
return !$this->match($values, $pattern);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@norzechowicz I'm not pretty sure that we must check if values match to pattern because it already hasn't array_diff_key($pattern, $values) and also because OptionalExpander works only with top level match

*/
public function getName()
{
return 'inArray';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please make constant from those names? For example:

InArray::NAME

This should allow to use constants here https://github.com/coduo/php-matcher/blob/master/src/Parser/ExpanderInitializer.php#L18

You can also replace "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\StartsWith" with StartsWith::class

@@ -82,7 +82,7 @@ public function getError()
public function hasExpander(string $expanderName)
{
foreach ($this->expanders as $expander) {
if ($expander->getName() === $expanderName) {
if ($expander::NAME === $expanderName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the problem, interface can't guarantee that Expander will have NAME constant. Please add is($name) method as I suggested in my previous comment

@teklakct
Copy link
Contributor Author

teklakct commented Aug 2, 2017

@norzechowicz is this is what you mean?

@norberttech norberttech merged commit 8cfa24b into coduo:master Aug 2, 2017
@teklakct teklakct deleted the feature/optional-expander branch August 2, 2017 17:28
norberttech pushed a commit that referenced this pull request Sep 2, 2017
* Add optional expander definition

* Add hasExpander method for Pattern

* Allow mark JSON properties & xml nodes as optional

* Use intuitive matcher type definition in Xml test stock qty node definition

* Add information about optional Expander to README

* Remove return type declaration

* Catch PHPMatcher Exception when parsing pattern for optional values

* Add getName to PatternExpander interface

* Remove unncessary ExpanderInitializer dependency in TypePattern

* Use constants for expander name instead of method

* Redeclare $expanderDefinitions using constants

* Add static is($name) method to PatternExpander interface
norberttech added a commit that referenced this pull request Sep 4, 2017
* Allow to mark JSON properties & XML nodes as optional (#102)

* Add optional expander definition

* Add hasExpander method for Pattern

* Allow mark JSON properties & xml nodes as optional

* Use intuitive matcher type definition in Xml test stock qty node definition

* Add information about optional Expander to README

* Remove return type declaration

* Catch PHPMatcher Exception when parsing pattern for optional values

* Add getName to PatternExpander interface

* Remove unncessary ExpanderInitializer dependency in TypePattern

* Use constants for expander name instead of method

* Redeclare $expanderDefinitions using constants

* Add static is($name) method to PatternExpander interface

* revert php 7.0 feature

* drop php 5.3, 5.4 support

* Use proper test case base class

* Use proper test case base class

* Fixed has expander method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optional JSON fields
2 participants