From 7b7b497318b00624e0ef169d1a5e35951191ff36 Mon Sep 17 00:00:00 2001 From: ytake Date: Wed, 19 Apr 2017 23:07:46 +0900 Subject: [PATCH] init --- .gitignore | 4 + .scrutinizer.yml | 12 + .travis.yml | 21 ++ CONTRIBUTING.md | 30 ++ LICENSE | 20 ++ README.md | 7 +- UPGRADE-3.0.md | 7 + composer.json | 43 +++ phpunit.xml.dist | 23 ++ src/Climate/Celsius.php | 30 ++ src/Climate/Fahrenheit.php | 30 ++ src/Climate/Kelvin.php | 30 ++ src/Climate/RelativeHumidity.php | 46 +++ src/Climate/Temperature.php | 23 ++ src/DateTime/Date.php | 162 +++++++++++ src/DateTime/DateTime.php | 145 ++++++++++ src/DateTime/DateTimeWithTimeZone.php | 163 +++++++++++ .../Exception/InvalidDateException.php | 13 + .../Exception/InvalidTimeZoneException.php | 12 + src/DateTime/Hour.php | 58 ++++ src/DateTime/Minute.php | 59 ++++ src/DateTime/Month.php | 57 ++++ src/DateTime/MonthDay.php | 45 +++ src/DateTime/Second.php | 45 +++ src/DateTime/Time.php | 163 +++++++++++ src/DateTime/TimeZone.php | 110 +++++++ src/DateTime/WeekDay.php | 52 ++++ src/DateTime/Year.php | 21 ++ src/Enum/Enum.php | 56 ++++ .../InvalidNativeArgumentException.php | 11 + src/Geography/Address.php | 212 ++++++++++++++ src/Geography/Continent.php | 16 ++ src/Geography/Coordinate.php | 215 ++++++++++++++ src/Geography/Country.php | 85 ++++++ src/Geography/CountryCode.php | 253 ++++++++++++++++ src/Geography/CountryCodeName.php | 269 ++++++++++++++++++ src/Geography/DistanceFormula.php | 12 + src/Geography/DistanceUnit.php | 13 + src/Geography/Ellipsoid.php | 32 +++ src/Geography/Latitude.php | 32 +++ src/Geography/Longitude.php | 31 ++ src/Geography/Street.php | 141 +++++++++ src/Identity/UUID.php | 73 +++++ src/Money/Currency.php | 70 +++++ src/Money/CurrencyCode.php | 169 +++++++++++ src/Money/Money.php | 133 +++++++++ src/NullValue/NullValue.php | 47 +++ src/Number/Complex.php | 154 ++++++++++ src/Number/Integer.php | 66 +++++ src/Number/Natural.php | 30 ++ src/Number/NumberInterface.php | 13 + src/Number/Real.php | 110 +++++++ src/Number/RoundingMode.php | 13 + src/Person/Age.php | 9 + src/Person/Gender.php | 12 + src/Person/Name.php | 135 +++++++++ src/StringLiteral/StringLiteral.php | 84 ++++++ src/Structure/Collection.php | 127 +++++++++ src/Structure/Dictionary.php | 114 ++++++++ src/Structure/KeyValuePair.php | 99 +++++++ src/Util/Util.php | 33 +++ src/ValueObjectInterface.php | 28 ++ src/Web/Domain.php | 23 ++ src/Web/EmailAddress.php | 51 ++++ src/Web/FragmentIdentifier.php | 23 ++ src/Web/FragmentIdentifierInterface.php | 7 + src/Web/Hostname.php | 25 ++ src/Web/IPAddress.php | 40 +++ src/Web/IPAddressVersion.php | 11 + src/Web/IPv4Address.php | 24 ++ src/Web/IPv6Address.php | 24 ++ src/Web/NullFragmentIdentifier.php | 15 + src/Web/NullPortNumber.php | 9 + src/Web/NullQueryString.php | 15 + src/Web/Path.php | 20 ++ src/Web/PortNumber.php | 32 +++ src/Web/PortNumberInterface.php | 7 + src/Web/QueryString.php | 37 +++ src/Web/QueryStringInterface.php | 8 + src/Web/SchemeName.php | 23 ++ src/Web/Url.php | 216 ++++++++++++++ tests/Climate/CelsiusTest.php | 37 +++ tests/Climate/FahrenheitTest.php | 37 +++ tests/Climate/KelvinTest.php | 37 +++ tests/Climate/RelativeHumidityTest.php | 25 ++ tests/DateTime/DateTest.php | 94 ++++++ tests/DateTime/DateTimeTest.php | 111 ++++++++ tests/DateTime/DateTimeWithTimeZoneTest.php | 140 +++++++++ tests/DateTime/HourTest.php | 30 ++ tests/DateTime/MinuteTest.php | 30 ++ tests/DateTime/MonthDayTest.php | 30 ++ tests/DateTime/MonthTest.php | 33 +++ tests/DateTime/SecondTest.php | 30 ++ tests/DateTime/TimeTest.php | 94 ++++++ tests/DateTime/TimeZoneTest.php | 78 +++++ tests/DateTime/WeekDayTest.php | 33 +++ tests/DateTime/YearTest.php | 16 ++ tests/Enum/EnumTest.php | 27 ++ tests/Geography/AddressTest.php | 125 ++++++++ tests/Geography/CoordinateTest.php | 113 ++++++++ tests/Geography/CountryCodeNameTest.php | 20 ++ tests/Geography/CountryTest.php | 51 ++++ tests/Geography/LatitudeTest.php | 26 ++ tests/Geography/LongitudeTest.php | 26 ++ tests/Geography/StreetTest.php | 65 +++++ tests/Identity/UUIDTest.php | 43 +++ tests/Money/CurrencyTest.php | 47 +++ tests/Money/MoneyTest.php | 110 +++++++ tests/NullValue/NullValueTest.php | 36 +++ tests/Number/ComplexTest.php | 88 ++++++ tests/Number/IntegerTest.php | 57 ++++ tests/Number/NaturalTest.php | 15 + tests/Number/RealTest.php | 69 +++++ tests/Person/AgeTest.php | 35 +++ tests/Person/GenderTest.php | 35 +++ tests/Person/NameTest.php | 69 +++++ tests/StringLiteral/StringLiteralTest.php | 56 ++++ tests/Structure/CollectionTest.php | 114 ++++++++ tests/Structure/DictionaryTest.php | 97 +++++++ tests/Structure/KeyValuePairTest.php | 58 ++++ tests/TestCase.php | 7 + tests/Util/UtilTest.php | 25 ++ tests/Web/DomainTest.php | 18 ++ tests/Web/EmailAddressTest.php | 41 +++ tests/Web/FragmentIdentifierTest.php | 30 ++ tests/Web/HostnameTest.php | 15 + tests/Web/IPAddressTest.php | 25 ++ tests/Web/IPv4AddressTest.php | 22 ++ tests/Web/IPv6AddressTest.php | 22 ++ tests/Web/PathTest.php | 22 ++ tests/Web/PortNumberTest.php | 22 ++ tests/Web/QueryStringTest.php | 53 ++++ tests/Web/SchemeNameTest.php | 21 ++ tests/Web/UrlTest.php | 181 ++++++++++++ 134 files changed, 7678 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .scrutinizer.yml create mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 UPGRADE-3.0.md create mode 100644 composer.json create mode 100644 phpunit.xml.dist create mode 100644 src/Climate/Celsius.php create mode 100644 src/Climate/Fahrenheit.php create mode 100644 src/Climate/Kelvin.php create mode 100644 src/Climate/RelativeHumidity.php create mode 100644 src/Climate/Temperature.php create mode 100644 src/DateTime/Date.php create mode 100644 src/DateTime/DateTime.php create mode 100644 src/DateTime/DateTimeWithTimeZone.php create mode 100644 src/DateTime/Exception/InvalidDateException.php create mode 100644 src/DateTime/Exception/InvalidTimeZoneException.php create mode 100644 src/DateTime/Hour.php create mode 100644 src/DateTime/Minute.php create mode 100644 src/DateTime/Month.php create mode 100644 src/DateTime/MonthDay.php create mode 100644 src/DateTime/Second.php create mode 100644 src/DateTime/Time.php create mode 100644 src/DateTime/TimeZone.php create mode 100644 src/DateTime/WeekDay.php create mode 100644 src/DateTime/Year.php create mode 100644 src/Enum/Enum.php create mode 100644 src/Exception/InvalidNativeArgumentException.php create mode 100644 src/Geography/Address.php create mode 100644 src/Geography/Continent.php create mode 100644 src/Geography/Coordinate.php create mode 100644 src/Geography/Country.php create mode 100644 src/Geography/CountryCode.php create mode 100644 src/Geography/CountryCodeName.php create mode 100644 src/Geography/DistanceFormula.php create mode 100644 src/Geography/DistanceUnit.php create mode 100644 src/Geography/Ellipsoid.php create mode 100644 src/Geography/Latitude.php create mode 100644 src/Geography/Longitude.php create mode 100644 src/Geography/Street.php create mode 100644 src/Identity/UUID.php create mode 100644 src/Money/Currency.php create mode 100644 src/Money/CurrencyCode.php create mode 100644 src/Money/Money.php create mode 100644 src/NullValue/NullValue.php create mode 100644 src/Number/Complex.php create mode 100644 src/Number/Integer.php create mode 100644 src/Number/Natural.php create mode 100644 src/Number/NumberInterface.php create mode 100644 src/Number/Real.php create mode 100644 src/Number/RoundingMode.php create mode 100644 src/Person/Age.php create mode 100644 src/Person/Gender.php create mode 100644 src/Person/Name.php create mode 100644 src/StringLiteral/StringLiteral.php create mode 100644 src/Structure/Collection.php create mode 100644 src/Structure/Dictionary.php create mode 100644 src/Structure/KeyValuePair.php create mode 100644 src/Util/Util.php create mode 100644 src/ValueObjectInterface.php create mode 100644 src/Web/Domain.php create mode 100644 src/Web/EmailAddress.php create mode 100644 src/Web/FragmentIdentifier.php create mode 100644 src/Web/FragmentIdentifierInterface.php create mode 100644 src/Web/Hostname.php create mode 100644 src/Web/IPAddress.php create mode 100644 src/Web/IPAddressVersion.php create mode 100644 src/Web/IPv4Address.php create mode 100644 src/Web/IPv6Address.php create mode 100644 src/Web/NullFragmentIdentifier.php create mode 100644 src/Web/NullPortNumber.php create mode 100644 src/Web/NullQueryString.php create mode 100644 src/Web/Path.php create mode 100644 src/Web/PortNumber.php create mode 100644 src/Web/PortNumberInterface.php create mode 100644 src/Web/QueryString.php create mode 100644 src/Web/QueryStringInterface.php create mode 100644 src/Web/SchemeName.php create mode 100644 src/Web/Url.php create mode 100644 tests/Climate/CelsiusTest.php create mode 100644 tests/Climate/FahrenheitTest.php create mode 100644 tests/Climate/KelvinTest.php create mode 100644 tests/Climate/RelativeHumidityTest.php create mode 100644 tests/DateTime/DateTest.php create mode 100644 tests/DateTime/DateTimeTest.php create mode 100644 tests/DateTime/DateTimeWithTimeZoneTest.php create mode 100644 tests/DateTime/HourTest.php create mode 100644 tests/DateTime/MinuteTest.php create mode 100644 tests/DateTime/MonthDayTest.php create mode 100644 tests/DateTime/MonthTest.php create mode 100644 tests/DateTime/SecondTest.php create mode 100644 tests/DateTime/TimeTest.php create mode 100644 tests/DateTime/TimeZoneTest.php create mode 100644 tests/DateTime/WeekDayTest.php create mode 100644 tests/DateTime/YearTest.php create mode 100644 tests/Enum/EnumTest.php create mode 100644 tests/Geography/AddressTest.php create mode 100644 tests/Geography/CoordinateTest.php create mode 100644 tests/Geography/CountryCodeNameTest.php create mode 100644 tests/Geography/CountryTest.php create mode 100644 tests/Geography/LatitudeTest.php create mode 100644 tests/Geography/LongitudeTest.php create mode 100644 tests/Geography/StreetTest.php create mode 100644 tests/Identity/UUIDTest.php create mode 100644 tests/Money/CurrencyTest.php create mode 100644 tests/Money/MoneyTest.php create mode 100644 tests/NullValue/NullValueTest.php create mode 100644 tests/Number/ComplexTest.php create mode 100644 tests/Number/IntegerTest.php create mode 100644 tests/Number/NaturalTest.php create mode 100644 tests/Number/RealTest.php create mode 100644 tests/Person/AgeTest.php create mode 100644 tests/Person/GenderTest.php create mode 100644 tests/Person/NameTest.php create mode 100644 tests/StringLiteral/StringLiteralTest.php create mode 100644 tests/Structure/CollectionTest.php create mode 100644 tests/Structure/DictionaryTest.php create mode 100644 tests/Structure/KeyValuePairTest.php create mode 100644 tests/TestCase.php create mode 100644 tests/Util/UtilTest.php create mode 100644 tests/Web/DomainTest.php create mode 100644 tests/Web/EmailAddressTest.php create mode 100644 tests/Web/FragmentIdentifierTest.php create mode 100644 tests/Web/HostnameTest.php create mode 100644 tests/Web/IPAddressTest.php create mode 100644 tests/Web/IPv4AddressTest.php create mode 100644 tests/Web/IPv6AddressTest.php create mode 100644 tests/Web/PathTest.php create mode 100644 tests/Web/PortNumberTest.php create mode 100644 tests/Web/QueryStringTest.php create mode 100644 tests/Web/SchemeNameTest.php create mode 100644 tests/Web/UrlTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4773508 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/composer.lock +/phpunit.xml +/vendor/ diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 0000000..6ebfd66 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,12 @@ +tools: + external_code_coverage: + timeout: 600 + php_code_sniffer: true + php_cpd: true + php_loc: true + php_mess_detector: true + php_pdepend: true + php_analyzer: true + sensiolabs_security_checker: true +filter: + paths: [src/*] diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3b0f06c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: php + +sudo: false + +php: + - 5.4 + - 5.5 + - 5.6 + - hhvm + - nightly + +before_script: + - composer self-update + - composer install --prefer-dist --no-interaction + +script: + - bin/phpunit --coverage-clover=coverage.clover --coverage-text + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1053119 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +Contributing +============ + +If you are reading this, **thank you**! You are about to make things better and this makes you **a hero**! + +Here are a few rules to follow in order to ease code reviews, and discussions before +maintainers accept and merge your work. + +You MUST follow the [PSR-1](http://www.php-fig.org/psr/1/) and +[PSR-2](http://www.php-fig.org/psr/2/). If you don't know about any of them, you +should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer +tool](http://cs.sensiolabs.org/). + +You MUST run the test suite. + +You MUST write (or update) unit tests. + +You SHOULD write documentation. + +Please, write [commit messages that make +sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), +and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing) +before submitting your Pull Request. + +One may ask you to [squash your +commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) +too. This is used to "clean" your Pull Request before merging it (we don't want +commits such as `fix tests`, `fix 2`, `fix 3`, etc.). + +Thank you very much! \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bc23710 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Nicolò Pignatelli + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 80a713b..d119c39 100644 --- a/README.md +++ b/README.md @@ -1 +1,6 @@ -# valueobjects \ No newline at end of file +ValueObjects +============ + +*nicolopignatelli/valueobjects* + +Temporary substitute library diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md new file mode 100644 index 0000000..b16cb72 --- /dev/null +++ b/UPGRADE-3.0.md @@ -0,0 +1,7 @@ +UPGRADE FROM 2.x to 3.0 +======================= + +### StringLiteral + + * The `String` and `Null` classed and namespaces have been respectively renamed to + `StringLiteral` and `NullValue` in order to be compatible with PHP 7. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..2662612 --- /dev/null +++ b/composer.json @@ -0,0 +1,43 @@ +{ + "name": "ytake/valueobjects", + "description": "A PHP library/collection of classes aimed to help developers using and undestanding immutable objects.(temporary package)", + "license": "MIT", + "authors": [ + { + "name": "Nicolò Pignatelli", + "email": "pignatelli.nicolo@gmail.com" + } + ], + "require": { + "php": ">=5.4", + "ramsey/uuid": "~3.0", + "mathiasverraes/money": "~1.2", + "marc-mabe/php-enum": "~1.0", + "zendframework/zend-validator": "~2.2", + "league/geotools": "~0.7" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "config": { + "bin-dir": "bin" + }, + "autoload": { + "psr-4": { + "ValueObjects\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "ValueObjects\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "4.2.x-dev" + } + }, + "replace": { + "nicolopignatelli/valueobjects": "^4.0" + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..ccde45f --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,23 @@ + + + + + ./tests/ + + + + + ./src/ + + + diff --git a/src/Climate/Celsius.php b/src/Climate/Celsius.php new file mode 100644 index 0000000..020f466 --- /dev/null +++ b/src/Climate/Celsius.php @@ -0,0 +1,30 @@ +value); + } + + /** + * @return Kelvin + */ + public function toKelvin() + { + return new Kelvin($this->value + 273.15); + } + + /** + * @return Fahrenheit + */ + public function toFahrenheit() + { + return new Fahrenheit($this->value * 1.8 + 32); + } +} diff --git a/src/Climate/Fahrenheit.php b/src/Climate/Fahrenheit.php new file mode 100644 index 0000000..e14bff2 --- /dev/null +++ b/src/Climate/Fahrenheit.php @@ -0,0 +1,30 @@ +value - 32) / 1.8); + } + + /** + * @return Kelvin + */ + public function toKelvin() + { + return new Kelvin($this->toCelsius()->toNative() + 273.15); + } + + /** + * @return Fahrenheit + */ + public function toFahrenheit() + { + return new static($this->value); + } +} diff --git a/src/Climate/Kelvin.php b/src/Climate/Kelvin.php new file mode 100644 index 0000000..85f83dd --- /dev/null +++ b/src/Climate/Kelvin.php @@ -0,0 +1,30 @@ +value - 273.15); + } + + /** + * @return Kelvin + */ + public function toKelvin() + { + return new static($this->value); + } + + /** + * @return Fahrenheit + */ + public function toFahrenheit() + { + return new Fahrenheit($this->toCelsius()->toNative() * 1.8 + 32); + } +} diff --git a/src/Climate/RelativeHumidity.php b/src/Climate/RelativeHumidity.php new file mode 100644 index 0000000..16bbd89 --- /dev/null +++ b/src/Climate/RelativeHumidity.php @@ -0,0 +1,46 @@ + array('min_range' => self::MIN, 'max_range' => self::MAX) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=' . self::MIN . ', <=' . self::MAX . ')')); + } + + parent::__construct($value); + } +} diff --git a/src/Climate/Temperature.php b/src/Climate/Temperature.php new file mode 100644 index 0000000..fd2f261 --- /dev/null +++ b/src/Climate/Temperature.php @@ -0,0 +1,23 @@ +format('Y')); + $month = Month::fromNativeDateTime($date); + $day = \intval($date->format('d')); + + return new static(new Year($year), $month, new MonthDay($day)); + } + + /** + * Returns current Date + * + * @return Date + */ + public static function now() + { + $date = new static(Year::now(), Month::now(), MonthDay::now()); + + return $date; + } + + /** + * Create a new Date + * + * @param Year $year + * @param Month $month + * @param MonthDay $day + * @throws InvalidDateException + */ + public function __construct(Year $year, Month $month, MonthDay $day) + { + \DateTime::createFromFormat('Y-F-j', \sprintf('%d-%s-%d', $year->toNative(), $month, $day->toNative())); + $nativeDateErrors = \DateTime::getLastErrors(); + + if ($nativeDateErrors['warning_count'] > 0 || $nativeDateErrors['error_count'] > 0) { + throw new InvalidDateException($year->toNative(), $month->toNative(), $day->toNative()); + } + + $this->year = $year; + $this->month = $month; + $this->day = $day; + } + + /** + * Tells whether two Date are equal by comparing their values + * + * @param ValueObjectInterface $date + * @return bool + */ + public function sameValueAs(ValueObjectInterface $date) + { + if (false === Util::classEquals($this, $date)) { + return false; + } + + return $this->getYear()->sameValueAs($date->getYear()) && + $this->getMonth()->sameValueAs($date->getMonth()) && + $this->getDay()->sameValueAs($date->getDay()); + } + + /** + * Get year + * + * @return Year + */ + public function getYear() + { + return clone $this->year; + } + + /** + * Get month + * + * @return Month + */ + public function getMonth() + { + return $this->month; + } + + /** + * Get day + * + * @return MonthDay + */ + public function getDay() + { + return clone $this->day; + } + + /** + * Returns a native PHP \DateTime version of the current Date + * + * @return \DateTime + */ + public function toNativeDateTime() + { + $year = $this->getYear()->toNative(); + $month = $this->getMonth()->getNumericValue(); + $day = $this->getDay()->toNative(); + + $date = new \DateTime(); + $date->setDate($year, $month, $day); + $date->setTime(0, 0, 0); + + return $date; + } + + /** + * Returns date as string in format Y-n-j + * + * @return string + */ + public function __toString() + { + return $this->toNativeDateTime()->format('Y-n-j'); + } +} diff --git a/src/DateTime/DateTime.php b/src/DateTime/DateTime.php new file mode 100644 index 0000000..ca38922 --- /dev/null +++ b/src/DateTime/DateTime.php @@ -0,0 +1,145 @@ +date = $date; + + if (null === $time) { + $time = Time::zero(); + } + + $this->time = $time; + } + + /** + * Tells whether two DateTime are equal by comparing their values + * + * @param ValueObjectInterface $date_time + * @return bool + */ + public function sameValueAs(ValueObjectInterface $date_time) + { + if (false === Util::classEquals($this, $date_time)) { + return false; + } + + return $this->getDate()->sameValueAs($date_time->getDate()) && $this->getTime()->sameValueAs($date_time->getTime()); + } + + /** + * Returns date from current DateTime + * + * @return Date + */ + public function getDate() + { + return clone $this->date; + } + + /** + * Returns time from current DateTime + * + * @return Time + */ + public function getTime() + { + return clone $this->time; + } + + /** + * Returns a native PHP \DateTime version of the current DateTime. + * + * @return \DateTime + */ + public function toNativeDateTime() + { + $year = $this->getDate()->getYear()->toNative(); + $month = $this->getDate()->getMonth()->getNumericValue(); + $day = $this->getDate()->getDay()->toNative(); + $hour = $this->getTime()->getHour()->toNative(); + $minute = $this->getTime()->getMinute()->toNative(); + $second = $this->getTime()->getSecond()->toNative(); + + $dateTime = new \DateTime(); + $dateTime->setDate($year, $month, $day); + $dateTime->setTime($hour, $minute, $second); + + return $dateTime; + } + + /** + * Returns DateTime as string in format "Y-n-j G:i:s" + * + * @return string + */ + public function __toString() + { + return \sprintf('%s %s', $this->getDate(), $this->getTime()); + } +} diff --git a/src/DateTime/DateTimeWithTimeZone.php b/src/DateTime/DateTimeWithTimeZone.php new file mode 100644 index 0000000..bd8cb8b --- /dev/null +++ b/src/DateTime/DateTimeWithTimeZone.php @@ -0,0 +1,163 @@ +getTimezone()); + + return new static($datetime, $timezone); + } + + /** + * Returns a DateTimeWithTimeZone object using current DateTime and default TimeZone + * + * @return DateTimeWithTimeZone + */ + public static function now() + { + return new static(DateTime::now(), TimeZone::fromDefault()); + } + + /** + * Returns a new DateTimeWithTimeZone object + * + * @param DateTime $datetime + * @param TimeZone $timezone + */ + public function __construct(DateTime $datetime, TimeZone $timezone = null) + { + $this->dateTime = $datetime; + $this->timeZone = $timezone; + } + + /** + * Tells whether two DateTimeWithTimeZone are equal by comparing their values + * + * @param ValueObjectInterface $dateTimeWithTimeZone + * + * @return bool + */ + public function sameValueAs(ValueObjectInterface $dateTimeWithTimeZone) + { + if (false === Util::classEquals($this, $dateTimeWithTimeZone)) { + return false; + } + + return $this->getDateTime()->sameValueAs($dateTimeWithTimeZone->getDateTime()) && + $this->getTimeZone()->sameValueAs($dateTimeWithTimeZone->getTimeZone()); + } + + /** + * Tells whether two DateTimeWithTimeZone represents the same timestamp + * + * @param ValueObjectInterface $dateTimeWithTimeZone + * + * @return bool + */ + public function sameTimestampAs(ValueObjectInterface $dateTimeWithTimeZone) + { + if (false === Util::classEquals($this, $dateTimeWithTimeZone)) { + return false; + } + + return $this->toNativeDateTime() == $dateTimeWithTimeZone->toNativeDateTime(); + } + + /** + * Returns datetime from current DateTimeWithTimeZone + * + * @return DateTime + */ + public function getDateTime() + { + return clone $this->dateTime; + } + + /** + * Returns timezone from current DateTimeWithTimeZone + * + * @return TimeZone + */ + public function getTimeZone() + { + return clone $this->timeZone; + } + + /** + * Returns a native PHP \DateTime version of the current DateTimeWithTimeZone + * + * @return \DateTime + */ + public function toNativeDateTime() + { + $date = $this->getDateTime()->getDate(); + $time = $this->getDateTime()->getTime(); + $year = $date->getYear()->toNative(); + $month = $date->getMonth()->getNumericValue(); + $day = $date->getDay()->toNative(); + $hour = $time->getHour()->toNative(); + $minute = $time->getMinute()->toNative(); + $second = $time->getSecond()->toNative(); + $timezone = $this->getTimeZone()->toNativeDateTimeZone(); + + $dateTime = new \DateTime(); + $dateTime->setTimezone($timezone); + $dateTime->setDate($year, $month, $day); + $dateTime->setTime($hour, $minute, $second); + + return $dateTime; + } + + /** + * Returns DateTime as string in format "Y-n-j G:i:s e" + * + * @return string + */ + public function __toString() + { + return \sprintf('%s %s', $this->getDateTime(), $this->getTimeZone()); + } +} diff --git a/src/DateTime/Exception/InvalidDateException.php b/src/DateTime/Exception/InvalidDateException.php new file mode 100644 index 0000000..224d26e --- /dev/null +++ b/src/DateTime/Exception/InvalidDateException.php @@ -0,0 +1,13 @@ + array('min_range' => self::MIN_HOUR, 'max_range' => self::MAX_HOUR) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0, <=23)')); + } + + parent::__construct($value); + } + + /** + * Returns the current hour. + * + * @return Hour + */ + public static function now() + { + $now = new \DateTime('now'); + $hour = \intval($now->format('G')); + + return new static($hour); + } +} diff --git a/src/DateTime/Minute.php b/src/DateTime/Minute.php new file mode 100644 index 0000000..950cc81 --- /dev/null +++ b/src/DateTime/Minute.php @@ -0,0 +1,59 @@ + array('min_range' => self::MIN_MINUTE, 'max_range' => self::MAX_MINUTE) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0, <=59)')); + } + + parent::__construct($value); + } + + /** + * Returns the current minute. + * + * @return Minute + */ + public static function now() + { + $now = new \DateTime('now'); + $minute = \intval($now->format('i')); + + return new static($minute); + } +} diff --git a/src/DateTime/Month.php b/src/DateTime/Month.php new file mode 100644 index 0000000..5fdcf75 --- /dev/null +++ b/src/DateTime/Month.php @@ -0,0 +1,57 @@ +format('F')); + + return static::getByName($month); + } + + /** + * Returns a numeric representation of the Month. + * 1 for January to 12 for December. + * + * @return int + */ + public function getNumericValue() + { + return $this->getOrdinal() + 1; + } +} diff --git a/src/DateTime/MonthDay.php b/src/DateTime/MonthDay.php new file mode 100644 index 0000000..13dbeb8 --- /dev/null +++ b/src/DateTime/MonthDay.php @@ -0,0 +1,45 @@ + array('min_range' => self::MIN_MONTH_DAY, 'max_range' => self::MAX_MONTH_DAY) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0, <=31)')); + } + + parent::__construct($value); + } + + /** + * Returns the current month day. + * + * @return MonthDay + */ + public static function now() + { + $now = new \DateTime('now'); + $monthDay = \intval($now->format('j')); + + return new static($monthDay); + } +} diff --git a/src/DateTime/Second.php b/src/DateTime/Second.php new file mode 100644 index 0000000..ebc2a06 --- /dev/null +++ b/src/DateTime/Second.php @@ -0,0 +1,45 @@ + array('min_range' => self::MIN_SECOND, 'max_range' => self::MAX_SECOND) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0, <=59)')); + } + + parent::__construct($value); + } + + /** + * Returns the current second. + * + * @return Second + */ + public static function now() + { + $now = new \DateTime('now'); + $second = \intval($now->format('s')); + + return new static($second); + } +} diff --git a/src/DateTime/Time.php b/src/DateTime/Time.php new file mode 100644 index 0000000..bc1f3a2 --- /dev/null +++ b/src/DateTime/Time.php @@ -0,0 +1,163 @@ +format('G')); + $minute = \intval($time->format('i')); + $second = \intval($time->format('s')); + + return static::fromNative($hour, $minute, $second); + } + + /** + * Returns current Time + * + * @return self + */ + public static function now() + { + $time = new static(Hour::now(), Minute::now(), Second::now()); + + return $time; + } + + /** + * Return zero time + * + * @return static + */ + public static function zero() + { + $time = new static(new Hour(0), new Minute(0), new Second(0)); + + return $time; + } + + /** + * Returns a new Time objects + * + * @param Hour $hour + * @param Minute $minute + * @param Second $second + */ + public function __construct(Hour $hour, Minute $minute, Second $second) + { + $this->hour = $hour; + $this->minute = $minute; + $this->second = $second; + } + + /** + * Tells whether two Time are equal by comparing their values + * + * @param ValueObjectInterface $time + * @return bool + */ + public function sameValueAs(ValueObjectInterface $time) + { + if (false === Util::classEquals($this, $time)) { + return false; + } + + return $this->getHour()->sameValueAs($time->getHour()) && $this->getMinute()->sameValueAs($time->getMinute()) && $this->getSecond()->sameValueAs($time->getSecond()); + } + + /** + * Get hour + * + * @return Hour + */ + public function getHour() + { + return $this->hour; + } + + /** + * Get minute + * + * @return Minute + */ + public function getMinute() + { + return $this->minute; + } + + /** + * Get second + * + * @return Second + */ + public function getSecond() + { + return $this->second; + } + + /** + * Returns a native PHP \DateTime version of the current Time. + * Date is set to current. + * + * @return \DateTime + */ + public function toNativeDateTime() + { + $hour = $this->getHour()->toNative(); + $minute = $this->getMinute()->toNative(); + $second = $this->getSecond()->toNative(); + + $time = new \DateTime('now'); + $time->setTime($hour, $minute, $second); + + return $time; + } + + /** + * Returns time as string in format G:i:s + * + * @return string + */ + public function __toString() + { + return $this->toNativeDateTime()->format('G:i:s'); + } +} diff --git a/src/DateTime/TimeZone.php b/src/DateTime/TimeZone.php new file mode 100644 index 0000000..a24a053 --- /dev/null +++ b/src/DateTime/TimeZone.php @@ -0,0 +1,110 @@ +getName()); + } + + /** + * Returns default TimeZone + * + * @return self + */ + public static function fromDefault() + { + return new static(new StringLiteral(date_default_timezone_get())); + } + + /** + * Returns a new TimeZone object + * + * @param StringLiteral $name + * @throws InvalidTimeZoneException + */ + public function __construct(StringLiteral $name) + { + if (!in_array($name->toNative(), timezone_identifiers_list())) { + throw new InvalidTimeZoneException($name); + } + + $this->name = $name; + } + + /** + * Returns a native PHP \DateTimeZone version of the current TimeZone. + * + * @return \DateTimeZone + */ + public function toNativeDateTimeZone() + { + return new \DateTimeZone($this->getName()->toNative()); + } + + /** + * Tells whether two DateTimeZone are equal by comparing their names + * + * @param ValueObjectInterface $timezone + * @return bool + */ + public function sameValueAs(ValueObjectInterface $timezone) + { + if (false === Util::classEquals($this, $timezone)) { + return false; + } + + return $this->getName()->sameValueAs($timezone->getName()); + } + + /** + * Returns timezone name + * + * @return StringLiteral + */ + public function getName() + { + return clone $this->name; + } + + /** + * Returns timezone name as string + * + * @return string + */ + public function __toString() + { + return $this->getName()->__toString(); + } +} diff --git a/src/DateTime/WeekDay.php b/src/DateTime/WeekDay.php new file mode 100644 index 0000000..d501d0a --- /dev/null +++ b/src/DateTime/WeekDay.php @@ -0,0 +1,52 @@ +format('l')); + + return static::getByName($weekDay); + } + + /** + * Returns a numeric representation of the WeekDay. + * 1 for Monday to 7 for Sunday. + * + * @return int + */ + public function getNumericValue() + { + return $this->getOrdinal() + 1; + } +} diff --git a/src/DateTime/Year.php b/src/DateTime/Year.php new file mode 100644 index 0000000..e5da23e --- /dev/null +++ b/src/DateTime/Year.php @@ -0,0 +1,21 @@ +format('Y')); + + return new static($year); + } +} diff --git a/src/Enum/Enum.php b/src/Enum/Enum.php new file mode 100644 index 0000000..6ae2a16 --- /dev/null +++ b/src/Enum/Enum.php @@ -0,0 +1,56 @@ +toNative() === $enum->toNative(); + } + + /** + * Returns a native string representation of the Enum value + * + * @return string + */ + public function __toString() + { + return \strval($this->toNative()); + } +} diff --git a/src/Exception/InvalidNativeArgumentException.php b/src/Exception/InvalidNativeArgumentException.php new file mode 100644 index 0000000..141373c --- /dev/null +++ b/src/Exception/InvalidNativeArgumentException.php @@ -0,0 +1,11 @@ +message = sprintf('Argument "%s" is invalid. Allowed types for argument are "%s".', $value, implode(', ', $allowed_types)); + } +} diff --git a/src/Geography/Address.php b/src/Geography/Address.php new file mode 100644 index 0000000..0d8a163 --- /dev/null +++ b/src/Geography/Address.php @@ -0,0 +1,212 @@ +name = $name; + $this->street = $street; + $this->district = $district; + $this->city = $city; + $this->region = $region; + $this->postalCode = $postalCode; + $this->country = $country; + } + + /** + * Tells whether two Address are equal + * + * @param ValueObjectInterface $address + * @return bool + */ + public function sameValueAs(ValueObjectInterface $address) + { + if (false === Util::classEquals($this, $address)) { + return false; + } + + return $this->getName()->sameValueAs($address->getName()) && + $this->getStreet()->sameValueAs($address->getStreet()) && + $this->getDistrict()->sameValueAs($address->getDistrict()) && + $this->getCity()->sameValueAs($address->getCity()) && + $this->getRegion()->sameValueAs($address->getRegion()) && + $this->getPostalCode()->sameValueAs($address->getPostalCode()) && + $this->getCountry()->sameValueAs($address->getCountry()) + ; + } + + /** + * Returns addressee name + * + * @return StringLiteral + */ + public function getName() + { + return clone $this->name; + } + + /** + * Returns street + * + * @return Street + */ + public function getStreet() + { + return clone $this->street; + } + + /** + * Returns district + * + * @return StringLiteral + */ + public function getDistrict() + { + return clone $this->district; + } + + /** + * Returns city + * + * @return StringLiteral + */ + public function getCity() + { + return clone $this->city; + } + + /** + * Returns region + * + * @return StringLiteral + */ + public function getRegion() + { + return clone $this->region; + } + + /** + * Returns postal code + * + * @return StringLiteral + */ + public function getPostalCode() + { + return clone $this->postalCode; + } + + /** + * Returns country + * + * @return Country + */ + public function getCountry() + { + return clone $this->country; + } + + /** + * Returns a string representation of the Address in US standard format. + * + * @return string + */ + public function __toString() + { + $format = <<getName(), $this->getStreet(), $this->getCity(), $this->getRegion(), $this->getPostalCode(), $this->getCountry()); + + return $addressString; + } +} diff --git a/src/Geography/Continent.php b/src/Geography/Continent.php new file mode 100644 index 0000000..daadb42 --- /dev/null +++ b/src/Geography/Continent.php @@ -0,0 +1,16 @@ + 3) { + throw new \BadMethodCallException('You must provide 2 to 3 arguments: 1) latitude, 2) longitude, 3) valid ellipsoid type (optional)'); + } + + $coordinate = new BaseCoordinate(array($args[0], $args[1])); + $latitude = Latitude::fromNative($coordinate->getLatitude()); + $longitude = Longitude::fromNative($coordinate->getLongitude()); + + $nativeEllipsoid = isset($args[2]) ? $args[2] : null; + $ellipsoid = Ellipsoid::fromNative($nativeEllipsoid); + + return new static($latitude, $longitude, $ellipsoid); + } + + /** + * Returns a new Coordinate object + * + * @param Latitude $latitude + * @param Longitude $longitude + * @param Ellipsoid $ellipsoid + */ + public function __construct(Latitude $latitude, Longitude $longitude, Ellipsoid $ellipsoid = null) + { + if (null === $ellipsoid) { + $ellipsoid = Ellipsoid::WGS84(); + } + + $this->latitude = $latitude; + $this->longitude = $longitude; + $this->ellipsoid = $ellipsoid; + } + + /** + * Tells whether tow Coordinate objects are equal + * + * @param ValueObjectInterface $coordinate + * @return bool + */ + public function sameValueAs(ValueObjectInterface $coordinate) + { + if (false === Util::classEquals($this, $coordinate)) { + return false; + } + + return $this->getLatitude()->sameValueAs($coordinate->getLatitude()) && + $this->getLongitude()->sameValueAs($coordinate->getLongitude()) && + $this->getEllipsoid()->sameValueAs($coordinate->getEllipsoid()) + ; + } + + /** + * Returns latitude + * + * @return Latitude + */ + public function getLatitude() + { + return clone $this->latitude; + } + + /** + * Returns longitude + * + * @return Longitude + */ + public function getLongitude() + { + return clone $this->longitude; + } + + /** + * Returns ellipsoid + * + * @return Ellipsoid + */ + public function getEllipsoid() + { + return $this->ellipsoid; + } + + /** + * Returns a degrees/minutes/seconds representation of the coordinate + * + * @return StringLiteral + */ + public function toDegreesMinutesSeconds() + { + $coordinate = static::getBaseCoordinate($this); + $convert = new Convert($coordinate); + $dms = $convert->toDegreesMinutesSeconds(); + + return new StringLiteral($dms); + } + + /** + * Returns a decimal minutes representation of the coordinate + * + * @return StringLiteral + */ + public function toDecimalMinutes() + { + $coordinate = static::getBaseCoordinate($this); + $convert = new Convert($coordinate); + $dm = $convert->toDecimalMinutes(); + + return new StringLiteral($dm); + } + + /** + * Returns a Universal Transverse Mercator projection representation of the coordinate in meters + * + * @return StringLiteral + */ + public function toUniversalTransverseMercator() + { + $coordinate = static::getBaseCoordinate($this); + $convert = new Convert($coordinate); + $utm = $convert->toUniversalTransverseMercator(); + + return new StringLiteral($utm); + } + + /** + * Calculates the distance between two Coordinate objects + * + * @param Coordinate $coordinate + * @param DistanceUnit $unit + * @param DistanceFormula $formula + * @return Real + */ + public function distanceFrom(Coordinate $coordinate, DistanceUnit $unit = null, DistanceFormula $formula = null) + { + if (null === $unit) { + $unit = DistanceUnit::METER(); + } + + if (null === $formula) { + $formula = DistanceFormula::FLAT(); + } + + $baseThis = static::getBaseCoordinate($this); + $baseCoordinate = static::getBaseCoordinate($coordinate); + + $distance = new Distance(); + $distance + ->setFrom($baseThis) + ->setTo($baseCoordinate) + ->in($unit->toNative()) + ; + + $value = \call_user_func(array($distance, $formula->toNative())); + + return new Real($value); + } + + /** + * Returns a native string version of the Coordiantes object in format "$latitude,$longitude" + * + * @return string + */ + public function __toString() + { + return \sprintf('%F,%F', $this->getLatitude()->toNative(), $this->getLongitude()->toNative()); + } + + /** + * Returns the underlying Coordinate object + * + * @param self $coordinate + * @return BaseCoordinate + */ + protected static function getBaseCoordinate(self $coordinate) + { + $latitude = $coordinate->getLatitude()->toNative(); + $longitude = $coordinate->getLongitude()->toNative(); + $ellipsoid = BaseEllipsoid::createFromName($coordinate->getEllipsoid()->toNative()); + $coordinate = new BaseCoordinate(array($latitude, $longitude), $ellipsoid); + + return $coordinate; + } +} diff --git a/src/Geography/Country.php b/src/Geography/Country.php new file mode 100644 index 0000000..9226e85 --- /dev/null +++ b/src/Geography/Country.php @@ -0,0 +1,85 @@ +code = $code; + } + + /** + * Tells whether two Country are equal + * + * @param ValueObjectInterface $country + * @return bool + */ + public function sameValueAs(ValueObjectInterface $country) + { + if (false === Util::classEquals($this, $country)) { + return false; + } + + return $this->getCode()->sameValueAs($country->getCode()); + } + + /** + * Returns country code + * + * @return CountryCode + */ + public function getCode() + { + return $this->code; + } + + /** + * Returns country name + * + * @return StringLiteral + */ + public function getName() + { + $code = $this->getCode(); + $name = CountryCodeName::getName($code); + + return $name; + } + + /** + * Returns country name as native string + * + * @return string + */ + public function __toString() + { + return $this->getName()->toNative(); + } +} diff --git a/src/Geography/CountryCode.php b/src/Geography/CountryCode.php new file mode 100644 index 0000000..161ba34 --- /dev/null +++ b/src/Geography/CountryCode.php @@ -0,0 +1,253 @@ + 'Afghanistan', + 'AX' => 'Åland Islands', + 'AL' => 'Albania', + 'DZ' => 'Algeria', + 'AD' => 'Andorra', + 'AO' => 'Angola', + 'AI' => 'Anguilla', + 'AQ' => 'Antarctica', + 'AG' => 'Antigua and Barbuda', + 'AR' => 'Argentina', + 'AM' => 'Armenia', + 'AW' => 'Aruba', + 'AU' => 'Australia', + 'AT' => 'Austria', + 'AZ' => 'Azerbaijan', + 'BS' => 'Bahamas', + 'BH' => 'Bahrain', + 'BD' => 'Bangladesh', + 'BB' => 'Barbados', + 'BY' => 'Belarus', + 'BE' => 'Belgium', + 'PW' => 'Belau', + 'BZ' => 'Belize', + 'BJ' => 'Benin', + 'BM' => 'Bermuda', + 'BT' => 'Bhutan', + 'BO' => 'Bolivia', + 'BQ' => 'Bonaire, Saint Eustatius and Saba', + 'BA' => 'Bosnia and Herzegovina', + 'BW' => 'Botswana', + 'BV' => 'Bouvet Island', + 'BR' => 'Brazil', + 'IO' => 'British Indian Ocean Territory', + 'VG' => 'British Virgin Islands', + 'BN' => 'Brunei', + 'BG' => 'Bulgaria', + 'BF' => 'Burkina Faso', + 'BI' => 'Burundi', + 'KH' => 'Cambodia', + 'CM' => 'Cameroon', + 'CA' => 'Canada', + 'CV' => 'Cape Verde', + 'KY' => 'Cayman Islands', + 'CF' => 'Central African Republic', + 'TD' => 'Chad', + 'CL' => 'Chile', + 'CN' => 'China', + 'CX' => 'Christmas Island', + 'CC' => 'Cocos (Keeling) Islands', + 'CO' => 'Colombia', + 'KM' => 'Comoros', + 'CG' => 'Congo (Brazzaville)', + 'CD' => 'Congo (Kinshasa)', + 'CK' => 'Cook Islands', + 'CR' => 'Costa Rica', + 'HR' => 'Croatia', + 'CU' => 'Cuba', + 'CW' => 'Curaçao', + 'CY' => 'Cyprus', + 'CZ' => 'Czech Republic', + 'DK' => 'Denmark', + 'DJ' => 'Djibouti', + 'DM' => 'Dominica', + 'DO_' => 'Dominican Republic', + 'EC' => 'Ecuador', + 'EG' => 'Egypt', + 'SV' => 'El Salvador', + 'GQ' => 'Equatorial Guinea', + 'ER' => 'Eritrea', + 'EE' => 'Estonia', + 'ET' => 'Ethiopia', + 'FK' => 'Falkland Islands', + 'FO' => 'Faroe Islands', + 'FJ' => 'Fiji', + 'FI' => 'Finland', + 'FR' => 'France', + 'GF' => 'French Guiana', + 'PF' => 'French Polynesia', + 'TF' => 'French Southern Territories', + 'GA' => 'Gabon', + 'GM' => 'Gambia', + 'GE' => 'Georgia', + 'DE' => 'Germany', + 'GH' => 'Ghana', + 'GI' => 'Gibraltar', + 'GR' => 'Greece', + 'GL' => 'Greenland', + 'GD' => 'Grenada', + 'GP' => 'Guadeloupe', + 'GT' => 'Guatemala', + 'GG' => 'Guernsey', + 'GN' => 'Guinea', + 'GW' => 'Guinea-Bissau', + 'GY' => 'Guyana', + 'HT' => 'Haiti', + 'HM' => 'Heard Island and McDonald Islands', + 'HN' => 'Honduras', + 'HK' => 'Hong Kong', + 'HU' => 'Hungary', + 'IS' => 'Iceland', + 'IN' => 'India', + 'ID' => 'Indonesia', + 'IR' => 'Iran', + 'IQ' => 'Iraq', + 'IE' => 'Republic of Ireland', + 'IM' => 'Isle of Man', + 'IL' => 'Israel', + 'IT' => 'Italy', + 'CI' => 'Ivory Coast', + 'JM' => 'Jamaica', + 'JP' => 'Japan', + 'JE' => 'Jersey', + 'JO' => 'Jordan', + 'KZ' => 'Kazakhstan', + 'KE' => 'Kenya', + 'KI' => 'Kiribati', + 'KW' => 'Kuwait', + 'KG' => 'Kyrgyzstan', + 'LA' => 'Laos', + 'LV' => 'Latvia', + 'LB' => 'Lebanon', + 'LS' => 'Lesotho', + 'LR' => 'Liberia', + 'LY' => 'Libya', + 'LI' => 'Liechtenstein', + 'LT' => 'Lithuania', + 'LU' => 'Luxembourg', + 'MO' => 'Macao S.A.R., China', + 'MK' => 'Macedonia', + 'MG' => 'Madagascar', + 'MW' => 'Malawi', + 'MY' => 'Malaysia', + 'MV' => 'Maldives', + 'ML' => 'Mali', + 'MT' => 'Malta', + 'MH' => 'Marshall Islands', + 'MQ' => 'Martinique', + 'MR' => 'Mauritania', + 'MU' => 'Mauritius', + 'YT' => 'Mayotte', + 'MX' => 'Mexico', + 'FM' => 'Micronesia', + 'MD' => 'Moldova', + 'MC' => 'Monaco', + 'MN' => 'Mongolia', + 'ME' => 'Montenegro', + 'MS' => 'Montserrat', + 'MA' => 'Morocco', + 'MZ' => 'Mozambique', + 'MM' => 'Myanmar', + 'NA' => 'Namibia', + 'NR' => 'Nauru', + 'NP' => 'Nepal', + 'NL' => 'Netherlands', + 'AN' => 'Netherlands Antilles', + 'NC' => 'New Caledonia', + 'NZ' => 'New Zealand', + 'NI' => 'Nicaragua', + 'NE' => 'Niger', + 'NG' => 'Nigeria', + 'NU' => 'Niue', + 'NF' => 'Norfolk Island', + 'KP' => 'North Korea', + 'NO' => 'Norway', + 'OM' => 'Oman', + 'PK' => 'Pakistan', + 'PS' => 'Palestinian Territory', + 'PA' => 'Panama', + 'PG' => 'Papua New Guinea', + 'PY' => 'Paraguay', + 'PE' => 'Peru', + 'PH' => 'Philippines', + 'PN' => 'Pitcairn', + 'PL' => 'Poland', + 'PT' => 'Portugal', + 'QA' => 'Qatar', + 'RE' => 'Reunion', + 'RO' => 'Romania', + 'RU' => 'Russia', + 'RW' => 'Rwanda', + 'BL' => 'Saint-Barthélemy', + 'SH' => 'Saint Helena', + 'KN' => 'Saint Kitts and Nevis', + 'LC' => 'Saint Lucia', + 'MF' => 'Saint Martin (French part)', + 'SX' => 'Saint Martin (Dutch part)', + 'PM' => 'Saint Pierre and Miquelon', + 'VC' => 'Saint Vincent and the Grenadines', + 'WS' => 'Samoa', + 'SM' => 'San Marino', + 'ST' => 'São Tomé and Príncipe', + 'SA' => 'Saudi Arabia', + 'SN' => 'Senegal', + 'RS' => 'Serbia', + 'SC' => 'Seychelles', + 'SL' => 'Sierra Leone', + 'SG' => 'Singapore', + 'SK' => 'Slovakia', + 'SI' => 'Slovenia', + 'SB' => 'Solomon Islands', + 'SO' => 'Somalia', + 'ZA' => 'South Africa', + 'GS' => 'South Georgia/Sandwich Islands', + 'KR' => 'South Korea', + 'SS' => 'South Sudan', + 'ES' => 'Spain', + 'LK' => 'Sri Lanka', + 'SD' => 'Sudan', + 'SR' => 'Suriname', + 'SJ' => 'Svalbard and Jan Mayen', + 'SZ' => 'Swaziland', + 'SE' => 'Sweden', + 'CH' => 'Switzerland', + 'SY' => 'Syria', + 'TW' => 'Taiwan', + 'TJ' => 'Tajikistan', + 'TZ' => 'Tanzania', + 'TH' => 'Thailand', + 'TL' => 'Timor-Leste', + 'TG' => 'Togo', + 'TK' => 'Tokelau', + 'TO' => 'Tonga', + 'TT' => 'Trinidad and Tobago', + 'TN' => 'Tunisia', + 'TR' => 'Turkey', + 'TM' => 'Turkmenistan', + 'TC' => 'Turks and Caicos Islands', + 'TV' => 'Tuvalu', + 'UG' => 'Uganda', + 'UA' => 'Ukraine', + 'AE' => 'United Arab Emirates', + 'GB' => 'United Kingdom', + 'US' => 'United States', + 'UY' => 'Uruguay', + 'UZ' => 'Uzbekistan', + 'VU' => 'Vanuatu', + 'VA' => 'Vatican', + 'VE' => 'Venezuela', + 'VN' => 'Vietnam', + 'WF' => 'Wallis and Futuna', + 'EH' => 'Western Sahara', + 'YE' => 'Yemen', + 'ZM' => 'Zambia', + 'ZW' => 'Zimbabwe', + ); + + /** + * Returns country name + * + * @param CountryCode $code + * @return StringLiteral + */ + public static function getName(CountryCode $code) + { + $codeValue = $code->toNative(); + $name = self::$names[$codeValue]; + + return new StringLiteral($name); + } +} diff --git a/src/Geography/DistanceFormula.php b/src/Geography/DistanceFormula.php new file mode 100644 index 0000000..2fedabd --- /dev/null +++ b/src/Geography/DistanceFormula.php @@ -0,0 +1,12 @@ +getLatitude(); + + $this->value = $latitude; + } +} diff --git a/src/Geography/Longitude.php b/src/Geography/Longitude.php new file mode 100644 index 0000000..4e84e4b --- /dev/null +++ b/src/Geography/Longitude.php @@ -0,0 +1,31 @@ +getLongitude(); + + $this->value = $longitude; + } +} diff --git a/src/Geography/Street.php b/src/Geography/Street.php new file mode 100644 index 0000000..2c358b2 --- /dev/null +++ b/src/Geography/Street.php @@ -0,0 +1,141 @@ +name = $name; + $this->number = $number; + + if ($elements === null) { + $elements = new StringLiteral(''); + } + $this->elements = $elements; + + if ($format === null) { + $format = new StringLiteral('%number% %name%'); + } + $this->format = $format; + } + + /** + * Tells whether two Street objects are equal + * @param ValueObjectInterface $street + * @return bool + */ + public function sameValueAs(ValueObjectInterface $street) + { + if (false === Util::classEquals($this, $street)) { + return false; + } + + return $this->getName()->sameValueAs($street->getName()) && + $this->getNumber()->sameValueAs($street->getNumber()) && + $this->getElements()->sameValueAs($street->getElements()) + ; + } + + /** + * Returns street name + * + * @return StringLiteral + */ + public function getName() + { + return clone $this->name; + } + + /** + * Returns street number + * + * @return StringLiteral + */ + public function getNumber() + { + return clone $this->number; + } + + /** + * Returns street elements + * @return StringLiteral + */ + public function getElements() + { + return clone $this->elements; + } + + /** + * Returns a string representation of the StringLiteral in the format defined in the constructor + * + * @return string + */ + public function __toString() + { + $replacements = array( + "%name%" => $this->getName(), + "%number%" => $this->getNumber(), + "%elements%" => $this->getElements() + ); + + $streetString = str_replace(array_keys($replacements), array_values($replacements), $this->format); + + return $streetString; + } +} diff --git a/src/Identity/UUID.php b/src/Identity/UUID.php new file mode 100644 index 0000000..af26ced --- /dev/null +++ b/src/Identity/UUID.php @@ -0,0 +1,73 @@ +toNative(); + + return $uuidString; + } + + public function __construct($value = null) + { + $uuid_str = BaseUuid::uuid4(); + + if (null !== $value) { + $pattern = '/'.BaseUuid::VALID_PATTERN.'/'; + + if (! \preg_match($pattern, $value)) { + throw new InvalidNativeArgumentException($value, array('UUID string')); + } + + $uuid_str = $value; + } + + $this->value = \strval($uuid_str); + } + + /** + * Tells whether two UUID are equal by comparing their values + * + * @param UUID $uuid + * @return bool + */ + public function sameValueAs(ValueObjectInterface $uuid) + { + if (false === Util::classEquals($this, $uuid)) { + return false; + } + + return $this->toNative() === $uuid->toNative(); + } +} diff --git a/src/Money/Currency.php b/src/Money/Currency.php new file mode 100644 index 0000000..2bd1496 --- /dev/null +++ b/src/Money/Currency.php @@ -0,0 +1,70 @@ +code = $code; + $this->currency = new BaseCurrency($code->toNative()); + } + + /** + * Tells whether two Currency are equal by comparing their names + * + * @param ValueObjectInterface $currency + * @return bool + */ + public function sameValueAs(ValueObjectInterface $currency) + { + if (false === Util::classEquals($this, $currency)) { + return false; + } + + return $this->getCode()->toNative() == $currency->getCode()->toNative(); + } + + /** + * Returns currency code + * + * @return CurrencyCode + */ + public function getCode() + { + return $this->code; + } + + /** + * Returns string representation of the currency + * + * @return string + */ + public function __toString() + { + return $this->getCode()->toNative(); + } +} diff --git a/src/Money/CurrencyCode.php b/src/Money/CurrencyCode.php new file mode 100644 index 0000000..3fa63b8 --- /dev/null +++ b/src/Money/CurrencyCode.php @@ -0,0 +1,169 @@ +getCode()->toNative()); + $this->money = new BaseMoney($amount->toNative(), $baseCurrency); + $this->currency = $currency; + } + + /** + * Tells whether two Currency are equal by comparing their amount and currency + * + * @param ValueObjectInterface $money + * @return bool + */ + public function sameValueAs(ValueObjectInterface $money) + { + if (false === Util::classEquals($this, $money)) { + return false; + } + + return $this->getAmount()->sameValueAs($money->getAmount()) && $this->getCurrency()->sameValueAs($money->getCurrency()); + } + + /** + * Returns money amount + * + * @return \ValueObjects\Number\Integer + */ + public function getAmount() + { + $amount = new Integer($this->money->getAmount()); + + return $amount; + } + + /** + * Returns money currency + * + * @return Currency + */ + public function getCurrency() + { + return clone $this->currency; + } + + /** + * Add an integer quantity to the amount and returns a new Money object. + * Use a negative quantity for subtraction. + * + * @param \ValueObjects\Number\Integer $quantity Quantity to add + * @return Money + */ + public function add(Integer $quantity) + { + $amount = new Integer($this->getAmount()->toNative() + $quantity->toNative()); + $result = new static($amount, $this->getCurrency()); + + return $result; + } + + /** + * Multiply the Money amount for a given number and returns a new Money object. + * Use 0 < Real $multipler < 1 for division. + * + * @param Real $multiplier + * @param mixed $rounding_mode Rounding mode of the operation. Defaults to RoundingMode::HALF_UP. + * @return Money + */ + public function multiply(Real $multiplier, RoundingMode $rounding_mode = null) + { + if (null === $rounding_mode) { + $rounding_mode = RoundingMode::HALF_UP(); + } + + $amount = $this->getAmount()->toNative() * $multiplier->toNative(); + $roundedAmount = new Integer(round($amount, 0, $rounding_mode->toNative())); + $result = new static($roundedAmount, $this->getCurrency()); + + return $result; + } + + /** + * Returns a string representation of the Money value in format "CUR AMOUNT" (e.g.: EUR 1000) + * + * @return string + */ + public function __toString() + { + return \sprintf('%s %d', $this->getCurrency()->getCode(), $this->getAmount()->toNative()); + } +} diff --git a/src/NullValue/NullValue.php b/src/NullValue/NullValue.php new file mode 100644 index 0000000..1ec0930 --- /dev/null +++ b/src/NullValue/NullValue.php @@ -0,0 +1,47 @@ +toNative() * \cos($argument->toNative()); + $imValue = $modulus->toNative() * \sin($argument->toNative()); + $real = new Real($realValue); + $im = new Real($imValue); + $complex = new static($real, $im); + + return $complex; + } + + /** + * Returns a Complex object give its real and imaginary parts as parameters + * + * @param Real $real + * @param Real $im + */ + public function __construct(Real $real, Real $im) + { + $this->real = $real; + $this->im = $im; + } + + public function sameValueAs(ValueObjectInterface $complex) + { + if (false === Util::classEquals($this, $complex)) { + return false; + } + + return $this->getReal()->sameValueAs($complex->getReal()) && + $this->getIm()->sameValueAs($complex->getIm()); + } + + /** + * Returns the native value of the real and imaginary parts as an array + * + * @return array + */ + public function toNative() + { + return array( + $this->getReal()->toNative(), + $this->getIm()->toNative() + ); + } + + /** + * Returns the real part of the complex number + * + * @return Real + */ + public function getReal() + { + return clone $this->real; + } + + /** + * Returns the imaginary part of the complex number + * + * @return Real + */ + public function getIm() + { + return clone $this->im; + } + + /** + * Returns the modulus (or absolute value or magnitude) of the Complex number + * + * @return Real + */ + public function getModulus() + { + $real = $this->getReal()->toNative(); + $im = $this->getIm()->toNative(); + $mod = \sqrt(\pow($real, 2) + \pow($im, 2)); + + return new Real($mod); + } + + /** + * Returns the argument (or phase) of the Complex number + * + * @return Real + */ + public function getArgument() + { + $real = $this->getReal()->toNative(); + $im = $this->getIm()->toNative(); + $arg = \atan2($im, $real); + + return new Real($arg); + } + + /** + * Returns a native string version of the Complex object in format "${real} +|- ${complex}i" + * + * @return string + */ + public function __toString() + { + $format = '%g %+gi'; + $real = $this->getReal()->toNative(); + $im = $this->getIm()->toNative(); + $string = \sprintf($format, $real, $im); + + return \preg_replace('/(\+|-)/', '$1 ', $string); + } +} diff --git a/src/Number/Integer.php b/src/Number/Integer.php new file mode 100644 index 0000000..b53ad82 --- /dev/null +++ b/src/Number/Integer.php @@ -0,0 +1,66 @@ +toNative() === $integer->toNative(); + } + + /** + * Returns the value of the integer number + * + * @return int + */ + public function toNative() + { + $value = parent::toNative(); + + return \intval($value); + } + + /** + * Returns a Real with the value of the Integer + * + * @return Real + */ + public function toReal() + { + $value = $this->toNative(); + $real = new Real($value); + + return $real; + } +} diff --git a/src/Number/Natural.php b/src/Number/Natural.php new file mode 100644 index 0000000..261fa36 --- /dev/null +++ b/src/Number/Natural.php @@ -0,0 +1,30 @@ + array( + 'min_range' => 0 + ) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0)')); + } + + parent::__construct($value); + } +} diff --git a/src/Number/NumberInterface.php b/src/Number/NumberInterface.php new file mode 100644 index 0000000..950db61 --- /dev/null +++ b/src/Number/NumberInterface.php @@ -0,0 +1,13 @@ +value = $value; + } + + /** + * Returns the native value of the real number + * + * @return float + */ + public function toNative() + { + return $this->value; + } + + /** + * Tells whether two Real are equal by comparing their values + * + * @param ValueObjectInterface $real + * @return bool + */ + public function sameValueAs(ValueObjectInterface $real) + { + if (false === Util::classEquals($this, $real)) { + return false; + } + + return $this->toNative() === $real->toNative(); + } + + /** + * Returns the integer part of the Real number as a Integer + * + * @param RoundingMode $rounding_mode Rounding mode of the conversion. Defaults to RoundingMode::HALF_UP. + * @return Integer + */ + public function toInteger(RoundingMode $rounding_mode = null) + { + if (null === $rounding_mode) { + $rounding_mode = RoundingMode::HALF_UP(); + } + + $value = $this->toNative(); + $integerValue = \round($value, 0, $rounding_mode->toNative()); + $integer = new Integer($integerValue); + + return $integer; + } + + /** + * Returns the absolute integer part of the Real number as a Natural + * + * @param RoundingMode $rounding_mode Rounding mode of the conversion. Defaults to RoundingMode::HALF_UP. + * @return Natural + */ + public function toNatural(RoundingMode $rounding_mode = null) + { + $integerValue = $this->toInteger($rounding_mode)->toNative(); + $naturalValue = \abs($integerValue); + $natural = new Natural($naturalValue); + + return $natural; + } + + /** + * Returns the string representation of the real value + * + * @return string + */ + public function __toString() + { + return \strval($this->toNative()); + } +} diff --git a/src/Number/RoundingMode.php b/src/Number/RoundingMode.php new file mode 100644 index 0000000..4e20dcf --- /dev/null +++ b/src/Number/RoundingMode.php @@ -0,0 +1,13 @@ +firstName = $first_name; + $this->middleName = $middle_name; + $this->lastName = $last_name; + } + + /** + * Returns the first name + * + * @return StringLiteral + */ + public function getFirstName() + { + return $this->firstName; + } + + /** + * Returns the middle name + * + * @return StringLiteral + */ + public function getMiddleName() + { + return $this->middleName; + } + + /** + * Returns the last name + * + * @return StringLiteral + */ + public function getLastName() + { + return $this->lastName; + } + + /** + * Returns the full name + * + * @return StringLiteral + */ + public function getFullName() + { + $fullNameString = $this->firstName . + ($this->middleName->isEmpty() ? '' : ' ' . $this->middleName) . + ($this->lastName->isEmpty() ? '' : ' ' . $this->lastName); + + $fullName = new StringLiteral($fullNameString); + + return $fullName; + } + + /** + * Tells whether two names are equal by comparing their values + * + * @param ValueObjectInterface $name + * @return bool + */ + public function sameValueAs(ValueObjectInterface $name) + { + if (false === Util::classEquals($this, $name)) { + return false; + } + + return $this->getFullName() == $name->getFullName(); + } + + /** + * Returns the full name + * + * @return string + */ + public function __toString() + { + return \strval($this->getFullName()); + } +} diff --git a/src/StringLiteral/StringLiteral.php b/src/StringLiteral/StringLiteral.php new file mode 100644 index 0000000..66b059c --- /dev/null +++ b/src/StringLiteral/StringLiteral.php @@ -0,0 +1,84 @@ +value = $value; + } + + /** + * Returns the value of the string + * + * @return string + */ + public function toNative() + { + return $this->value; + } + + /** + * Tells whether two string literals are equal by comparing their values + * + * @param ValueObjectInterface $stringLiteral + * @return bool + */ + public function sameValueAs(ValueObjectInterface $stringLiteral) + { + if (false === Util::classEquals($this, $stringLiteral)) { + return false; + } + + return $this->toNative() === $stringLiteral->toNative(); + } + + /** + * Tells whether the StringLiteral is empty + * + * @return bool + */ + public function isEmpty() + { + return \strlen($this->toNative()) == 0; + } + + /** + * Returns the string value itself + * + * @return string + */ + public function __toString() + { + return $this->toNative(); + } +} diff --git a/src/Structure/Collection.php b/src/Structure/Collection.php new file mode 100644 index 0000000..cc6be1d --- /dev/null +++ b/src/Structure/Collection.php @@ -0,0 +1,127 @@ +items = $items; + } + + /** + * Tells whether two Collection are equal by comparing their size and items (item order matters) + * + * @param ValueObjectInterface $collection + * @return bool + */ + public function sameValueAs(ValueObjectInterface $collection) + { + if (false === Util::classEquals($this, $collection) || false === $this->count()->sameValueAs($collection->count())) { + return false; + } + + $arrayCollection = $collection->toArray(); + + foreach ($this->items as $index => $item) { + if (!isset($arrayCollection[$index]) || false === $item->sameValueAs($arrayCollection[$index])) { + return false; + } + } + + return true; + } + + /** + * Returns the number of objects in the collection + * + * @return Natural + */ + public function count() + { + return new Natural($this->items->count()); + } + + /** + * Tells whether the Collection contains an object + * + * @param ValueObjectInterface $object + * @return bool + */ + public function contains(ValueObjectInterface $object) + { + foreach ($this->items as $item) { + if ($item->sameValueAs($object)) { + return true; + } + } + + return false; + } + + /** + * Returns a native array representation of the Collection + * + * @return array + */ + public function toArray() + { + return $this->items->toArray(); + } + + /** + * Returns a native string representation of the Collection object + * + * @return string + */ + public function __toString() + { + $string = \sprintf('%s(%d)', \get_class($this), $this->count()->toNative()); + + return $string; + } +} diff --git a/src/Structure/Dictionary.php b/src/Structure/Dictionary.php new file mode 100644 index 0000000..aaa124c --- /dev/null +++ b/src/Structure/Dictionary.php @@ -0,0 +1,114 @@ + $arrayValue) { + $key = new StringLiteral(\strval($arrayKey)); + + if ($arrayValue instanceof \Traversable || \is_array($arrayValue)) { + $value = Collection::fromNative($arrayValue); + } else { + $value = new StringLiteral(\strval($arrayValue)); + } + + $keyValuePairs[] = new KeyValuePair($key, $value); + } + + $fixedArray = \SplFixedArray::fromArray($keyValuePairs); + + return new static($fixedArray); + } + + /** + * Returns a new Dictionary object + * + * @param \SplFixedArray $key_value_pairs + */ + public function __construct(\SplFixedArray $key_value_pairs) + { + foreach ($key_value_pairs as $keyValuePair) { + if (false === $keyValuePair instanceof KeyValuePair) { + $type = \is_object($keyValuePair) ? \get_class($keyValuePair) : \gettype($keyValuePair); + throw new \InvalidArgumentException(\sprintf('Passed SplFixedArray object must contains "KeyValuePair" objects only. "%s" given.', $type)); + } + } + + $this->items = $key_value_pairs; + } + + /** + * Returns a Collection of the keys + * + * @return Collection + */ + public function keys() + { + $count = $this->count()->toNative(); + $keysArray = new \SplFixedArray($count); + + foreach ($this->items as $key => $item) { + $keysArray->offsetSet($key, $item->getKey()); + } + + return new Collection($keysArray); + } + + /** + * Returns a Collection of the values + * + * @return Collection + */ + public function values() + { + $count = $this->count()->toNative(); + $valuesArray = new \SplFixedArray($count); + + foreach ($this->items as $key => $item) { + $valuesArray->offsetSet($key, $item->getValue()); + } + + return new Collection($valuesArray); + } + + /** + * Tells whether $object is one of the keys + * + * @param ValueObjectInterface $object + * @return bool + */ + public function containsKey(ValueObjectInterface $object) + { + $keys = $this->keys(); + + return $keys->contains($object); + } + + /** + * Tells whether $object is one of the values + * + * @param ValueObjectInterface $object + * @return bool + */ + public function containsValue(ValueObjectInterface $object) + { + $values = $this->values(); + + return $values->contains($object); + } +} diff --git a/src/Structure/KeyValuePair.php b/src/Structure/KeyValuePair.php new file mode 100644 index 0000000..049e79b --- /dev/null +++ b/src/Structure/KeyValuePair.php @@ -0,0 +1,99 @@ +key = $key; + $this->value = $value; + } + + /** + * Tells whether two KeyValuePair are equal + * + * @param ValueObjectInterface $keyValuePair + * @return bool + */ + public function sameValueAs(ValueObjectInterface $keyValuePair) + { + if (false === Util::classEquals($this, $keyValuePair)) { + return false; + } + + return $this->getKey()->sameValueAs($keyValuePair->getKey()) && $this->getValue()->sameValueAs($keyValuePair->getValue()); + } + + /** + * Returns key + * + * @return ValueObjectInterface + */ + public function getKey() + { + return clone $this->key; + } + + /** + * Returns value + * + * @return ValueObjectInterface + */ + public function getValue() + { + return clone $this->value; + } + + /** + * Returns a string representation of the KeyValuePair in format "$key => $value" + * + * @return string + */ + public function __toString() + { + $string = sprintf('%s => %s', $this->getKey(), $this->getValue()); + + return $string; + } +} diff --git a/src/Util/Util.php b/src/Util/Util.php new file mode 100644 index 0000000..543c3a8 --- /dev/null +++ b/src/Util/Util.php @@ -0,0 +1,33 @@ +value = $filteredValue; + } + + /** + * Returns the local part of the email address + * + * @return StringLiteral + */ + public function getLocalPart() + { + $parts = explode('@', $this->toNative()); + $localPart = new StringLiteral($parts[0]); + + return $localPart; + } + + /** + * Returns the domain part of the email address + * + * @return Domain + */ + public function getDomainPart() + { + $parts = \explode('@', $this->toNative()); + $domain = \trim($parts[1], '[]'); + + return Domain::specifyType($domain); + } +} diff --git a/src/Web/FragmentIdentifier.php b/src/Web/FragmentIdentifier.php new file mode 100644 index 0000000..5787903 --- /dev/null +++ b/src/Web/FragmentIdentifier.php @@ -0,0 +1,23 @@ +value = $value; + } +} diff --git a/src/Web/FragmentIdentifierInterface.php b/src/Web/FragmentIdentifierInterface.php new file mode 100644 index 0000000..a4d23b1 --- /dev/null +++ b/src/Web/FragmentIdentifierInterface.php @@ -0,0 +1,7 @@ + Validator::ALLOW_DNS | Validator::ALLOW_LOCAL)); + + if (false === $validator->isValid($value)) { + throw new InvalidNativeArgumentException($value, array('string (valid hostname)')); + } + + $this->value = $value; + } +} diff --git a/src/Web/IPAddress.php b/src/Web/IPAddress.php new file mode 100644 index 0000000..c972217 --- /dev/null +++ b/src/Web/IPAddress.php @@ -0,0 +1,40 @@ +value = $filteredValue; + } + + /** + * Returns the version (IPv4 or IPv6) of the ip address + * + * @return IPAddressVersion + */ + public function getVersion() + { + $isIPv4 = filter_var($this->toNative(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + + if (false !== $isIPv4) { + return IPAddressVersion::IPV4(); + } + + return IPAddressVersion::IPV6(); + } +} diff --git a/src/Web/IPAddressVersion.php b/src/Web/IPAddressVersion.php new file mode 100644 index 0000000..2169ef3 --- /dev/null +++ b/src/Web/IPAddressVersion.php @@ -0,0 +1,11 @@ +value = $filteredValue; + } +} diff --git a/src/Web/IPv6Address.php b/src/Web/IPv6Address.php new file mode 100644 index 0000000..4222725 --- /dev/null +++ b/src/Web/IPv6Address.php @@ -0,0 +1,24 @@ +value = $filteredValue; + } +} diff --git a/src/Web/NullFragmentIdentifier.php b/src/Web/NullFragmentIdentifier.php new file mode 100644 index 0000000..4255077 --- /dev/null +++ b/src/Web/NullFragmentIdentifier.php @@ -0,0 +1,15 @@ +value = ''; + } +} diff --git a/src/Web/NullPortNumber.php b/src/Web/NullPortNumber.php new file mode 100644 index 0000000..eaaa705 --- /dev/null +++ b/src/Web/NullPortNumber.php @@ -0,0 +1,9 @@ +value = ''; + } +} diff --git a/src/Web/Path.php b/src/Web/Path.php new file mode 100644 index 0000000..76d631b --- /dev/null +++ b/src/Web/Path.php @@ -0,0 +1,20 @@ +value = $filteredValue; + } +} diff --git a/src/Web/PortNumber.php b/src/Web/PortNumber.php new file mode 100644 index 0000000..29db4f8 --- /dev/null +++ b/src/Web/PortNumber.php @@ -0,0 +1,32 @@ + array( + 'min_range' => 0, + 'max_range' => 65535 + ) + ); + + $value = filter_var($value, FILTER_VALIDATE_INT, $options); + + if (false === $value) { + throw new InvalidNativeArgumentException($value, array('int (>=0, <=65535)')); + } + + parent::__construct($value); + } +} diff --git a/src/Web/PortNumberInterface.php b/src/Web/PortNumberInterface.php new file mode 100644 index 0000000..1d94909 --- /dev/null +++ b/src/Web/PortNumberInterface.php @@ -0,0 +1,7 @@ +value = $value; + } + + /** + * Returns a Dictionary structured representation of the query string + * + * @return Dictionary + */ + public function toDictionary() + { + $value = \ltrim($this->toNative(), '?'); + \parse_str($value, $data); + + return Dictionary::fromNative($data); + } +} diff --git a/src/Web/QueryStringInterface.php b/src/Web/QueryStringInterface.php new file mode 100644 index 0000000..9acb4b8 --- /dev/null +++ b/src/Web/QueryStringInterface.php @@ -0,0 +1,8 @@ +value = $value; + } +} diff --git a/src/Web/Url.php b/src/Web/Url.php new file mode 100644 index 0000000..bede0d9 --- /dev/null +++ b/src/Web/Url.php @@ -0,0 +1,216 @@ +scheme = $scheme; + $this->user = $user; + $this->password = $password; + $this->domain = $domain; + $this->path = $path; + $this->port = $port; + $this->queryString = $query; + $this->fragmentIdentifier = $fragment; + } + + /** + * Tells whether two Url are sameValueAs by comparing their components + * + * @param ValueObjectInterface $url + * @return bool + */ + public function sameValueAs(ValueObjectInterface $url) + { + if (false === Util::classEquals($this, $url)) { + return false; + } + + return $this->getScheme()->sameValueAs($url->getScheme()) && + $this->getUser()->sameValueAs($url->getUser()) && + $this->getPassword()->sameValueAs($url->getPassword()) && + $this->getDomain()->sameValueAs($url->getDomain()) && + $this->getPath()->sameValueAs($url->getPath()) && + $this->getPort()->sameValueAs($url->getPort()) && + $this->getQueryString()->sameValueAs($url->getQueryString()) && + $this->getFragmentIdentifier()->sameValueAs($url->getFragmentIdentifier()) + ; + } + + /** + * Returns the domain of the Url + * + * @return Hostname|IPAddress + */ + public function getDomain() + { + return clone $this->domain; + } + + /** + * Returns the fragment identifier of the Url + * + * @return FragmentIdentifier + */ + public function getFragmentIdentifier() + { + return clone $this->fragmentIdentifier; + } + + /** + * Returns the password part of the Url + * + * @return StringLiteral + */ + public function getPassword() + { + return clone $this->password; + } + + /** + * Returns the path of the Url + * + * @return Path + */ + public function getPath() + { + return clone $this->path; + } + + /** + * Returns the port of the Url + * + * @return PortNumberInterface + */ + public function getPort() + { + return clone $this->port; + } + + /** + * Returns the query string of the Url + * + * @return QueryString + */ + public function getQueryString() + { + return clone $this->queryString; + } + + /** + * Returns the scheme of the Url + * + * @return SchemeName + */ + public function getScheme() + { + return clone $this->scheme; + } + + /** + * Returns the user part of the Url + * + * @return StringLiteral + */ + public function getUser() + { + return clone $this->user; + } + + /** + * Returns a string representation of the url + * + * @return string + */ + public function __toString() + { + $userPass = ''; + if (false === $this->getUser()->isEmpty()) { + $userPass = \sprintf('%s@', $this->getUser()); + + if (false === $this->getPassword()->isEmpty()) { + $userPass = \sprintf('%s:%s@', $this->getUser(), $this->getPassword()); + } + } + + $port = ''; + if (false === NullPortNumber::create()->sameValueAs($this->getPort())) { + $port = \sprintf(':%d', $this->getPort()->toNative()); + } + + $urlString = \sprintf('%s://%s%s%s%s%s%s', $this->getScheme(), $userPass, $this->getDomain(), $port, $this->getPath(), $this->getQueryString(), $this->getFragmentIdentifier()); + + return $urlString; + } +} diff --git a/tests/Climate/CelsiusTest.php b/tests/Climate/CelsiusTest.php new file mode 100644 index 0000000..ab2a976 --- /dev/null +++ b/tests/Climate/CelsiusTest.php @@ -0,0 +1,37 @@ +assertEquals(10, $temperature->toCelsius()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToKelvin(Celsius $temperature) + { + $this->assertEquals(10 + 273.15, $temperature->toKelvin()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToFahrenheit(Celsius $temperature) + { + $this->assertEquals(10 * 1.8 + 32, $temperature->toFahrenheit()->toNative()); + } +} diff --git a/tests/Climate/FahrenheitTest.php b/tests/Climate/FahrenheitTest.php new file mode 100644 index 0000000..9b6ecd4 --- /dev/null +++ b/tests/Climate/FahrenheitTest.php @@ -0,0 +1,37 @@ +assertEquals((10 - 32) / 1.8, $temperature->toCelsius()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToKelvin(Fahrenheit $temperature) + { + $this->assertEquals($temperature->toCelsius()->toNative() + 273.15, $temperature->toKelvin()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToFahrenheit(Fahrenheit $temperature) + { + $this->assertEquals(10, $temperature->toFahrenheit()->toNative()); + } +} diff --git a/tests/Climate/KelvinTest.php b/tests/Climate/KelvinTest.php new file mode 100644 index 0000000..01f6e0e --- /dev/null +++ b/tests/Climate/KelvinTest.php @@ -0,0 +1,37 @@ +assertEquals(10 - 273.15, $temperature->toCelsius()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToKelvin(Kelvin $temperature) + { + $this->assertEquals(10, $temperature->toKelvin()->toNative()); + } + + /** + * @dataProvider temperatureProvider + */ + public function testToFahrenheit(Kelvin $temperature) + { + $this->assertEquals($temperature->toCelsius()->toNative() * 1.8 + 32, $temperature->toFahrenheit()->toNative()); + } +} diff --git a/tests/Climate/RelativeHumidityTest.php b/tests/Climate/RelativeHumidityTest.php new file mode 100644 index 0000000..b53fa0c --- /dev/null +++ b/tests/Climate/RelativeHumidityTest.php @@ -0,0 +1,25 @@ +assertTrue($fromNativeRelHum->sameValueAs($constructedRelHum)); + } + + /** + * @expectedException \ValueObjects\Exception\InvalidNativeArgumentException + */ + public function testInvalidRelativeHumidity() + { + new RelativeHumidity(128); + } +} diff --git a/tests/DateTime/DateTest.php b/tests/DateTime/DateTest.php new file mode 100644 index 0000000..1c9c9ed --- /dev/null +++ b/tests/DateTime/DateTest.php @@ -0,0 +1,94 @@ +assertTrue($fromNativeDate->sameValueAs($constructedDate)); + } + + public function testFromNativeDateTime() + { + $nativeDate = new \DateTime(); + $nativeDate->setDate(2013, 12, 3); + $dateFromNative = Date::fromNativeDateTime($nativeDate); + $constructedDate = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + + $this->assertTrue($dateFromNative->sameValueAs($constructedDate)); + } + + public function testNow() + { + $date = Date::now(); + $this->assertEquals(date('Y-n-j'), \strval($date)); + } + + /** @expectedException ValueObjects\DateTime\Exception\InvalidDateException */ + public function testAlmostValidDateException() + { + new Date(new Year(2013), Month::FEBRUARY(), new MonthDay(31)); + } + + public function testSameValueAs() + { + $date1 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $date2 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $date3 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(5)); + + $this->assertTrue($date1->sameValueAs($date2)); + $this->assertFalse($date1->sameValueAs($date3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($date1->sameValueAs($mock)); + } + + public function testGetYear() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $year = new Year(2013); + + $this->assertTrue($year->sameValueAs($date->getYear())); + } + + public function testGetMonth() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $month = Month::DECEMBER(); + + $this->assertTrue($month->sameValueAs($date->getMonth())); + } + + public function testGetDay() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $day = new MonthDay(3); + + $this->assertTrue($day->sameValueAs($date->getDay())); + } + + public function testToNativeDateTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $nativeDate = \DateTime::createFromFormat('Y-n-j H:i:s', '2013-12-3 00:00:00'); + + $this->assertEquals($nativeDate, $date->toNativeDateTime()); + } + + public function testToString() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $this->assertEquals('2013-12-3', $date->__toString()); + } + +} diff --git a/tests/DateTime/DateTimeTest.php b/tests/DateTime/DateTimeTest.php new file mode 100644 index 0000000..258cbc6 --- /dev/null +++ b/tests/DateTime/DateTimeTest.php @@ -0,0 +1,111 @@ +assertTrue($fromNativeDateTime->sameValueAs($constructedDateTime)); + } + + public function testFromNativeDateTime() + { + $nativeDateTime = new \DateTime(); + $nativeDateTime->setDate(2013, 12, 6)->setTime(20, 50, 10); + $dateTimeFromNative = DateTime::fromNativeDateTime($nativeDateTime); + + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(6)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $constructedDateTime = new DateTime($date, $time); + + $this->assertTrue($dateTimeFromNative->sameValueAs($constructedDateTime)); + } + + public function testNow() + { + $dateTime = DateTime::now(); + $this->assertEquals(date('Y-n-j G:i:s'), \strval($dateTime)); + } + + public function testNullTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(21)); + $dateTime = new DateTime($date); + $this->assertTrue(Time::zero()->sameValueAs($dateTime->getTime())); + } + + public function testSameValueAs() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + + $date3 = new Date(new Year(2014), Month::MARCH(), new MonthDay(5)); + $time3 = new Time(new Hour(10), new Minute(52), new Second(40)); + + $dateTime1 = new DateTime($date, $time); + $dateTime2 = new DateTime($date, $time); + $dateTime3 = new DateTime($date3, $time3); + + $this->assertTrue($dateTime1->sameValueAs($dateTime2)); + $this->assertFalse($dateTime1->sameValueAs($dateTime3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($dateTime1->sameValueAs($mock)); + } + + public function testGetDate() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + + $this->assertTrue($date->sameValueAs($dateTime->getDate())); + } + + public function testGetTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + + $this->assertTrue($time->sameValueAs($dateTime->getTime())); + } + + public function testToNativeDateTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + $nativeDateTime = \DateTime::createFromFormat('Y-n-j H:i:s', '2013-12-3 20:50:10'); + + $this->assertEquals($nativeDateTime, $dateTime->toNativeDateTime()); + } + + public function testToString() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + + $this->assertEquals('2013-12-3 20:50:10', $dateTime->__toString()); + } + +} diff --git a/tests/DateTime/DateTimeWithTimeZoneTest.php b/tests/DateTime/DateTimeWithTimeZoneTest.php new file mode 100644 index 0000000..5e927ef --- /dev/null +++ b/tests/DateTime/DateTimeWithTimeZoneTest.php @@ -0,0 +1,140 @@ +assertTrue($fromNativeDateTimeWithTz->sameValueAs($constructedDateTimeWithTz)); + } + + public function testFromNativeDateTime() + { + $nativeDateTime = new \DateTime(); + $nativeDateTime->setTimeZone(new \DateTimeZone('Europe/Madrid'))->setDate(2013, 12, 6)->setTime(20, 50, 10); + $dateTimeWithTzFromNative = DateTimeWithTimeZone::fromNativeDateTime($nativeDateTime); + + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(6)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $timezone = new TimeZone(new StringLiteral('Europe/Madrid')); + $constructedDateTimeWithTz = new DateTimeWithTimeZone(new DateTime($date, $time), $timezone); + + $this->assertTrue($dateTimeWithTzFromNative->sameValueAs($constructedDateTimeWithTz)); + } + + public function testNow() + { + $dateTimeWithTz = DateTimeWithTimeZone::now(); + $this->assertEquals(date('Y-n-j G:i:s e'), \strval($dateTimeWithTz)); + } + + public function testSameValueAs() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + + $date3 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time3 = new Time(new Hour(20), new Minute(50), new Second(10)); + $timeZone3 = new TimeZone(new StringLiteral('Europe/London')); + + $dateTimeWithTz1 = new DateTimeWithTimeZone(new DateTime($date, $time), $timeZone); + $dateTimeWithTz2 = new DateTimeWithTimeZone(new DateTime($date, $time), $timeZone); + $dateTimeWithTz3 = new DateTimeWithTimeZone(new DateTime($date3, $time3), $timeZone3); + + $this->assertTrue($dateTimeWithTz1->sameValueAs($dateTimeWithTz2)); + $this->assertFalse($dateTimeWithTz1->sameValueAs($dateTimeWithTz3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($dateTimeWithTz1->sameValueAs($mock)); + } + + public function testSameTimestampAs() + { + $date1 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time1 = new Time(new Hour(20), new Minute(50), new Second(10)); + $timeZone1 = new TimeZone(new StringLiteral('Europe/Madrid')); + + $date2 = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time2 = new Time(new Hour(19), new Minute(50), new Second(10)); + $timeZone2 = new TimeZone(new StringLiteral('Europe/London')); + + $dateTimeWithTz1 = new DateTimeWithTimeZone(new DateTime($date1, $time1), $timeZone1); + $dateTimeWithTz2 = new DateTimeWithTimeZone(new DateTime($date2, $time2), $timeZone2); + + $this->assertTrue($dateTimeWithTz1->sameTimestampAs($dateTimeWithTz2)); + $this->assertFalse($dateTimeWithTz1->sameValueAs($dateTimeWithTz2)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($dateTimeWithTz1->sameTimestampAs($mock)); + } + + public function testGetDateTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + $dateTimeWithTz = new DateTimeWithTimeZone($dateTime, $timeZone); + + $this->assertTrue($dateTime->sameValueAs($dateTimeWithTz->getDateTime())); + } + + public function testGetTimeZone() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + $dateTimeWithTz = new DateTimeWithTimeZone($dateTime, $timeZone); + + $this->assertTrue($timeZone->sameValueAs($dateTimeWithTz->getTimeZone())); + } + + public function testToNativeDateTime() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + $dateTimeWithTz = new DateTimeWithTimeZone($dateTime, $timeZone); + $nativeDateTime = \DateTime::createFromFormat('Y-n-j H:i:s e', '2013-12-3 20:50:10 Europe/Madrid'); + + $this->assertEquals($nativeDateTime, $dateTimeWithTz->toNativeDateTime()); + } + + public function testToString() + { + $date = new Date(new Year(2013), Month::DECEMBER(), new MonthDay(3)); + $time = new Time(new Hour(20), new Minute(50), new Second(10)); + $dateTime = new DateTime($date, $time); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + $dateTimeWithTz = new DateTimeWithTimeZone($dateTime, $timeZone); + + $this->assertEquals('2013-12-3 20:50:10 Europe/Madrid', $dateTimeWithTz->__toString()); + } +} diff --git a/tests/DateTime/HourTest.php b/tests/DateTime/HourTest.php new file mode 100644 index 0000000..0b7c5ee --- /dev/null +++ b/tests/DateTime/HourTest.php @@ -0,0 +1,30 @@ +assertTrue($fromNativeHour->sameValueAs($constructedHour)); + } + + public function testNow() + { + $hour = Hour::now(); + $this->assertEquals(date('G'), $hour->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidHour() + { + new Hour(24); + } + +} diff --git a/tests/DateTime/MinuteTest.php b/tests/DateTime/MinuteTest.php new file mode 100644 index 0000000..df8b0ef --- /dev/null +++ b/tests/DateTime/MinuteTest.php @@ -0,0 +1,30 @@ +assertTrue($fromNativeMinute->sameValueAs($constructedMinute)); + } + + public function testNow() + { + $minute = Minute::now(); + $this->assertEquals(\intval(date('i')), $minute->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidMinute() + { + new Minute(60); + } + +} diff --git a/tests/DateTime/MonthDayTest.php b/tests/DateTime/MonthDayTest.php new file mode 100644 index 0000000..0b551b8 --- /dev/null +++ b/tests/DateTime/MonthDayTest.php @@ -0,0 +1,30 @@ +assertTrue($fromNativeMonthDay->sameValueAs($constructedMonthDay)); + } + + public function testNow() + { + $monthDay = MonthDay::now(); + $this->assertEquals(date('j'), $monthDay->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidMonthDay() + { + new MonthDay(32); + } + +} diff --git a/tests/DateTime/MonthTest.php b/tests/DateTime/MonthTest.php new file mode 100644 index 0000000..36bed1a --- /dev/null +++ b/tests/DateTime/MonthTest.php @@ -0,0 +1,33 @@ +assertEquals(date('F'), $month->toNative()); + } + + public function testFromNativeDateTime() + { + $nativeDateTime = new \DateTime(); + $nativeDateTime->setDate(2013, 12, 1); + + $month = Month::fromNativeDateTime($nativeDateTime); + + $this->assertEquals('December', $month->toNative()); + } + + public function testGetNumericValue() + { + $month = Month::APRIL(); + + $this->assertEquals(4, $month->getNumericValue()); + } + +} diff --git a/tests/DateTime/SecondTest.php b/tests/DateTime/SecondTest.php new file mode 100644 index 0000000..24eff83 --- /dev/null +++ b/tests/DateTime/SecondTest.php @@ -0,0 +1,30 @@ +assertTrue($fromNativeSecond->sameValueAs($constructedSecond)); + } + + public function testNow() + { + $second = Second::now(); + $this->assertEquals(\intval(date('s')), $second->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidSecond() + { + new Second(60); + } + +} diff --git a/tests/DateTime/TimeTest.php b/tests/DateTime/TimeTest.php new file mode 100644 index 0000000..61aac5f --- /dev/null +++ b/tests/DateTime/TimeTest.php @@ -0,0 +1,94 @@ +assertTrue($fromNativeTime->sameValueAs($constructedTime)); + } + + public function testFromNativeDateTime() + { + $nativeTime = new \DateTime(); + $nativeTime->setTime(20, 10, 34); + $timeFromNative = Time::fromNativeDateTime($nativeTime); + $constructedTime = new Time(new Hour(20), new Minute(10), new Second(34)); + + $this->assertTrue($timeFromNative->sameValueAs($constructedTime)); + } + + public function testNow() + { + $time = Time::now(); + $this->assertEquals(date('G:i:s'), \strval($time)); + } + + public function testZero() + { + $time = Time::zero(); + $this->assertEquals('0:00:00', \strval($time)); + } + + public function testSameValueAs() + { + $time1 = new Time(new Hour(20), new Minute(10), new Second(34)); + $time2 = new Time(new Hour(20), new Minute(10), new Second(34)); + $time3 = new Time(new Hour(20), new Minute(1), new Second(10)); + + $this->assertTrue($time1->sameValueAs($time2)); + $this->assertFalse($time1->sameValueAs($time3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($time1->sameValueAs($mock)); + } + + public function testGetHour() + { + $time = new Time(new Hour(20), new Minute(10), new Second(34)); + $hour = new Hour(20); + + $this->assertTrue($hour->sameValueAs($time->getHour())); + } + + public function testGetMinute() + { + $time = new Time(new Hour(20), new Minute(10), new Second(34)); + $minute = new Minute(10); + + $this->assertTrue($minute->sameValueAs($time->getMinute())); + } + + public function testGetSecond() + { + $time = new Time(new Hour(20), new Minute(10), new Second(34)); + $day = new Second(34); + + $this->assertTrue($day->sameValueAs($time->getSecond())); + } + + public function testToNativeDateTime() + { + $time = new Time(new Hour(20), new Minute(10), new Second(34)); + $nativeTime = \DateTime::createFromFormat('H:i:s', '20:10:34'); + + $this->assertEquals($nativeTime, $time->toNativeDateTime()); + } + + public function testToString() + { + $time = new Time(new Hour(20), new Minute(10), new Second(34)); + $this->assertEquals('20:10:34', $time->__toString()); + } + +} diff --git a/tests/DateTime/TimeZoneTest.php b/tests/DateTime/TimeZoneTest.php new file mode 100644 index 0000000..01b67a6 --- /dev/null +++ b/tests/DateTime/TimeZoneTest.php @@ -0,0 +1,78 @@ +assertTrue($fromNativeTimeZone->sameValueAs($constructedTimeZone)); + } + + public function testFromNativeDateTimeZone() + { + $nativeTimeZone = new \DateTimeZone('Europe/Madrid'); + $timeZoneFromNative = TimeZone::fromNativeDateTimeZone($nativeTimeZone); + + $constructedTimeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + + $this->assertTrue($timeZoneFromNative->sameValueAs($constructedTimeZone)); + } + + public function testDefaultTz() + { + $timeZone = TimeZone::fromDefault(); + $this->assertEquals(date_default_timezone_get(), \strval($timeZone)); + } + + public function testSameValueAs() + { + $timeZone1 = new TimeZone(new StringLiteral('Europe/Madrid')); + $timeZone2 = new TimeZone(new StringLiteral('Europe/Madrid')); + $timeZone3 = new TimeZone(new StringLiteral('Europe/Berlin')); + + $this->assertTrue($timeZone1->sameValueAs($timeZone2)); + $this->assertFalse($timeZone1->sameValueAs($timeZone3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($timeZone1->sameValueAs($mock)); + } + + public function testGetName() + { + $name = new StringLiteral('Europe/Madrid'); + $timeZone = new TimeZone($name); + + $this->assertTrue($name->sameValueAs($timeZone->getName())); + } + + public function testToNativeDateTimeZone() + { + $nativeTimeZone = new \DateTimeZone('Europe/Madrid'); + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + + $this->assertEquals($nativeTimeZone, $timeZone->toNativeDateTimeZone()); + } + + public function testToString() + { + $timeZone = new TimeZone(new StringLiteral('Europe/Madrid')); + + $this->assertEquals('Europe/Madrid', $timeZone->__toString()); + } + + /** + * @expectedException \ValueObjects\DateTime\Exception\InvalidTimeZoneException + */ + public function testExceptionOnInvalidTimeZoneName() + { + $timeZone = new TimeZone(new StringLiteral('Mars/Phobos')); + } +} diff --git a/tests/DateTime/WeekDayTest.php b/tests/DateTime/WeekDayTest.php new file mode 100644 index 0000000..a26b926 --- /dev/null +++ b/tests/DateTime/WeekDayTest.php @@ -0,0 +1,33 @@ +assertEquals(date('l'), $weekDay->toNative()); + } + + public function testFromNativeDateTime() + { + $nativeDateTime = new \DateTime(); + $nativeDateTime->setDate(2013, 12, 14); + + $weekDay = WeekDay::fromNativeDateTime($nativeDateTime); + + $this->assertEquals('Saturday', $weekDay->toNative()); + } + + public function testGetNumericValue() + { + $weekDay = WeekDay::SATURDAY(); + + $this->assertEquals(6, $weekDay->getNumericValue()); + } + +} diff --git a/tests/DateTime/YearTest.php b/tests/DateTime/YearTest.php new file mode 100644 index 0000000..2f7af77 --- /dev/null +++ b/tests/DateTime/YearTest.php @@ -0,0 +1,16 @@ +assertEquals(date('Y'), $year->toNative()); + } + +} diff --git a/tests/Enum/EnumTest.php b/tests/Enum/EnumTest.php new file mode 100644 index 0000000..9e5f1e4 --- /dev/null +++ b/tests/Enum/EnumTest.php @@ -0,0 +1,27 @@ +getMock('ValueObjects\Enum\Enum', array(), array(), '', false); + $stub2 = $this->getMock('ValueObjects\Enum\Enum', array(), array(), '', false); + + $stub1->expects($this->any()) + ->method('sameValueAs') + ->will($this->returnValue(true)); + + $this->assertTrue($stub1->sameValueAs($stub2)); + } + + public function testToString() + { + $stub = $this->getMock('ValueObjects\Enum\Enum', array(), array(), '', false); + + $this->assertEquals('', $stub->__toString()); + } +} diff --git a/tests/Geography/AddressTest.php b/tests/Geography/AddressTest.php new file mode 100644 index 0000000..6380482 --- /dev/null +++ b/tests/Geography/AddressTest.php @@ -0,0 +1,125 @@ +address = new Address( + new StringLiteral('Nicolò Pignatelli'), + new Street(new StringLiteral('via Manara'), new StringLiteral('3')), + new StringLiteral(''), + new StringLiteral('Altamura'), + new StringLiteral('BARI'), + new StringLiteral('70022'), + new Country(CountryCode::IT()) + ); + } + + public function testFromNative() + { + $fromNativeAddress = Address::fromNative('Nicolò Pignatelli', 'via Manara', '3', '', 'Altamura', 'BARI', '70022', 'IT'); + $this->assertTrue($this->address->sameValueAs($fromNativeAddress)); + } + + /** @expectedException \BadMethodCallException */ + public function testInvalidFromNative() + { + Address::fromNative('invalid'); + } + + public function testSameValueAs() + { + $address2 = new Address( + new StringLiteral('Nicolò Pignatelli'), + new Street(new StringLiteral('via Manara'), new StringLiteral('3')), + new StringLiteral(''), + new StringLiteral('Altamura'), + new StringLiteral('BARI'), + new StringLiteral('70022'), + new Country(CountryCode::IT()) + ); + + $address3 = new Address( + new StringLiteral('Nicolò Pignatelli'), + new Street(new StringLiteral('SP159'), new StringLiteral('km 4')), + new StringLiteral(''), + new StringLiteral('Altamura'), + new StringLiteral('BARI'), + new StringLiteral('70022'), + new Country(CountryCode::IT()) + ); + + $this->assertTrue($this->address->sameValueAs($address2)); + $this->assertTrue($address2->sameValueAs($this->address)); + $this->assertFalse($this->address->sameValueAs($address3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->address->sameValueAs($mock)); + } + + public function testGetName() + { + $name = new StringLiteral('Nicolò Pignatelli'); + $this->assertTrue($this->address->getName()->sameValueAs($name)); + } + + public function testGetStreet() + { + $street = new Street(new StringLiteral('via Manara'), new StringLiteral('3')); + $this->assertTrue($this->address->getStreet()->sameValueAs($street)); + } + + public function testGetDistrict() + { + $district = new StringLiteral(''); + $this->assertTrue($this->address->getDistrict()->sameValueAs($district)); + } + + public function testGetCity() + { + $city = new StringLiteral('Altamura'); + $this->assertTrue($this->address->getCity()->sameValueAs($city)); + } + + public function testGetRegion() + { + $region = new StringLiteral('BARI'); + $this->assertTrue($this->address->getRegion()->sameValueAs($region)); + } + + public function testGetPostalCode() + { + $code = new StringLiteral('70022'); + $this->assertTrue($this->address->getPostalCode()->sameValueAs($code)); + } + + public function testGetCountry() + { + $country = new Country(CountryCode::IT()); + $this->assertTrue($this->address->getCountry()->sameValueAs($country)); + } + + public function testToString() + { + $addressString = <<assertSame($addressString, $this->address->__toString()); + } +} diff --git a/tests/Geography/CoordinateTest.php b/tests/Geography/CoordinateTest.php new file mode 100644 index 0000000..c6c5fd8 --- /dev/null +++ b/tests/Geography/CoordinateTest.php @@ -0,0 +1,113 @@ +coordinate = new Coordinate( + new Latitude(40.829137), + new Longitude(16.555838) + ); + } + + public function testNullConstructorEllipsoid() + { + $this->assertTrue($this->coordinate->getEllipsoid()->sameValueAs(Ellipsoid::WGS84())); + } + + public function testFromNative() + { + $fromNativeCoordinate = Coordinate::fromNative(40.829137, 16.555838, 'WGS84'); + $this->assertTrue($this->coordinate->sameValueAs($fromNativeCoordinate)); + } + + /** @expectedException \BadMethodCallException */ + public function testInvalidFromNative() + { + Coordinate::fromNative(40.829137); + } + + public function testSameValueAs() + { + $coordinate2 = new Coordinate( + new Latitude(40.829137), + new Longitude(16.555838) + ); + $coordinate3 = new Coordinate( + new Latitude(40.829137), + new Longitude(16.555838), + Ellipsoid::WGS60() + ); + + $this->assertTrue($this->coordinate->sameValueAs($coordinate2)); + $this->assertTrue($coordinate2->sameValueAs($this->coordinate)); + $this->assertFalse($this->coordinate->sameValueAs($coordinate3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->coordinate->sameValueAs($mock)); + } + + public function getLatitude() + { + $latitude = new Latitude(40.829137); + $this->assertTrue($this->coordinate->getLatitude()->sameValueAs($latitude)); + } + + public function getLongitude() + { + $longitude = new Longitude(16.555838); + $this->assertTrue($this->coordinate->getLongitude()->sameValueAs($longitude)); + } + + public function getEllipsoid() + { + $ellipsoid = Ellipsoid::WGS84(); + $this->assertTrue($this->coordinate->getEllipsoid()->sameValueAs($ellipsoid)); + } + + public function testToDegreesMinutesSeconds() + { + $dms = new StringLiteral('40°49′45″N, 16°33′21″E'); + $this->assertTrue($this->coordinate->toDegreesMinutesSeconds()->sameValueAs($dms)); + } + + public function testToDecimalMinutes() + { + $dm = new StringLiteral('40 49.74822N, 16 33.35028E'); + $this->assertTrue($this->coordinate->toDecimalMinutes()->sameValueAs($dm)); + } + + public function testToUniversalTransverseMercator() + { + $utm = new StringLiteral('33T 631188 4520953'); + $this->assertTrue($this->coordinate->toUniversalTransverseMercator()->sameValueAs($utm)); + } + + public function testDistanceFrom() + { + $newYork = new Coordinate( + new Latitude(41.145556), + new Longitude(-73.995) + ); + + $distance = $this->coordinate->distanceFrom($newYork); + $this->assertSame(7609068.4225575, $distance->toNative()); + } + + public function testToString() + { + $this->assertSame('40.829137,16.555838', $this->coordinate->__toString()); + } +} diff --git a/tests/Geography/CountryCodeNameTest.php b/tests/Geography/CountryCodeNameTest.php new file mode 100644 index 0000000..40e4673 --- /dev/null +++ b/tests/Geography/CountryCodeNameTest.php @@ -0,0 +1,20 @@ +assertTrue($name->sameValueAs($expectedString)); + } +} diff --git a/tests/Geography/CountryTest.php b/tests/Geography/CountryTest.php new file mode 100644 index 0000000..53a15b7 --- /dev/null +++ b/tests/Geography/CountryTest.php @@ -0,0 +1,51 @@ +assertTrue($constructedCountry->sameValueAs($fromNativeCountry)); + } + + public function testSameValueAs() + { + $country1 = new Country(CountryCode::IT()); + $country2 = new Country(CountryCode::IT()); + $country3 = new Country(CountryCode::US()); + + $this->assertTrue($country1->sameValueAs($country2)); + $this->assertFalse($country1->sameValueAs($country3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($country1->sameValueAs($mock)); + } + + public function testGetCode() + { + $italy = new Country(CountryCode::IT()); + $this->assertTrue($italy->getCode()->sameValueAs(CountryCode::IT())); + } + + public function testGetName() + { + $italy = new Country(CountryCode::IT()); + $name = new StringLiteral('Italy'); + $this->assertTrue($italy->getName()->sameValueAs($name)); + } + + public function testToString() + { + $italy = new Country(CountryCode::IT()); + $this->assertSame('Italy', $italy->__toString()); + } +} diff --git a/tests/Geography/LatitudeTest.php b/tests/Geography/LatitudeTest.php new file mode 100644 index 0000000..b250652 --- /dev/null +++ b/tests/Geography/LatitudeTest.php @@ -0,0 +1,26 @@ +assertEquals(90, $latitude->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidLatitude() + { + new Latitude('invalid'); + } +} diff --git a/tests/Geography/LongitudeTest.php b/tests/Geography/LongitudeTest.php new file mode 100644 index 0000000..dd9ba41 --- /dev/null +++ b/tests/Geography/LongitudeTest.php @@ -0,0 +1,26 @@ +assertEquals(-179, $longitude->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidLongitude() + { + new Longitude('invalid'); + } +} diff --git a/tests/Geography/StreetTest.php b/tests/Geography/StreetTest.php new file mode 100644 index 0000000..93786da --- /dev/null +++ b/tests/Geography/StreetTest.php @@ -0,0 +1,65 @@ +street = new Street(new StringLiteral('Abbey Rd'), new StringLiteral('3'), new StringLiteral('Building A'), new StringLiteral('%number% %name%, %elements%')); + } + + public function testFromNative() + { + $fromNativeStreet = Street::fromNative('Abbey Rd', '3', 'Building A'); + $this->assertTrue($this->street->sameValueAs($fromNativeStreet)); + } + + /** @expectedException \BadMethodCallException */ + public function testInvalidFromNative() + { + Street::fromNative('Abbey Rd'); + } + + public function testSameValueAs() + { + $street2 = new Street(new StringLiteral('Abbey Rd'), new StringLiteral('3'), new StringLiteral('Building A')); + $street3 = new Street(new StringLiteral('Orchard Road'), new StringLiteral('')); + + $this->assertTrue($this->street->sameValueAs($street2)); + $this->assertTrue($street2->sameValueAs($this->street)); + $this->assertFalse($this->street->sameValueAs($street3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->street->sameValueAs($mock)); + } + + public function testGetName() + { + $name = new StringLiteral('Abbey Rd'); + $this->assertTrue($this->street->getName()->sameValueAs($name)); + } + + public function testGetNumber() + { + $number = new StringLiteral('3'); + $this->assertTrue($this->street->getNumber()->sameValueAs($number)); + } + + public function testGetElements() + { + $elements = new StringLiteral('Building A'); + $this->assertTrue($this->street->getElements()->sameValueAs($elements)); + } + + public function testToString() + { + $this->assertSame('3 Abbey Rd, Building A', $this->street->__toString()); + } +} diff --git a/tests/Identity/UUIDTest.php b/tests/Identity/UUIDTest.php new file mode 100644 index 0000000..e23d605 --- /dev/null +++ b/tests/Identity/UUIDTest.php @@ -0,0 +1,43 @@ +assertRegexp('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/', $uuidString); + } + + public function testFromNative() + { + $uuid1 = new UUID(); + $uuid2 = UUID::fromNative($uuid1->toNative()); + + $this->assertTrue($uuid1->sameValueAs($uuid2)); + } + + public function testSameValueAs() + { + $uuid1 = new UUID(); + $uuid2 = clone $uuid1; + $uuid3 = new UUID(); + + $this->assertTrue($uuid1->sameValueAs($uuid2)); + $this->assertFalse($uuid1->sameValueAs($uuid3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($uuid1->sameValueAs($mock)); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalid() + { + new UUID('invalid'); + } +} diff --git a/tests/Money/CurrencyTest.php b/tests/Money/CurrencyTest.php new file mode 100644 index 0000000..17b3df6 --- /dev/null +++ b/tests/Money/CurrencyTest.php @@ -0,0 +1,47 @@ +assertTrue($fromNativeCurrency->sameValueAs($constructedCurrency)); + } + + public function testSameValueAs() + { + $eur1 = new Currency(CurrencyCode::EUR()); + $eur2 = new Currency(CurrencyCode::EUR()); + $usd = new Currency(CurrencyCode::USD()); + + $this->assertTrue($eur1->sameValueAs($eur2)); + $this->assertTrue($eur2->sameValueAs($eur1)); + $this->assertFalse($eur1->sameValueAs($usd)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($eur1->sameValueAs($mock)); + } + + public function testGetCode() + { + $cad = new Currency(CurrencyCode::CAD()); + + $this->assertInstanceOf('\ValueObjects\Money\CurrencyCode', $cad->getCode()); + $this->assertSame('CAD', $cad->getCode()->toNative()); + } + + public function testToString() + { + $eur = new Currency(CurrencyCode::EUR()); + + $this->assertSame('EUR', $eur->__toString()); + } +} diff --git a/tests/Money/MoneyTest.php b/tests/Money/MoneyTest.php new file mode 100644 index 0000000..ca118e3 --- /dev/null +++ b/tests/Money/MoneyTest.php @@ -0,0 +1,110 @@ +assertTrue($fromNativeMoney->sameValueAs($constructedMoney)); + } + + public function testSameValueAs() + { + $eur = new Currency(CurrencyCode::EUR()); + $usd = new Currency(CurrencyCode::USD()); + + $money1 = new Money(new Integer(1200), $eur); + $money2 = new Money(new Integer(1200), $eur); + $money3 = new Money(new Integer(34607), $usd); + + $this->assertTrue($money1->sameValueAs($money2)); + $this->assertTrue($money2->sameValueAs($money1)); + $this->assertFalse($money1->sameValueAs($money3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($money1->sameValueAs($mock)); + } + + public function testGetAmount() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $amount = $money->getAmount(); + + $this->assertInstanceOf('\ValueObjects\Number\Integer', $amount); + $this->assertSame(1200, $amount->toNative()); + } + + public function testGetCurrency() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $currency = $money->getCurrency(); + + $this->assertInstanceOf('\ValueObjects\Money\Currency', $currency); + $this->assertSame('EUR', $currency->getCode()->toNative()); + } + + public function testAdd() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $addendum = new Integer(156); + + $addedMoney = $money->add($addendum); + + $this->assertEquals(1356, $addedMoney->getAmount()->toNative()); + } + + public function testAddNegative() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $addendum = new Integer(-120); + + $addedMoney = $money->add($addendum); + + $this->assertEquals(1080, $addedMoney->getAmount()->toNative()); + } + + public function testMultiply() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $multiplier = new Real(1.2); + + $addedMoney = $money->multiply($multiplier); + + $this->assertEquals(1440, $addedMoney->getAmount()->toNative()); + } + + public function testMultiplyInverse() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + $multiplier = new Real(0.3); + + $addedMoney = $money->multiply($multiplier); + + $this->assertEquals(360, $addedMoney->getAmount()->toNative()); + } + + public function testToString() + { + $eur = new Currency(CurrencyCode::EUR()); + $money = new Money(new Integer(1200), $eur); + + $this->assertSame('EUR 1200', $money->__toString()); + } +} diff --git a/tests/NullValue/NullValueTest.php b/tests/NullValue/NullValueTest.php new file mode 100644 index 0000000..f173b7a --- /dev/null +++ b/tests/NullValue/NullValueTest.php @@ -0,0 +1,36 @@ +assertTrue($null1->sameValueAs($null2)); + } + + public function testCreate() + { + $null = NullValue::create(); + + $this->assertInstanceOf('ValueObjects\NullValue\NullValue', $null); + } + + public function testToString() + { + $foo = new NullValue(); + $this->assertSame('', $foo->__toString()); + } +} diff --git a/tests/Number/ComplexTest.php b/tests/Number/ComplexTest.php new file mode 100644 index 0000000..1979b9a --- /dev/null +++ b/tests/Number/ComplexTest.php @@ -0,0 +1,88 @@ +complex = new Complex(new Real(2.05), new Real(3.2)); + } + + public function testFromNative() + { + $fromNativeComplex = Complex::fromNative(2.05, 3.2); + + $this->assertTrue($fromNativeComplex->sameValueAs($this->complex)); + } + + public function testFromNativeWithWrongNumberOfArgsThrowsError() + { + $this->setExpectedException('BadMethodCallException'); + $fromNativeComplex = Complex::fromNative(2.05); + } + + public function testFromPolar() + { + $mod = new Real(3.800328933132); + $arg = new Real(1.0010398733119); + $fromPolar = Complex::fromPolar($mod, $arg); + + $nativeModulus = $this->complex->getModulus(); + $nativeArgument = $this->complex->getArgument(); + + $this->assertTrue($nativeModulus->sameValueAs($fromPolar->getModulus())); + $this->assertTrue($nativeArgument->sameValueAs($fromPolar->getArgument())); + } + + public function testToNative() + { + $this->assertEquals(array(2.05, 3.2), $this->complex->toNative()); + } + + public function testGetReal() + { + $real = new Real(2.05); + + $this->assertTrue($real->sameValueAs($this->complex->getReal())); + } + + public function testGetIm() + { + $im = new Real(3.2); + + $this->assertTrue($im->sameValueAs($this->complex->getIm())); + } + + public function testGetModulus() + { + $mod = new Real(3.800328933132); + + $this->assertTrue($mod->sameValueAs($this->complex->getModulus())); + } + + public function testGetArgument() + { + $arg = new Real(1.0010398733119); + + $this->assertTrue($arg->sameValueAs($this->complex->getArgument())); + } + + public function testToString() + { + $complex = new Complex(new Real(2.034), new Real(-1.4)); + $this->assertEquals('2.034 - 1.4i', $complex->__toString()); + } + + public function testNotSameValue() + { + $this->assertFalse($this->complex->sameValueAs(new Real(2.035))); + } +} diff --git a/tests/Number/IntegerTest.php b/tests/Number/IntegerTest.php new file mode 100644 index 0000000..9cbfc63 --- /dev/null +++ b/tests/Number/IntegerTest.php @@ -0,0 +1,57 @@ +assertSame(5, $integer->toNative()); + } + + public function testSameValueAs() + { + $integer1 = new Integer(3); + $integer2 = new Integer(3); + $integer3 = new Integer(45); + + $this->assertTrue($integer1->sameValueAs($integer2)); + $this->assertTrue($integer2->sameValueAs($integer1)); + $this->assertFalse($integer1->sameValueAs($integer3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($integer1->sameValueAs($mock)); + } + + public function testToString() + { + $integer = new Integer(87); + $this->assertSame('87', $integer->__toString()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidNativeArgument() + { + new Integer(23.4); + } + + public function testZeroToString() + { + $zero = new Integer(0); + $this->assertSame('0', $zero->__toString()); + } + + public function testToReal() + { + $integer = new Integer(5); + $nativeReal = new Real(5); + $real = $integer->toReal(); + + $this->assertTrue($real->sameValueAs($nativeReal)); + } +} diff --git a/tests/Number/NaturalTest.php b/tests/Number/NaturalTest.php new file mode 100644 index 0000000..b3398f4 --- /dev/null +++ b/tests/Number/NaturalTest.php @@ -0,0 +1,15 @@ +assertTrue($fromNativeReal->sameValueAs($constructedReal)); + } + + public function testToNative() + { + $real = new Real(3.4); + $this->assertEquals(3.4, $real->toNative()); + } + + public function testSameValueAs() + { + $real1 = new Real(5.64); + $real2 = new Real(5.64); + $real3 = new Real(6.01); + + $this->assertTrue($real1->sameValueAs($real2)); + $this->assertTrue($real2->sameValueAs($real1)); + $this->assertFalse($real1->sameValueAs($real3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($real1->sameValueAs($mock)); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidNativeArgument() + { + new Real('invalid'); + } + + public function testToInteger() + { + $real = new Real(3.14); + $nativeInteger = new Integer(3); + $integer = $real->toInteger(); + + $this->assertTrue($integer->sameValueAs($nativeInteger)); + } + + public function testToNatural() + { + $real = new Real(3.14); + $nativeNatural = new Natural(3); + $natural = $real->toNatural(); + + $this->assertTrue($natural->sameValueAs($nativeNatural)); + } + + public function testToString() + { + $real = new Real(.7); + $this->assertEquals('.7', $real->__toString()); + } +} diff --git a/tests/Person/AgeTest.php b/tests/Person/AgeTest.php new file mode 100644 index 0000000..be37837 --- /dev/null +++ b/tests/Person/AgeTest.php @@ -0,0 +1,35 @@ +assertEquals(25, $age->toNative()); + } + + public function testSameValueAs() + { + $age1 = new Age(33); + $age2 = new Age(33); + $age3 = new Age(66); + + $this->assertTrue($age1->sameValueAs($age2)); + $this->assertTrue($age2->sameValueAs($age1)); + $this->assertFalse($age1->sameValueAs($age3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($age1->sameValueAs($mock)); + } + + public function testToString() + { + $age = new Age(54); + $this->assertEquals('54', $age->__toString()); + } +} diff --git a/tests/Person/GenderTest.php b/tests/Person/GenderTest.php new file mode 100644 index 0000000..240e16d --- /dev/null +++ b/tests/Person/GenderTest.php @@ -0,0 +1,35 @@ +assertEquals(Gender::FEMALE, $gender->toNative()); + } + + public function testSameValueAs() + { + $male1 = Gender::MALE(); + $male2 = Gender::MALE(); + $other = Gender::OTHER(); + + $this->assertTrue($male1->sameValueAs($male2)); + $this->assertTrue($male2->sameValueAs($male1)); + $this->assertFalse($male1->sameValueAs($other)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($male1->sameValueAs($mock)); + } + + public function testToString() + { + $sex = Gender::FEMALE(); + $this->assertEquals('female', $sex->__toString()); + } +} diff --git a/tests/Person/NameTest.php b/tests/Person/NameTest.php new file mode 100644 index 0000000..ee90be8 --- /dev/null +++ b/tests/Person/NameTest.php @@ -0,0 +1,69 @@ +name = new Name(new StringLiteral('foo'), new StringLiteral('bar'), new StringLiteral('baz')); + } + + public function testFromNative() + { + $fromNativeName = Name::fromNative('foo', 'bar', 'baz'); + + $this->assertTrue($fromNativeName->sameValueAs($this->name)); + } + + public function testGetFirstName() + { + $this->assertEquals('foo', $this->name->getFirstName()); + } + + public function testGetMiddleName() + { + $this->assertEquals('bar', $this->name->getMiddleName()); + } + + public function testGetLastName() + { + $this->assertEquals('baz', $this->name->getLastName()); + } + + public function testGetFullName() + { + $this->assertEquals('foo bar baz', $this->name->getFullName()); + } + + public function testEmptyFullName() + { + $name = new Name(new StringLiteral(''), new StringLiteral(''), new StringLiteral('')); + + $this->assertEquals('', $name->getFullName()); + } + + public function testSameValueAs() + { + $name2 = new Name(new StringLiteral('foo'), new StringLiteral('bar'), new StringLiteral('baz')); + $name3 = new Name(new StringLiteral('foo'), new StringLiteral(''), new StringLiteral('baz')); + + $this->assertTrue($this->name->sameValueAs($name2)); + $this->assertTrue($name2->sameValueAs($this->name)); + $this->assertFalse($this->name->sameValueAs($name3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->name->sameValueAs($mock)); + } + + public function testToString() + { + $this->assertEquals('foo bar baz', $this->name->__toString()); + } +} diff --git a/tests/StringLiteral/StringLiteralTest.php b/tests/StringLiteral/StringLiteralTest.php new file mode 100644 index 0000000..fa1d1cf --- /dev/null +++ b/tests/StringLiteral/StringLiteralTest.php @@ -0,0 +1,56 @@ +assertTrue($string->sameValueAs($constructedString)); + } + + public function testToNative() + { + $string = new StringLiteral('foo'); + $this->assertEquals('foo', $string->toNative()); + } + + public function testSameValueAs() + { + $foo1 = new StringLiteral('foo'); + $foo2 = new StringLiteral('foo'); + $bar = new StringLiteral('bar'); + + $this->assertTrue($foo1->sameValueAs($foo2)); + $this->assertTrue($foo2->sameValueAs($foo1)); + $this->assertFalse($foo1->sameValueAs($bar)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($foo1->sameValueAs($mock)); + } + + /** @expectedException \ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidNativeArgument() + { + new StringLiteral(12); + } + + public function testIsEmpty() + { + $string = new StringLiteral(''); + + $this->assertTrue($string->isEmpty()); + } + + public function testToString() + { + $foo = new StringLiteral('foo'); + $this->assertEquals('foo', $foo->__toString()); + } +} diff --git a/tests/Structure/CollectionTest.php b/tests/Structure/CollectionTest.php new file mode 100644 index 0000000..3bd357b --- /dev/null +++ b/tests/Structure/CollectionTest.php @@ -0,0 +1,114 @@ +offsetSet(0, new StringLiteral('one')); + $array->offsetSet(1, new StringLiteral('two')); + $array->offsetSet(2, new Integer(3)); + + $this->collection = new Collection($array); + } + + /** @expectedException \InvalidArgumentException */ + public function testInvalidArgument() + { + $array = \SplFixedArray::fromArray(array('one', 'two', 'three')); + + new Collection($array); + } + + public function testFromNative() + { + $array = \SplFixedArray::fromArray(array( + 'one', + 'two', + array(1, 2) + )); + $fromNativeCollection = Collection::fromNative($array); + + $innerArray = new Collection( + \SplFixedArray::fromArray(array( + new StringLiteral('1'), + new StringLiteral('2') + )) + ); + $array = \SplFixedArray::fromArray(array( + new StringLiteral('one'), + new StringLiteral('two'), + $innerArray + )); + $constructedCollection = new Collection($array); + + $this->assertTrue($fromNativeCollection->sameValueAs($constructedCollection)); + } + + public function testSameValueAs() + { + $array = \SplFixedArray::fromArray(array( + new StringLiteral('one'), + new StringLiteral('two'), + new Integer(3) + )); + $collection2 = new Collection($array); + + $array = \SplFixedArray::fromArray(array( + 'one', + 'two', + array(1, 2) + )); + $collection3 = Collection::fromNative($array); + + $this->assertTrue($this->collection->sameValueAs($collection2)); + $this->assertTrue($collection2->sameValueAs($this->collection)); + $this->assertFalse($this->collection->sameValueAs($collection3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->collection->sameValueAs($mock)); + } + + public function testCount() + { + $three = new Natural(3); + + $this->assertTrue($this->collection->count()->sameValueAs($three)); + } + + public function testContains() + { + $one = new StringLiteral('one'); + $ten = new StringLiteral('ten'); + + $this->assertTrue($this->collection->contains($one)); + $this->assertFalse($this->collection->contains($ten)); + } + + public function testToArray() + { + $array = array( + new StringLiteral('one'), + new StringLiteral('two'), + new Integer(3) + ); + + $this->assertEquals($array, $this->collection->toArray()); + } + + public function testToString() + { + $this->assertEquals('ValueObjects\Structure\Collection(3)', $this->collection->__toString()); + } +} diff --git a/tests/Structure/DictionaryTest.php b/tests/Structure/DictionaryTest.php new file mode 100644 index 0000000..e0ea811 --- /dev/null +++ b/tests/Structure/DictionaryTest.php @@ -0,0 +1,97 @@ +dictionary = new Dictionary($array); + } + + public function testFromNative() + { + $constructedArray = \SplFixedArray::fromArray(array( + new KeyValuePair(new StringLiteral('0'), new StringLiteral('zero')), + new KeyValuePair(new StringLiteral('1'), new StringLiteral('one')), + new KeyValuePair(new StringLiteral('2'), new StringLiteral('two')), + )); + + $fromNativeArray = \SplFixedArray::fromArray(array( + 'zero', + 'one', + 'two' + )); + + $constructedDictionary = new Dictionary($constructedArray); + $fromNativeDictionary = Dictionary::fromNative($fromNativeArray); + + $this->assertTrue($constructedDictionary->sameValueAs($fromNativeDictionary)); + } + + /** @expectedException \InvalidArgumentException */ + public function testInvalidArgument() + { + $array = \SplFixedArray::fromArray(array('one', 'two', 'three')); + + new Dictionary($array); + } + + public function testKeys() + { + $array = \SplFixedArray::fromArray(array( + new Integer(0), + new Integer(1), + new Integer(2) + )); + $keys = new Collection($array); + + $this->assertTrue($this->dictionary->keys()->sameValueAs($keys)); + } + + public function testValues() + { + $array = \SplFixedArray::fromArray(array( + new StringLiteral('zero'), + new StringLiteral('one'), + new StringLiteral('two') + )); + $values = new Collection($array); + + $this->assertTrue($this->dictionary->values()->sameValueAs($values)); + } + + public function testContainsKey() + { + $one = new Integer(1); + $ten = new Integer(10); + + $this->assertTrue($this->dictionary->containsKey($one)); + $this->assertFalse($this->dictionary->containsKey($ten)); + } + + public function testContainsValue() + { + $one = new StringLiteral('one'); + $ten = new StringLiteral('ten'); + + $this->assertTrue($this->dictionary->containsValue($one)); + $this->assertFalse($this->dictionary->containsValue($ten)); + } +} diff --git a/tests/Structure/KeyValuePairTest.php b/tests/Structure/KeyValuePairTest.php new file mode 100644 index 0000000..30bac38 --- /dev/null +++ b/tests/Structure/KeyValuePairTest.php @@ -0,0 +1,58 @@ +keyValuePair = new KeyValuePair(new StringLiteral('key'), new StringLiteral('value')); + } + + public function testFromNative() + { + $fromNativePair = KeyValuePair::fromNative('key', 'value'); + $this->assertTrue($this->keyValuePair->sameValueAs($fromNativePair)); + } + + /** @expectedException \BadMethodCallException */ + public function testInvalidFromNative() + { + KeyValuePair::fromNative('key', 'value', 'invalid'); + } + + public function testSameValueAs() + { + $keyValuePair2 = new KeyValuePair(new StringLiteral('key'), new StringLiteral('value')); + $keyValuePair3 = new KeyValuePair(new StringLiteral('foo'), new StringLiteral('bar')); + + $this->assertTrue($this->keyValuePair->sameValueAs($keyValuePair2)); + $this->assertTrue($keyValuePair2->sameValueAs($this->keyValuePair)); + $this->assertFalse($this->keyValuePair->sameValueAs($keyValuePair3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->keyValuePair->sameValueAs($mock)); + } + + public function testGetKey() + { + $this->assertEquals('key', $this->keyValuePair->getKey()); + } + + public function testGetValue() + { + $this->assertEquals('value', $this->keyValuePair->getValue()); + } + + public function testToString() + { + $this->assertEquals('key => value', $this->keyValuePair->__toString()); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..c094ee1 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,7 @@ +assertTrue(Util::classEquals($util1, $util2)); + $this->assertFalse(Util::classEquals($util1, $this)); + } + + public function testGetClassAsString() + { + $util = new Util(); + $this->assertEquals('ValueObjects\Util\Util', Util::getClassAsString($util)); + } + +} diff --git a/tests/Web/DomainTest.php b/tests/Web/DomainTest.php new file mode 100644 index 0000000..66a86ff --- /dev/null +++ b/tests/Web/DomainTest.php @@ -0,0 +1,18 @@ +assertInstanceOf('ValueObjects\Web\IPAddress', $ip); + $this->assertInstanceOf('ValueObjects\Web\Hostname', $hostname); + } +} diff --git a/tests/Web/EmailAddressTest.php b/tests/Web/EmailAddressTest.php new file mode 100644 index 0000000..ef00cb8 --- /dev/null +++ b/tests/Web/EmailAddressTest.php @@ -0,0 +1,41 @@ +assertInstanceOf('ValueObjects\Web\EmailAddress', $email1); + + $email2 = new EmailAddress('foo@[120.0.0.1]'); + $this->assertInstanceOf('ValueObjects\Web\EmailAddress', $email2); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidEmailAddress() + { + new EmailAddress('invalid'); + } + + public function testGetLocalPart() + { + $email = new EmailAddress('foo@bar.baz'); + $localPart = $email->getLocalPart(); + + $this->assertEquals('foo', $localPart->toNative()); + } + + public function testGetDomainPart() + { + $email = new EmailAddress('foo@bar.com'); + $domainPart = $email->getDomainPart(); + + $this->assertEquals('bar.com', $domainPart->toNative()); + $this->assertInstanceOf('ValueObjects\Web\Domain', $domainPart); + } +} diff --git a/tests/Web/FragmentIdentifierTest.php b/tests/Web/FragmentIdentifierTest.php new file mode 100644 index 0000000..e1f1e73 --- /dev/null +++ b/tests/Web/FragmentIdentifierTest.php @@ -0,0 +1,30 @@ +assertInstanceOf('ValueObjects\Web\FragmentIdentifier', $fragment); + } + + public function testNullFragmentIdentifier() + { + $fragment = new NullFragmentIdentifier(); + + $this->assertInstanceOf('ValueObjects\Web\FragmentIdentifier', $fragment); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidFragmentIdentifier() + { + new FragmentIdentifier('invalìd'); + } +} diff --git a/tests/Web/HostnameTest.php b/tests/Web/HostnameTest.php new file mode 100644 index 0000000..f1c315e --- /dev/null +++ b/tests/Web/HostnameTest.php @@ -0,0 +1,15 @@ +assertSame(IPAddressVersion::IPV4(), $ip4->getVersion()); + + $ip6 = new IPAddress('::1'); + $this->assertSame(IPAddressVersion::IPV6(), $ip6->getVersion()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidIPAddress() + { + new IPAddress('invalid'); + } +} diff --git a/tests/Web/IPv4AddressTest.php b/tests/Web/IPv4AddressTest.php new file mode 100644 index 0000000..ec57509 --- /dev/null +++ b/tests/Web/IPv4AddressTest.php @@ -0,0 +1,22 @@ +assertInstanceOf('ValueObjects\Web\IPv4Address', $ip); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidIPv4Address() + { + new IPv4Address('::1'); + } +} diff --git a/tests/Web/IPv6AddressTest.php b/tests/Web/IPv6AddressTest.php new file mode 100644 index 0000000..a36f1b4 --- /dev/null +++ b/tests/Web/IPv6AddressTest.php @@ -0,0 +1,22 @@ +assertInstanceOf('ValueObjects\Web\IPv6Address', $ip); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidIPv6Address() + { + new IPv6Address('127.0.0.1'); + } +} diff --git a/tests/Web/PathTest.php b/tests/Web/PathTest.php new file mode 100644 index 0000000..647f09f --- /dev/null +++ b/tests/Web/PathTest.php @@ -0,0 +1,22 @@ +assertEquals($pathString, $path->toNative()); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidPath() + { + new Path('//valid?'); + } +} diff --git a/tests/Web/PortNumberTest.php b/tests/Web/PortNumberTest.php new file mode 100644 index 0000000..432914c --- /dev/null +++ b/tests/Web/PortNumberTest.php @@ -0,0 +1,22 @@ +assertInstanceOf('ValueObjects\Web\PortNumber', $port); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidPortNumber() + { + new PortNumber(65536); + } +} diff --git a/tests/Web/QueryStringTest.php b/tests/Web/QueryStringTest.php new file mode 100644 index 0000000..3a91003 --- /dev/null +++ b/tests/Web/QueryStringTest.php @@ -0,0 +1,53 @@ +assertInstanceOf('ValueObjects\Web\QueryString', $query); + } + + public function testEmptyQueryString() + { + $query = new NullQueryString(); + + $this->assertInstanceOf('ValueObjects\Web\QueryString', $query); + + $dictionary = $query->toDictionary(); + $this->assertInstanceOf('ValueObjects\Structure\Dictionary', $dictionary); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidQueryString() + { + new QueryString('invalìd'); + } + + public function testToDictionary() + { + $query = new QueryString('?foo=bar&array[]=one&array[]=two'); + $dictionary = $query->toDictionary(); + + $this->assertInstanceOf('ValueObjects\Structure\Dictionary', $dictionary); + + $array = array( + 'foo' => 'bar', + 'array' => array( + 'one', + 'two' + ) + ); + $expectedDictionary = Dictionary::fromNative($array); + + $this->assertTrue($expectedDictionary->sameValueAs($dictionary)); + } +} diff --git a/tests/Web/SchemeNameTest.php b/tests/Web/SchemeNameTest.php new file mode 100644 index 0000000..d1c5dca --- /dev/null +++ b/tests/Web/SchemeNameTest.php @@ -0,0 +1,21 @@ +assertInstanceOf('ValueObjects\Web\SchemeName', $scheme); + } + + /** @expectedException ValueObjects\Exception\InvalidNativeArgumentException */ + public function testInvalidSchemeName() + { + new SchemeName('ht*tp'); + } +} diff --git a/tests/Web/UrlTest.php b/tests/Web/UrlTest.php new file mode 100644 index 0000000..362466c --- /dev/null +++ b/tests/Web/UrlTest.php @@ -0,0 +1,181 @@ +url = new Url( + new SchemeName('http'), + new StringLiteral('user'), + new StringLiteral('pass'), + new Hostname('foo.com'), + new PortNumber(80), + new Path('/bar'), + new QueryString('?querystring'), + new FragmentIdentifier('#fragmentidentifier') + ); + } + + public function testFromNative() + { + $nativeUrlString = 'http://user:pass@foo.com:80/bar?querystring#fragmentidentifier'; + $fromNativeUrl = Url::fromNative($nativeUrlString); + + $this->assertTrue($this->url->sameValueAs($fromNativeUrl)); + + $nativeUrlString = 'http://www.test.com'; + $fromNativeUrl = Url::fromNative($nativeUrlString); + + $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); + + $nativeUrlString = 'http://www.test.com/bar'; + $fromNativeUrl = Url::fromNative($nativeUrlString); + + $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); + + $nativeUrlString = 'http://www.test.com/?querystring'; + $fromNativeUrl = Url::fromNative($nativeUrlString); + + $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); + + $nativeUrlString = 'http://www.test.com/#fragmentidentifier'; + $fromNativeUrl = Url::fromNative($nativeUrlString); + + $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); + } + + public function testSameValueAs() + { + $url2 = new Url( + new SchemeName('http'), + new StringLiteral('user'), + new StringLiteral('pass'), + new Hostname('foo.com'), + new PortNumber(80), + new Path('/bar'), + new QueryString('?querystring'), + new FragmentIdentifier('#fragmentidentifier') + ); + + $url3 = new Url( + new SchemeName('git+ssh'), + new StringLiteral(''), + new StringLiteral(''), + new Hostname('github.com'), + new NullPortNumber(), + new Path('/nicolopignatelli/valueobjects'), + new QueryString('?querystring'), + new FragmentIdentifier('#fragmentidentifier') + ); + + $this->assertTrue($this->url->sameValueAs($url2)); + $this->assertTrue($url2->sameValueAs($this->url)); + $this->assertFalse($this->url->sameValueAs($url3)); + + $mock = $this->getMock('ValueObjects\ValueObjectInterface'); + $this->assertFalse($this->url->sameValueAs($mock)); + } + + public function testGetDomain() + { + $domain = new Hostname('foo.com'); + $this->assertTrue($this->url->getDomain()->sameValueAs($domain)); + } + + public function testGetFragmentIdentifier() + { + $fragment = new FragmentIdentifier('#fragmentidentifier'); + $this->assertTrue($this->url->getFragmentIdentifier()->sameValueAs($fragment)); + } + + public function testGetPassword() + { + $password = new StringLiteral('pass'); + $this->assertTrue($this->url->getPassword()->sameValueAs($password)); + } + + public function testGetPath() + { + $path = new Path('/bar'); + $this->assertTrue($this->url->getPath()->sameValueAs($path)); + } + + public function testGetPort() + { + $port = new PortNumber(80); + $this->assertTrue($this->url->getPort()->sameValueAs($port)); + } + + public function testGetQueryString() + { + $queryString = new QueryString('?querystring'); + $this->assertTrue($this->url->getQueryString()->sameValueAs($queryString)); + } + + public function testGetScheme() + { + $scheme = new SchemeName('http'); + $this->assertTrue($this->url->getScheme()->sameValueAs($scheme)); + } + + public function testGetUser() + { + $user = new StringLiteral('user'); + $this->assertTrue($this->url->getUser()->sameValueAs($user)); + } + + public function testToString() + { + $this->assertSame('http://user:pass@foo.com:80/bar?querystring#fragmentidentifier', $this->url->__toString()); + } + + public function testAuthlessUrlToString() + { + $nativeUrlString = 'http://foo.com:80/bar?querystring#fragmentidentifier'; + $authlessUrl = new Url( + new SchemeName('http'), + new StringLiteral(''), + new StringLiteral(''), + new Hostname('foo.com'), + new PortNumber(80), + new Path('/bar'), + new QueryString('?querystring'), + new FragmentIdentifier('#fragmentidentifier') + ); + $this->assertSame($nativeUrlString, $authlessUrl->__toString()); + + $fromNativeUrl = Url::fromNative($nativeUrlString); + $this->assertSame($nativeUrlString, Url::fromNative($authlessUrl)->__toString()); + } + + public function testNullPortUrlToString() + { + $nullPortUrl = new Url( + new SchemeName('http'), + new StringLiteral('user'), + new StringLiteral(''), + new Hostname('foo.com'), + new NullPortNumber(), + new Path('/bar'), + new QueryString('?querystring'), + new FragmentIdentifier('#fragmentidentifier') + ); + $this->assertSame('http://user@foo.com/bar?querystring#fragmentidentifier', $nullPortUrl->__toString()); + } +}