From aa511a28105784d851546aa1aaa9014f9649e6ff Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Sun, 15 Jan 2023 18:57:26 +0100 Subject: [PATCH 1/7] [Tests] New iteration of removing `$this` occurrences in future static data providers --- Tests/PropertyAccessorArrayAccessTest.php | 16 ++++++++-------- Tests/PropertyAccessorArrayObjectTest.php | 2 +- Tests/PropertyAccessorArrayTest.php | 2 +- ...ertyAccessorNonTraversableArrayObjectTest.php | 2 +- ...ropertyAccessorTraversableArrayObjectTest.php | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Tests/PropertyAccessorArrayAccessTest.php b/Tests/PropertyAccessorArrayAccessTest.php index 98d6eb57..89f89280 100644 --- a/Tests/PropertyAccessorArrayAccessTest.php +++ b/Tests/PropertyAccessorArrayAccessTest.php @@ -28,21 +28,21 @@ protected function setUp(): void $this->propertyAccessor = new PropertyAccessor(); } - abstract protected function getContainer(array $array); + abstract protected static function getContainer(array $array); - public function getValidPropertyPaths() + public static function getValidPropertyPaths(): array { return [ - [$this->getContainer(['firstName' => 'Bernhard']), '[firstName]', 'Bernhard'], - [$this->getContainer(['person' => $this->getContainer(['firstName' => 'Bernhard'])]), '[person][firstName]', 'Bernhard'], + [static::getContainer(['firstName' => 'Bernhard']), '[firstName]', 'Bernhard'], + [static::getContainer(['person' => static::getContainer(['firstName' => 'Bernhard'])]), '[person][firstName]', 'Bernhard'], ]; } - public function getInvalidPropertyPaths() + public static function getInvalidPropertyPaths(): array { return [ - [$this->getContainer(['firstName' => 'Bernhard']), 'firstName', 'Bernhard'], - [$this->getContainer(['person' => $this->getContainer(['firstName' => 'Bernhard'])]), 'person.firstName', 'Bernhard'], + [static::getContainer(['firstName' => 'Bernhard']), 'firstName', 'Bernhard'], + [static::getContainer(['person' => static::getContainer(['firstName' => 'Bernhard'])]), 'person.firstName', 'Bernhard'], ]; } @@ -61,7 +61,7 @@ public function testGetValueFailsIfNoSuchIndex() ->enableExceptionOnInvalidIndex() ->getPropertyAccessor(); - $object = $this->getContainer(['firstName' => 'Bernhard']); + $object = static::getContainer(['firstName' => 'Bernhard']); $this->propertyAccessor->getValue($object, '[lastName]'); } diff --git a/Tests/PropertyAccessorArrayObjectTest.php b/Tests/PropertyAccessorArrayObjectTest.php index fb0b3837..83858956 100644 --- a/Tests/PropertyAccessorArrayObjectTest.php +++ b/Tests/PropertyAccessorArrayObjectTest.php @@ -13,7 +13,7 @@ class PropertyAccessorArrayObjectTest extends PropertyAccessorCollectionTest { - protected function getContainer(array $array) + protected static function getContainer(array $array) { return new \ArrayObject($array); } diff --git a/Tests/PropertyAccessorArrayTest.php b/Tests/PropertyAccessorArrayTest.php index c9828263..16a283d3 100644 --- a/Tests/PropertyAccessorArrayTest.php +++ b/Tests/PropertyAccessorArrayTest.php @@ -13,7 +13,7 @@ class PropertyAccessorArrayTest extends PropertyAccessorCollectionTest { - protected function getContainer(array $array) + protected static function getContainer(array $array) { return $array; } diff --git a/Tests/PropertyAccessorNonTraversableArrayObjectTest.php b/Tests/PropertyAccessorNonTraversableArrayObjectTest.php index 6910d8be..96fb72c7 100644 --- a/Tests/PropertyAccessorNonTraversableArrayObjectTest.php +++ b/Tests/PropertyAccessorNonTraversableArrayObjectTest.php @@ -15,7 +15,7 @@ class PropertyAccessorNonTraversableArrayObjectTest extends PropertyAccessorArrayAccessTest { - protected function getContainer(array $array) + protected static function getContainer(array $array) { return new NonTraversableArrayObject($array); } diff --git a/Tests/PropertyAccessorTraversableArrayObjectTest.php b/Tests/PropertyAccessorTraversableArrayObjectTest.php index 4e450011..4fdcb191 100644 --- a/Tests/PropertyAccessorTraversableArrayObjectTest.php +++ b/Tests/PropertyAccessorTraversableArrayObjectTest.php @@ -15,7 +15,7 @@ class PropertyAccessorTraversableArrayObjectTest extends PropertyAccessorCollectionTest { - protected function getContainer(array $array) + protected static function getContainer(array $array) { return new TraversableArrayObject($array); } From 8d69f964530e2035bc34e0f3a4f242d058518a22 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Jan 2023 15:02:24 +0100 Subject: [PATCH 2/7] Update license years (last time) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 00837045..0138f8f0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2023 Fabien Potencier +Copyright (c) 2004-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 64165df1fa9f596774bdb5d95d44948b1c5c4cfb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 7 Feb 2023 10:31:13 +0100 Subject: [PATCH 3/7] minor #49253 [PHPUnit 10] Use `TestCase` suffix for abstract tests in `/Tests/` (OskarStark) This PR was merged into the 6.3 branch. Discussion ---------- [PHPUnit 10] Use `TestCase` suffix for abstract tests in `/Tests/` | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | Refs https://github.com/symfony/symfony/pull/49233 | License | MIT | Doc PR | n/a Replaces #49234 Using `Test` suffix is deprecated since PHPUnit 10 Spotted in * https://github.com/symfony/symfony/pull/49233 Commits ------- cb3db968e4 [PHPUnit 10] Use `TestCase` suffix for abstract tests in `/Tests/` --- ...> PropertyAccessorArrayAccessTestCase.php} | 2 +- Tests/PropertyAccessorArrayObjectTest.php | 2 +- Tests/PropertyAccessorArrayTest.php | 2 +- ...=> PropertyAccessorCollectionTestCase.php} | 30 +++++++++---------- ...yAccessorNonTraversableArrayObjectTest.php | 2 +- ...ertyAccessorTraversableArrayObjectTest.php | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) rename Tests/{PropertyAccessorArrayAccessTest.php => PropertyAccessorArrayAccessTestCase.php} (97%) rename Tests/{PropertyAccessorCollectionTest.php => PropertyAccessorCollectionTestCase.php} (82%) diff --git a/Tests/PropertyAccessorArrayAccessTest.php b/Tests/PropertyAccessorArrayAccessTestCase.php similarity index 97% rename from Tests/PropertyAccessorArrayAccessTest.php rename to Tests/PropertyAccessorArrayAccessTestCase.php index 89f89280..b1b3f63d 100644 --- a/Tests/PropertyAccessorArrayAccessTest.php +++ b/Tests/PropertyAccessorArrayAccessTestCase.php @@ -16,7 +16,7 @@ use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessor; -abstract class PropertyAccessorArrayAccessTest extends TestCase +abstract class PropertyAccessorArrayAccessTestCase extends TestCase { /** * @var PropertyAccessor diff --git a/Tests/PropertyAccessorArrayObjectTest.php b/Tests/PropertyAccessorArrayObjectTest.php index 83858956..9d836561 100644 --- a/Tests/PropertyAccessorArrayObjectTest.php +++ b/Tests/PropertyAccessorArrayObjectTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\PropertyAccess\Tests; -class PropertyAccessorArrayObjectTest extends PropertyAccessorCollectionTest +class PropertyAccessorArrayObjectTest extends PropertyAccessorCollectionTestCase { protected static function getContainer(array $array) { diff --git a/Tests/PropertyAccessorArrayTest.php b/Tests/PropertyAccessorArrayTest.php index 16a283d3..304b823e 100644 --- a/Tests/PropertyAccessorArrayTest.php +++ b/Tests/PropertyAccessorArrayTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\PropertyAccess\Tests; -class PropertyAccessorArrayTest extends PropertyAccessorCollectionTest +class PropertyAccessorArrayTest extends PropertyAccessorCollectionTestCase { protected static function getContainer(array $array) { diff --git a/Tests/PropertyAccessorCollectionTest.php b/Tests/PropertyAccessorCollectionTestCase.php similarity index 82% rename from Tests/PropertyAccessorCollectionTest.php rename to Tests/PropertyAccessorCollectionTestCase.php index 2daf260f..016d6942 100644 --- a/Tests/PropertyAccessorCollectionTest.php +++ b/Tests/PropertyAccessorCollectionTestCase.php @@ -13,7 +13,7 @@ use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; -class PropertyAccessorCollectionTest_Car +class PropertyAccessorCollectionTestCase_Car { private $axes; @@ -45,7 +45,7 @@ public function getAxes() } } -class PropertyAccessorCollectionTest_CarOnlyAdder +class PropertyAccessorCollectionTestCase_CarOnlyAdder { public function addAxis($axis) { @@ -56,7 +56,7 @@ public function getAxes() } } -class PropertyAccessorCollectionTest_CarOnlyRemover +class PropertyAccessorCollectionTestCase_CarOnlyRemover { public function removeAxis($axis) { @@ -67,14 +67,14 @@ public function getAxes() } } -class PropertyAccessorCollectionTest_CarNoAdderAndRemover +class PropertyAccessorCollectionTestCase_CarNoAdderAndRemover { public function getAxes() { } } -class PropertyAccessorCollectionTest_CompositeCar +class PropertyAccessorCollectionTestCase_CompositeCar { public function getStructure() { @@ -85,7 +85,7 @@ public function setStructure($structure) } } -class PropertyAccessorCollectionTest_CarStructure +class PropertyAccessorCollectionTestCase_CarStructure { public function addAxis($axis) { @@ -100,7 +100,7 @@ public function getAxes() } } -abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAccessTest +abstract class PropertyAccessorCollectionTestCase extends PropertyAccessorArrayAccessTestCase { public function testSetValueCallsAdderAndRemoverForCollections() { @@ -111,7 +111,7 @@ public function testSetValueCallsAdderAndRemoverForCollections() // Don't use a mock in order to test whether the collections are // modified while iterating them - $car = new PropertyAccessorCollectionTest_Car($axesBefore); + $car = new PropertyAccessorCollectionTestCase_Car($axesBefore); $this->propertyAccessor->setValue($car, 'axes', $axesMerged); @@ -151,7 +151,7 @@ public function testSetValueCallsAdderAndRemoverForNestedCollections() public function testSetValueFailsIfNoAdderNorRemoverFound() { $this->expectException(NoSuchPropertyException::class); - $this->expectExceptionMessageMatches('/Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover_[^"]*"./'); + $this->expectExceptionMessageMatches('/Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTestCase_CarNoAdderAndRemover_[^"]*"./'); $car = $this->createMock(__CLASS__.'_CarNoAdderAndRemover'); $axesBefore = $this->getContainer([1 => 'second', 3 => 'fourth']); $axesAfter = $this->getContainer([0 => 'first', 1 => 'second', 2 => 'third']); @@ -165,33 +165,33 @@ public function testSetValueFailsIfNoAdderNorRemoverFound() public function testIsWritableReturnsTrueIfAdderAndRemoverExists() { - $car = new PropertyAccessorCollectionTest_Car(); + $car = new PropertyAccessorCollectionTestCase_Car(); $this->assertTrue($this->propertyAccessor->isWritable($car, 'axes')); } public function testIsWritableReturnsFalseIfOnlyAdderExists() { - $car = new PropertyAccessorCollectionTest_CarOnlyAdder(); + $car = new PropertyAccessorCollectionTestCase_CarOnlyAdder(); $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes')); } public function testIsWritableReturnsFalseIfOnlyRemoverExists() { - $car = new PropertyAccessorCollectionTest_CarOnlyRemover(); + $car = new PropertyAccessorCollectionTestCase_CarOnlyRemover(); $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes')); } public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists() { - $car = new PropertyAccessorCollectionTest_CarNoAdderAndRemover(); + $car = new PropertyAccessorCollectionTestCase_CarNoAdderAndRemover(); $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes')); } public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable() { $this->expectException(NoSuchPropertyException::class); - $this->expectExceptionMessageMatches('/The property "axes" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\PropertyAccessorCollectionTest_Car" can be defined with the methods "addAxis\(\)", "removeAxis\(\)" but the new value must be an array or an instance of \\\Traversable\./'); - $car = new PropertyAccessorCollectionTest_Car(); + $this->expectExceptionMessageMatches('/The property "axes" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\PropertyAccessorCollectionTestCase_Car" can be defined with the methods "addAxis\(\)", "removeAxis\(\)" but the new value must be an array or an instance of \\\Traversable\./'); + $car = new PropertyAccessorCollectionTestCase_Car(); $this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable'); } diff --git a/Tests/PropertyAccessorNonTraversableArrayObjectTest.php b/Tests/PropertyAccessorNonTraversableArrayObjectTest.php index 96fb72c7..5c01079e 100644 --- a/Tests/PropertyAccessorNonTraversableArrayObjectTest.php +++ b/Tests/PropertyAccessorNonTraversableArrayObjectTest.php @@ -13,7 +13,7 @@ use Symfony\Component\PropertyAccess\Tests\Fixtures\NonTraversableArrayObject; -class PropertyAccessorNonTraversableArrayObjectTest extends PropertyAccessorArrayAccessTest +class PropertyAccessorNonTraversableArrayObjectTest extends PropertyAccessorArrayAccessTestCase { protected static function getContainer(array $array) { diff --git a/Tests/PropertyAccessorTraversableArrayObjectTest.php b/Tests/PropertyAccessorTraversableArrayObjectTest.php index 4fdcb191..bfd52fab 100644 --- a/Tests/PropertyAccessorTraversableArrayObjectTest.php +++ b/Tests/PropertyAccessorTraversableArrayObjectTest.php @@ -13,7 +13,7 @@ use Symfony\Component\PropertyAccess\Tests\Fixtures\TraversableArrayObject; -class PropertyAccessorTraversableArrayObjectTest extends PropertyAccessorCollectionTest +class PropertyAccessorTraversableArrayObjectTest extends PropertyAccessorCollectionTestCase { protected static function getContainer(array $array) { From 019a5ff0ce56b66e629958681570147234a4ac84 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 14 Dec 2022 15:42:16 +0100 Subject: [PATCH 4/7] Migrate to `static` data providers using `rector/rector` --- Tests/PropertyAccessorTest.php | 12 ++++++------ Tests/PropertyPathBuilderTest.php | 2 +- Tests/PropertyPathTest.php | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/PropertyAccessorTest.php b/Tests/PropertyAccessorTest.php index 46ecfcca..b5fbf23f 100644 --- a/Tests/PropertyAccessorTest.php +++ b/Tests/PropertyAccessorTest.php @@ -55,7 +55,7 @@ protected function setUp(): void $this->propertyAccessor = new PropertyAccessor(); } - public function getPathsWithUnexpectedType() + public static function getPathsWithUnexpectedType() { return [ ['', 'foobar'], @@ -69,7 +69,7 @@ public function getPathsWithUnexpectedType() ]; } - public function getPathsWithMissingProperty() + public static function getPathsWithMissingProperty() { return [ [(object) ['firstName' => 'Bernhard'], 'lastName'], @@ -89,7 +89,7 @@ public function getPathsWithMissingProperty() ]; } - public function getPathsWithMissingIndex() + public static function getPathsWithMissingIndex() { return [ [['firstName' => 'Bernhard'], '[lastName]'], @@ -660,7 +660,7 @@ public function testIsWritableReturnsFalseIfNotObjectOrArray($objectOrArray, $pa $this->assertFalse($this->propertyAccessor->isWritable($objectOrArray, $path)); } - public function getValidPropertyPaths() + public static function getValidPropertyPaths() { return [ [['Bernhard', 'Schussek'], '[0]', 'Bernhard'], @@ -723,7 +723,7 @@ public function testSetValueDeepWithMagicGetter() $this->assertSame('Updated', $obj->publicProperty['foo']['bar']); } - public function getReferenceChainObjectsForSetValue() + public static function getReferenceChainObjectsForSetValue() { return [ [['a' => ['b' => ['c' => 'old-value']]], '[a][b][c]', 'new-value'], @@ -744,7 +744,7 @@ public function testSetValueForReferenceChainIssue($object, $path, $value) $this->assertEquals($value, $this->propertyAccessor->getValue($object, $path)); } - public function getReferenceChainObjectsForIsWritable() + public static function getReferenceChainObjectsForIsWritable() { return [ [new TestClassIsWritable(['a' => ['b' => 'old-value']]), 'value[a][b]', false], diff --git a/Tests/PropertyPathBuilderTest.php b/Tests/PropertyPathBuilderTest.php index e26ed62e..5f467129 100644 --- a/Tests/PropertyPathBuilderTest.php +++ b/Tests/PropertyPathBuilderTest.php @@ -194,7 +194,7 @@ public function testReplaceDoesNotAllowInvalidOffsets($offset) $this->builder->replace($offset, 1, new PropertyPath('new1[new2].new3')); } - public function provideInvalidOffsets() + public static function provideInvalidOffsets() { return [ [6], diff --git a/Tests/PropertyPathTest.php b/Tests/PropertyPathTest.php index 87967373..88464d23 100644 --- a/Tests/PropertyPathTest.php +++ b/Tests/PropertyPathTest.php @@ -37,7 +37,7 @@ public function testDotCannotBePresentAtTheBeginning() new PropertyPath('.property'); } - public function providePathsContainingUnexpectedCharacters() + public static function providePathsContainingUnexpectedCharacters() { return [ ['property.'], From bbd4442bfbdf3992550772539ba743d6d834534f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 16 Feb 2023 10:33:00 +0100 Subject: [PATCH 5/7] CS fix --- Tests/PropertyAccessorTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/PropertyAccessorTest.php b/Tests/PropertyAccessorTest.php index b5fbf23f..5f1b51e5 100644 --- a/Tests/PropertyAccessorTest.php +++ b/Tests/PropertyAccessorTest.php @@ -129,6 +129,7 @@ public function testGetValueReturnsNullIfPropertyNotFoundAndExceptionIsDisabled( /** * @group legacy + * * @dataProvider getPathsWithMissingProperty */ public function testGetValueReturnsNullIfPropertyNotFoundAndExceptionIsDisabledUsingBooleanArgument($objectOrArray, $path) @@ -160,6 +161,7 @@ public function testGetValueThrowsExceptionIfIndexNotFoundAndIndexExceptionsEnab /** * @group legacy + * * @dataProvider getPathsWithMissingIndex */ public function testGetValueThrowsExceptionIfIndexNotFoundAndIndexExceptionsEnabledUsingBooleanArgument($objectOrArray, $path) @@ -357,6 +359,7 @@ public function testGetValueDoesNotReadMagicCallByDefault() /** * @group legacy + * * @expectedDeprecation Since symfony/property-access 5.2: Passing a boolean as the first argument to "Symfony\Component\PropertyAccess\PropertyAccessor::__construct()" is deprecated. Pass a combination of bitwise flags instead (i.e an integer). */ public function testLegacyGetValueReadsMagicCallIfEnabled() @@ -476,6 +479,7 @@ public function testSetValueDoesNotUpdateMagicCallByDefault() /** * @group legacy + * * @expectedDeprecation Since symfony/property-access 5.2: Passing a boolean as the first argument to "Symfony\Component\PropertyAccess\PropertyAccessor::__construct()" is deprecated. Pass a combination of bitwise flags instead (i.e an integer). */ public function testLegacySetValueUpdatesMagicCallIfEnabled() @@ -564,6 +568,7 @@ public function testIsReadableDoesNotRecognizeMagicCallByDefault() /** * @group legacy + * * @expectedDeprecation Since symfony/property-access 5.2: Passing a boolean as the first argument to "Symfony\Component\PropertyAccess\PropertyAccessor::__construct()" is deprecated. Pass a combination of bitwise flags instead (i.e an integer). */ public function testLegacyIsReadableRecognizesMagicCallIfEnabled() @@ -636,6 +641,7 @@ public function testIsWritableDoesNotRecognizeMagicCallByDefault() /** * @group legacy + * * @expectedDeprecation Since symfony/property-access 5.2: Passing a boolean as the first argument to "Symfony\Component\PropertyAccess\PropertyAccessor::__construct()" is deprecated. Pass a combination of bitwise flags instead (i.e an integer). */ public function testLegacyIsWritableRecognizesMagicCallIfEnabled() From 0722fdf6f2f699a57c114db780bd3e1d38022eb7 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 6 Mar 2023 20:42:33 +0100 Subject: [PATCH 6/7] [Tests] Remove occurrences of `withConsecutive()` --- Tests/PropertyAccessorCollectionTestCase.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Tests/PropertyAccessorCollectionTestCase.php b/Tests/PropertyAccessorCollectionTestCase.php index 016d6942..742889ad 100644 --- a/Tests/PropertyAccessorCollectionTestCase.php +++ b/Tests/PropertyAccessorCollectionTestCase.php @@ -138,12 +138,18 @@ public function testSetValueCallsAdderAndRemoverForNestedCollections() $structure->expects($this->once()) ->method('removeAxis') ->with('fourth'); + $structure->expects($this->exactly(2)) ->method('addAxis') - ->withConsecutive( - ['first'], - ['third'] - ); + ->willReturnCallback(function (string $axis) { + static $series = [ + 'first', + 'third', + ]; + + $this->assertSame(array_shift($series), $axis); + }) + ; $this->propertyAccessor->setValue($car, 'structure.axes', $axesAfter); } From ffee082889586b5718347b291e04071f4d07b38f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 14 Mar 2023 15:59:20 +0100 Subject: [PATCH 7/7] Fix some Composer keywords --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fb6103a5..b797151a 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "symfony/property-access", "type": "library", "description": "Provides functions to read and write from/to an object or array using a simple string notation", - "keywords": ["property", "index", "access", "object", "array", "extraction", "injection", "reflection", "property path"], + "keywords": ["property", "index", "access", "object", "array", "extraction", "injection", "reflection", "property-path"], "homepage": "https://symfony.com", "license": "MIT", "authors": [