diff --git a/src/Type/Definition/IDType.php b/src/Type/Definition/IDType.php index 1e3deb5..5912973 100644 --- a/src/Type/Definition/IDType.php +++ b/src/Type/Definition/IDType.php @@ -43,7 +43,7 @@ When expected as an input type, any string (such as `"4"`) or integer if ($value === null) { return 'null'; } - if (!is_scalar($value)) { + if (!is_scalar($value) && (!is_object($value) || !method_exists($value, '__toString'))) { throw new InvariantViolation("ID type cannot represent non scalar value: " . Utils::printSafe($value)); } return (string) $value; diff --git a/tests/Type/ObjectIdStub.php b/tests/Type/ObjectIdStub.php new file mode 100644 index 0000000..5379591 --- /dev/null +++ b/tests/Type/ObjectIdStub.php @@ -0,0 +1,23 @@ +id = $id; + } + + public function __toString() + { + return (string) $this->id; + } +} diff --git a/tests/Type/ScalarSerializationTest.php b/tests/Type/ScalarSerializationTest.php index d554ccf..edebcad 100644 --- a/tests/Type/ScalarSerializationTest.php +++ b/tests/Type/ScalarSerializationTest.php @@ -178,4 +178,25 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase // TODO: how should it behave on '0'? } + + public function testSerializesOutputID() + { + $idType = Type::id(); + + $this->assertSame('string', $idType->serialize('string')); + $this->assertSame('', $idType->serialize('')); + $this->assertSame('1', $idType->serialize('1')); + $this->assertSame('1', $idType->serialize(1)); + $this->assertSame('0', $idType->serialize(0)); + $this->assertSame('true', $idType->serialize(true)); + $this->assertSame('false', $idType->serialize(false)); + $this->assertSame('2', $idType->serialize(new ObjectIdStub(2))); + + try { + $idType->serialize(new \stdClass()); + $this->fail('Expected exception was not thrown'); + } catch (InvariantViolation $e) { + $this->assertEquals('ID type cannot represent non scalar value: instance of stdClass', $e->getMessage()); + } + } }