PK &|OmZ^] ] example/single.jsonnu W+A {"name":"Sheldon Cooper","address":{"street":"2311 N. Los Robles Avenue","city":"Pasadena"}}
PK &|Omڒ example/run.phpnu W+A map($json, new Contact());
$coords = $contact->address->getGeoCoords();
echo $contact->name . ' lives at coordinates '
. $coords['lat'] . ',' . $coords['lon'] . "\n";
?>PK &|O4G example/Address.phpnu W+A street)
. ',' . urlencode($this->city)
. '&format=json&addressdetails=1'
);
$json = json_decode($data);
return array(
'lat' => $json[0]->lat,
'lon' => $json[0]->lon
);
}
}
?>
PK &|OlE{ g g example/Contact.phpnu W+A
PK &|OCI .travis.ymlnu W+A language: php
sudo: false
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7
- hhvm
before_script:
- composer install --no-interaction --prefer-source --dev
- phpenv rehash
script:
- cd tests
- phpunit --coverage-text .
- cd ..
- ./vendor/bin/phpcs --standard=PEAR src/
PK &|O^/ / package.xmlnu W+A
JsonMapperzustellzentrum.cweiske.deMap nested JSON structures onto PHP classesMap nested JSON structures onto PHP classesChristian Weiskecweiskecweiske@cweiske.deyes2016-10-111.0.01.0.0stablestableOSL-3.0
* Add option to turn off the "must not be NULL" exception
* Add support for properties with hyphens "-"
* Add support for both "double" and "float" types
* Move to PEAR channel zustellzentrum.cweiske.de
5.3.01.9.11.0.01.0.0stablestable2016-10-11OSL-3.0
* Add option to turn off the "must not be NULL" exception
by @ kamranahmedse (issue #58)
* Add support for properties with hyphens "-" by @redshark1802 (issue #55)
* Add support for both "double" and "float" types
* Move to PEAR channel zustellzentrum.cweiske.de
0.11.00.11.0betabeta2016-04-14OSL-3.0
* Add $undefinedPropertyHandler (issue #51)
* Add $classMap to override class names (issue #53)
* Add option to enable strict object type checks (issue #50)
* Add composer autoloader performance improvement
* Add exception when an array is expected, but simple type given
(issue #44)
* Fix non-nullable object handling: Exception is now thrown when
NULL is given and an object was expected.
THIS WILL PROBABLY BREAK YOUR CODE
Add "|null" to all your "@var ClassName" lines to fix that.
0.10.00.10.0betabeta2015-09-24OSL-3.0
* Add dependency injection support (issue #42)
* Fix casting of arrays of simple types
0.9.00.9.0alphaalpha2015-08-14OSL-3.0
* Add case-insensitive property matching (issue #40)
* Add option to disable map() parameter type enforcement (issue #37)
0.8.00.8.0alphaalpha2015-07-06OSL-3.0
* Add support for seting objects directly if they have the correct type already by @radmen
* Throw exception when a non-object is passed to map()
0.7.00.7.0alphaalpha2015-06-19OSL-3.0
* Support "mixed" variable type (issue #33)
0.6.10.6.0alphaalpha2015-05-28OSL-3.0
* Fix namespace error with setter type hints
0.6.00.6.0alphaalpha2015-04-09OSL-3.0
* Prefer setter methods over directy property access
* Change setter method name calculation for properties
with _ underscores by @msankhala
0.5.00.3.0alphaalpha2015-03-18OSL-3.0
* Add support for nullable types (int|null) by @barryvdh
* Increase test coverage to 100%
* Fix float value detection by @sonicgd
0.4.40.3.0alphaalpha2015-01-08OSL-3.0
* Fix bug #23: handle empty variable types
* Fix bug #24: Namespaced ArrayObject class with namespaced value type does not work
0.4.30.3.0alphaalpha2014-12-17OSL-3.0
* Change license from AGPL 3.0 to OSL 3.0
0.4.20.3.0alphaalpha2014-12-05AGPL
* Fix array mapping when value is NULL by @darkgaro
0.4.10.3.0alphaalpha2014-11-04AGPL
* Fix handling of private properties with public setters
* Fix handling of simple array types in namespaced files
0.4.00.3.0alphaalpha2014-08-20AGPL
* Incorporate performance tweaks from @Jalle19
0.3.00.3.0alphaalpha2014-06-11AGPL
* Optional exceptions for missing or undefined data
0.2.10.2.0alphaalpha2014-05-16AGPL
* Handle NULL values when mapping simple data types onto objects
0.2.00.2.0alphaalpha2014-05-15AGPL
* Add support for mapping simple data types onto objects
* Fix tests on phpunit 4.x
0.1.30.1.0alphaalpha2014-03-17AGPL
* Prevent autoloading classes with ] in its name
0.1.20.1.0alphaalpha2014-02-03AGPL
* Fix issue #2: Namespace is prepended two times
* Fix issue #1: Remove declare(encoding="UTF-8") calls
0.1.10.1.0alphaalpha2014-01-28AGPL
Properly resolve namespace for array subtypes
0.1.00.1.0alphaalpha2014-01-28AGPL
First release
PK &|O$qB B
.gitignorenu W+A /README.html
/*.tgz
/dist/
/vendor/
.buildpath
.project
.settings
PK &|Oi" src/JsonMapper/Exception.phpnu W+A
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
/**
* Simple exception
*
* @category Netresearch
* @package JsonMapper
* @author Christian Weiske
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
class JsonMapper_Exception extends Exception
{
}
?>
PK &|O^U U src/JsonMapper.phpnu W+A
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
/**
* Automatically map JSON structures into objects.
*
* @category Netresearch
* @package JsonMapper
* @author Christian Weiske
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
class JsonMapper
{
/**
* PSR-3 compatible logger object
*
* @link http://www.php-fig.org/psr/psr-3/
* @var object
* @see setLogger()
*/
protected $logger;
/**
* Throw an exception when JSON data contain a property
* that is not defined in the PHP class
*
* @var boolean
*/
public $bExceptionOnUndefinedProperty = false;
/**
* Throw an exception if the JSON data miss a property
* that is marked with @required in the PHP class
*
* @var boolean
*/
public $bExceptionOnMissingData = false;
/**
* If the types of map() parameters shall be checked.
*
* You have to disable it if you're using the json_decode "assoc" parameter.
*
* json_decode($str, false)
*
* @var boolean
*/
public $bEnforceMapType = true;
/**
* Throw an exception when an object is expected but the JSON contains
* a non-object type.
*
* @var boolean
*/
public $bStrictObjectTypeChecking = false;
/**
* Throw an exception, if null value is found
* but the type of attribute does not allow nulls.
*
* @var bool
*/
public $bStrictNullTypes = true;
/**
* Override class names that JsonMapper uses to create objects.
* Useful when your setter methods accept abstract classes or interfaces.
*
* Works only when $bExceptionOnUndefinedProperty is disabled.
*
* Parameters to this function are:
* 1. Object that is being filled
* 2. Name of the unknown JSON property
* 3. JSON value of the property
*
* @var array
*/
public $classMap = array();
/**
* Callback used when an undefined property is found.
*
* @var callable
*/
public $undefinedPropertyHandler = null;
/**
* Runtime cache for inspected classes. This is particularly effective if
* mapArray() is called with a large number of objects
*
* @var array property inspection result cache
*/
protected $arInspectedClasses = array();
/**
* Map data all data in $json into the given $object instance.
*
* @param object $json JSON object structure from json_decode()
* @param object $object Object to map $json data into
*
* @return object Mapped object is returned.
* @see mapArray()
*/
public function map($json, $object)
{
if ($this->bEnforceMapType && !is_object($json)) {
throw new InvalidArgumentException(
'JsonMapper::map() requires first argument to be an object'
. ', ' . gettype($json) . ' given.'
);
}
if (!is_object($object)) {
throw new InvalidArgumentException(
'JsonMapper::map() requires second argument to be an object'
. ', ' . gettype($object) . ' given.'
);
}
$strClassName = get_class($object);
$rc = new ReflectionClass($object);
$strNs = $rc->getNamespaceName();
$providedProperties = array();
foreach ($json as $key => $jvalue) {
$key = $this->getSafeName($key);
$providedProperties[$key] = true;
// Store the property inspection results so we don't have to do it
// again for subsequent objects of the same type
if (!isset($this->arInspectedClasses[$strClassName][$key])) {
$this->arInspectedClasses[$strClassName][$key]
= $this->inspectProperty($rc, $key);
}
list($hasProperty, $accessor, $type)
= $this->arInspectedClasses[$strClassName][$key];
if (!$hasProperty) {
if ($this->bExceptionOnUndefinedProperty) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" does not exist'
. ' in object of type ' . $strClassName
);
} else if ($this->undefinedPropertyHandler !== null) {
call_user_func(
$this->undefinedPropertyHandler,
$object, $key, $jvalue
);
} else {
$this->log(
'info',
'Property {property} does not exist in {class}',
array('property' => $key, 'class' => $strClassName)
);
}
continue;
}
if ($accessor === null) {
if ($this->bExceptionOnUndefinedProperty) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" has no public setter method'
. ' in object of type ' . $strClassName
);
}
$this->log(
'info',
'Property {property} has no public setter method in {class}',
array('property' => $key, 'class' => $strClassName)
);
continue;
}
if ($this->isNullable($type) || !$this->bStrictNullTypes) {
if ($jvalue === null) {
$this->setProperty($object, $accessor, null);
continue;
}
$type = $this->removeNullable($type);
} else if ($jvalue === null) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" must not be NULL'
);
}
if ($type === null || $type === 'mixed') {
//no given type - simply set the json data
$this->setProperty($object, $accessor, $jvalue);
continue;
} else if ($this->isObjectOfSameType($type, $jvalue)) {
$this->setProperty($object, $accessor, $jvalue);
continue;
} else if ($this->isSimpleType($type)) {
settype($jvalue, $type);
$this->setProperty($object, $accessor, $jvalue);
continue;
}
//FIXME: check if type exists, give detailled error message if not
if ($type === '') {
throw new JsonMapper_Exception(
'Empty type at property "'
. $strClassName . '::$' . $key . '"'
);
}
$array = null;
$subtype = null;
if (substr($type, -2) == '[]') {
//array
$array = array();
$subtype = substr($type, 0, -2);
} else if (substr($type, -1) == ']') {
list($proptype, $subtype) = explode('[', substr($type, 0, -1));
if (!$this->isSimpleType($proptype)) {
$proptype = $this->getFullNamespace($proptype, $strNs);
}
if ($proptype == 'array') {
$array = array();
} else {
$array = $this->createInstance($proptype);
}
} else if ($type == 'ArrayObject'
|| is_subclass_of($type, 'ArrayObject')
) {
$array = $this->createInstance($type);
}
if ($array !== null) {
if (!is_array($jvalue) && $this->isFlatType(gettype($jvalue))) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" must be an array, '
. gettype($jvalue) . ' given'
);
}
$cleanSubtype = $this->removeNullable($subtype);
if (!$this->isSimpleType($cleanSubtype)) {
$subtype = $this->getFullNamespace($cleanSubtype, $strNs);
}
$child = $this->mapArray($jvalue, $array, $subtype);
} else if ($this->isFlatType(gettype($jvalue))) {
//use constructor parameter if we have a class
// but only a flat type (i.e. string, int)
if ($this->bStrictObjectTypeChecking) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" must be an object, '
. gettype($jvalue) . ' given'
);
}
$type = $this->getFullNamespace($type, $strNs);
$child = $this->createInstance($type, true, $jvalue);
} else {
$type = $this->getFullNamespace($type, $strNs);
$child = $this->createInstance($type);
$this->map($jvalue, $child);
}
$this->setProperty($object, $accessor, $child);
}
if ($this->bExceptionOnMissingData) {
$this->checkMissingData($providedProperties, $rc);
}
return $object;
}
/**
* Convert a type name to a fully namespaced type name.
*
* @param string $type Type name (simple type or class name)
* @param string $strNs Base namespace that gets prepended to the type name
*
* @return string Fully-qualified type name with namespace
*/
protected function getFullNamespace($type, $strNs)
{
if ($type !== '' && $type{0} != '\\') {
//create a full qualified namespace
if ($strNs != '') {
$type = '\\' . $strNs . '\\' . $type;
}
}
return $type;
}
/**
* Check required properties exist in json
*
* @param array $providedProperties array with json properties
* @param object $rc Reflection class to check
*
* @throws JsonMapper_Exception
*
* @return void
*/
protected function checkMissingData($providedProperties, ReflectionClass $rc)
{
foreach ($rc->getProperties() as $property) {
$rprop = $rc->getProperty($property->name);
$docblock = $rprop->getDocComment();
$annotations = $this->parseAnnotations($docblock);
if (isset($annotations['required'])
&& !isset($providedProperties[$property->name])
) {
throw new JsonMapper_Exception(
'Required property "' . $property->name . '" of class '
. $rc->getName()
. ' is missing in JSON data'
);
}
}
}
/**
* Map an array
*
* @param array $json JSON array structure from json_decode()
* @param mixed $array Array or ArrayObject that gets filled with
* data from $json
* @param string $class Class name for children objects.
* All children will get mapped onto this type.
* Supports class names and simple types
* like "string" and nullability "string|null".
* Pass "null" to not convert any values
*
* @return mixed Mapped $array is returned
*/
public function mapArray($json, $array, $class = null)
{
foreach ($json as $key => $jvalue) {
$key = $this->getSafeName($key);
if ($class === null) {
$array[$key] = $jvalue;
} else if ($this->isFlatType(gettype($jvalue))) {
//use constructor parameter if we have a class
// but only a flat type (i.e. string, int)
if ($jvalue === null) {
$array[$key] = null;
} else {
if ($this->isSimpleType($class)) {
settype($jvalue, $class);
$array[$key] = $jvalue;
} else {
$array[$key] = $this->createInstance(
$class, true, $jvalue
);
}
}
} else {
$array[$key] = $this->map(
$jvalue, $this->createInstance($class)
);
}
}
return $array;
}
/**
* Try to find out if a property exists in a given class.
* Checks property first, falls back to setter method.
*
* @param object $rc Reflection class to check
* @param string $name Property name
*
* @return array First value: if the property exists
* Second value: the accessor to use (
* ReflectionMethod or ReflectionProperty, or null)
* Third value: type of the property
*/
protected function inspectProperty(ReflectionClass $rc, $name)
{
//try setter method first
$setter = 'set' . $this->getCamelCaseName($name);
if ($rc->hasMethod($setter)) {
$rmeth = $rc->getMethod($setter);
if ($rmeth->isPublic()) {
$rparams = $rmeth->getParameters();
if (count($rparams) > 0) {
$pclass = $rparams[0]->getClass();
$nullability = '';
if ($rparams[0]->isOptional()) {
if ($rparams[0]->getDefaultValue() === null) {
$nullability = '|null';
}
}
if ($pclass !== null) {
return array(
true, $rmeth,
'\\' . $pclass->getName() . $nullability
);
}
}
$docblock = $rmeth->getDocComment();
$annotations = $this->parseAnnotations($docblock);
if (!isset($annotations['param'][0])) {
return array(true, $rmeth, null);
}
list($type) = explode(' ', trim($annotations['param'][0]));
return array(true, $rmeth, $type);
}
}
//now try to set the property directly
if ($rc->hasProperty($name)) {
$rprop = $rc->getProperty($name);
} else {
//case-insensitive property matching
$rprop = null;
foreach ($rc->getProperties(ReflectionProperty::IS_PUBLIC) as $p) {
if ((strcasecmp($p->name, $name) === 0)) {
$rprop = $p;
break;
}
}
}
if ($rprop !== null) {
if ($rprop->isPublic()) {
$docblock = $rprop->getDocComment();
$annotations = $this->parseAnnotations($docblock);
if (!isset($annotations['var'][0])) {
return array(true, $rprop, null);
}
//support "@var type description"
list($type) = explode(' ', $annotations['var'][0]);
return array(true, $rprop, $type);
} else {
//no setter, private property
return array(true, null, null);
}
}
//no setter, no property
return array(false, null, null);
}
/**
* Removes - and _ and makes the next letter uppercase
*
* @param string $name Property name
*
* @return string CamelCasedVariableName
*/
protected function getCamelCaseName($name)
{
return str_replace(
' ', '', ucwords(str_replace(array('_', '-'), ' ', $name))
);
}
/**
* Since hyphens cannot be used in variables we have to uppercase them.
*
* Technically you may use them, but they are awkward to access.
*
* @param string $name Property name
*
* @return string Name without hyphen
*/
protected function getSafeName($name)
{
if (strpos($name, '-') !== false) {
$name = $this->getCamelCaseName($name);
}
return $name;
}
/**
* Set a property on a given object to a given value.
*
* Checks if the setter or the property are public are made before
* calling this method.
*
* @param object $object Object to set property on
* @param object $accessor ReflectionMethod or ReflectionProperty
* @param mixed $value Value of property
*
* @return void
*/
protected function setProperty(
$object, $accessor, $value
) {
if ($accessor instanceof ReflectionProperty) {
$object->{$accessor->getName()} = $value;
} else {
$object->{$accessor->getName()}($value);
}
}
/**
* Create a new object of the given type.
*
* This method exists to be overwritten in child classes,
* so you can do dependency injection or so.
*
* @param string $class Class name to instantiate
* @param boolean $useParameter Pass $parameter to the constructor or not
* @param mixed $parameter Constructor parameter
*
* @return object Freshly created object
*/
public function createInstance(
$class, $useParameter = false, $parameter = null
) {
if (isset($this->classMap[$class])) {
$class = $this->classMap[$class];
}
if ($useParameter) {
return new $class($parameter);
} else {
return new $class();
}
}
/**
* Checks if the given type is a "simple type"
*
* @param string $type type name from gettype()
*
* @return boolean True if it is a simple PHP type
*
* @see isFlatType()
*/
protected function isSimpleType($type)
{
return $type == 'string'
|| $type == 'boolean' || $type == 'bool'
|| $type == 'integer' || $type == 'int'
|| $type == 'double' || $type == 'float'
|| $type == 'array' || $type == 'object';
}
/**
* Checks if the object is of this type or has this type as one of its parents
*
* @param string $type class name of type being required
* @param mixed $value Some PHP value to be tested
*
* @return boolean True if $object has type of $type
*/
protected function isObjectOfSameType($type, $value)
{
if (false === is_object($value)) {
return false;
}
return is_a($value, $type);
}
/**
* Checks if the given type is a type that is not nested
* (simple type except array and object)
*
* @param string $type type name from gettype()
*
* @return boolean True if it is a non-nested PHP type
*
* @see isSimpleType()
*/
protected function isFlatType($type)
{
return $type == 'NULL'
|| $type == 'string'
|| $type == 'boolean' || $type == 'bool'
|| $type == 'integer' || $type == 'int'
|| $type == 'double' || $type == 'float';
}
/**
* Checks if the given type is nullable
*
* @param string $type type name from the phpdoc param
*
* @return boolean True if it is nullable
*/
protected function isNullable($type)
{
return stripos('|' . $type . '|', '|null|') !== false;
}
/**
* Remove the 'null' section of a type
*
* @param string $type type name from the phpdoc param
*
* @return string The new type value
*/
protected function removeNullable($type)
{
if ($type === null) {
return null;
}
return substr(
str_ireplace('|null|', '|', '|' . $type . '|'),
1, -1
);
}
/**
* Copied from PHPUnit 3.7.29, Util/Test.php
*
* @param string $docblock Full method docblock
*
* @return array
*/
protected static function parseAnnotations($docblock)
{
$annotations = array();
// Strip away the docblock header and footer
// to ease parsing of one line annotations
$docblock = substr($docblock, 3, -2);
$re = '/@(?P[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?$/m';
if (preg_match_all($re, $docblock, $matches)) {
$numMatches = count($matches[0]);
for ($i = 0; $i < $numMatches; ++$i) {
$annotations[$matches['name'][$i]][] = $matches['value'][$i];
}
}
return $annotations;
}
/**
* Log a message to the $logger object
*
* @param string $level Logging level
* @param string $message Text to log
* @param array $context Additional information
*
* @return null
*/
protected function log($level, $message, array $context = array())
{
if ($this->logger) {
$this->logger->log($level, $message, $context);
}
}
/**
* Sets a logger instance on the object
*
* @param LoggerInterface $logger PSR-3 compatible logger object
*
* @return null
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
}
?>
PK &|O& ChangeLognu W+A 2016-10-11 Christian Weiske
* Add option to turn off the "must not be NULL" exception
by @ kamranahmedse (issue #58)
* Add support for properties with hyphens "-"
by @redshark1802 (issue #55)
* Add support for both "double" and "float" types
* Move to PEAR channel zustellzentrum.cweiske.de
* Version 1.0.0
2016-04-14 Christian Weiske
* Add $undefinedPropertyHandler (issue #51)
* Add $classMap to override class names (issue #53)
* Add option to enable strict object type checks (issue #50)
* Add composer autoloader performance improvement
* Add exception when an array is expected, but simple type given
(issue #44)
* Fix non-nullable object handling: Exception is now thrown when
NULL is given and an object was expected.
THIS WILL PROBABLY BREAK YOUR CODE
Add "|null" to all your "@var ClassName" lines to fix that.
* Version 0.11.0
2015-09-24 Christian Weiske
* Add dependency injection support (issue #42)
* Fix casting of arrays of simple types
* Version 0.10.0
2015-08-14 Christian Weiske
* Add case-insensitive property matching (issue #40)
* Add option to disable map() parameter type enforcement (issue #37)
* Release 0.9.0
2015-07-06 Christian Weiske
* Add support for seting objects directly if they have
the correct type already by @radmen
* Throw exception when a non-object is passed to map()
* Release 0.8.0
2015-06-19 Christian Weiske
* Support "mixed" variable type (issue #33)
* Release 0.7.0
2015-05-28 Christian Weiske
* Fix namespace error with setter type hints
* Release 0.6.1
2015-04-09 Christian Weiske
* Prefer setter methods over directy property access
* Change setter method name calculation for properties
with _ underscores by @msankhala
* Release 0.6.0
2015-03-18 Christian Weiske
* Add support for nullable types (int|null) by @barryvdh
* Increase test coverage to 100%
* Fix float value detection by @sonicgd
* Release 0.5.0
2015-01-08 Christian Weiske
* Fix bug #23: handle empty variable types
* Fix bug #24: Namespaced ArrayObject class with namespaced
value type does not work
* Release 0.4.4
2014-12-17 Christian Weiske
* Change license from AGPL v3 to OSL-3.0
* Release 0.4.3
2014-12-05 Christian Weiske
* Fix array mapping when value is NULL by @darkgaro
* Release 0.4.2
2014-11-04 Christian Weiske
* Fix handling of private properties with public setters
* Fix handling of simple array types in namespaced files
* Release 0.4.1
2014-08-20 Sebastian Mendel
* Incorporate performance tweaks from @Jalle19
* Release 0.4.0
2014-06-11 Andre Hähnel
* Optional exceptions for missing or undefined data
* Release 0.3.0
2014-05-16 Christian Weiske
* Handle NULL values when mapping simple data types onto objects
* Release 0.2.1
2014-05-15 Christian Weiske
* Add support for mapping simple data types onto objects
* Fix tests on phpunit 4.x
* Release version 0.2.0
2014-03-17 Christian Weiske
* Prevent autoloading classes with ] in its name
* Release version 0.1.3
2014-02-03 Christian Weiske
* Fix issue #2: Namespace is prepended two times
* Fix issue #1: Remove declare(encoding="UTF-8") calls
* Release version 0.1.2
PK &|OK? ? tests/SimpleTest.phpnu W+A
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link https://github.com/cweiske/jsonmapper
*/
require_once 'JsonMapperTest/Simple.php';
/**
* Unit tests for JsonMapper's simple type handling
*
* @category Tools
* @package JsonMapper
* @author Christian Weiske
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link https://github.com/cweiske/jsonmapper
*/
class SimpleTest extends \PHPUnit_Framework_TestCase
{
/**
* Test for "@var string"
*/
public function testMapSimpleString()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"str":"stringvalue"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('string', $sn->str);
$this->assertEquals('stringvalue', $sn->str);
}
/**
* Test for "@var float"
*/
public function testMapSimpleFloat()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"fl":"1.2"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('float', $sn->fl);
$this->assertEquals(1.2, $sn->fl);
}
/**
* Test for "@var bool"
*/
public function testMapSimpleBool()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pbool":"1"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('boolean', $sn->pbool);
$this->assertEquals(true, $sn->pbool);
}
/**
* Test for "@var boolean"
*/
public function testMapSimpleBoolean()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pboolean":"0"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('boolean', $sn->pboolean);
$this->assertEquals(false, $sn->pboolean);
}
/**
* Test for "@var int"
*/
public function testMapSimpleInt()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pint":"123"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('integer', $sn->pint);
$this->assertEquals(123, $sn->pint);
}
/**
* Test for "@var integer"
*/
public function testMapSimpleInteger()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pinteger":"12345"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('integer', $sn->pinteger);
$this->assertEquals(12345, $sn->pinteger);
}
/**
* Test for "@var mixed"
*/
public function testMapSimpleMixed()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"mixed":12345}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('integer', $sn->mixed);
$this->assertEquals('12345', $sn->mixed);
$sn = $jm->map(
json_decode('{"mixed":"12345"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('string', $sn->mixed);
$this->assertEquals(12345, $sn->mixed);
}
/**
* Test for "@var int|null" with int value
*/
public function testMapSimpleNullableInt()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pnullable":0}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('integer', $sn->pnullable);
$this->assertEquals(0, $sn->pnullable);
}
/**
* Test for "@var int|null" with null value
*/
public function testMapSimpleNullableNull()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pnullable":null}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('null', $sn->pnullable);
$this->assertEquals(null, $sn->pnullable);
}
/**
* Test for "@var int|null" with string value
*/
public function testMapSimpleNullableWrong()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"pnullable":"12345"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('integer', $sn->pnullable);
$this->assertEquals(12345, $sn->pnullable);
}
/**
* Test for variable with no @var annotation
*/
public function testMapSimpleNoType()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"notype":{"k":"v"}}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('object', $sn->notype);
$this->assertEquals((object) array('k' => 'v'), $sn->notype);
}
/**
* Variable with an underscore
*/
public function testMapSimpleUnderscore()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"under_score":"f"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('string', $sn->under_score);
$this->assertEquals('f', $sn->under_score);
}
/**
* Variable with an underscore and a setter method
*/
public function testMapSimpleUnderscoreSetter()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"under_score_setter":"blubb"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType(
'string', $sn->internalData['under_score_setter']
);
$this->assertEquals(
'blubb', $sn->internalData['under_score_setter']
);
}
/**
* Variable with hyphen (-)
*/
public function testMapSimpleHyphen()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"hyphen-value":"test"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType('string', $sn->hyphenValue);
$this->assertEquals('test', $sn->hyphenValue);
}
/**
* Variable with hyphen and a setter method
*/
public function testMapSimpleHyphenSetter()
{
$jm = new JsonMapper();
$sn = $jm->map(
json_decode('{"hyphen-value-setter":"blubb"}'),
new JsonMapperTest_Simple()
);
$this->assertInternalType(
'string', $sn->internalData['hyphen-value-setter']
);
$this->assertEquals(
'blubb', $sn->internalData['hyphen-value-setter']
);
}
}
?>
PK &|O[dP P tests/namespacetest/UnitData.phpnu W+A internalData['namespacedTypeHint'] = $foo;
}
}
?>
PK &|OR " tests/namespacetest/model/User.phpnu W+A name = $name;
}
}
?>
PK &|O3R R &