]> git.andy128k.dev Git - missing-tools.git/commitdiff
cleanup master
authorAndrey Kutejko <andy128k@gmail.com>
Tue, 19 Mar 2019 22:08:56 +0000 (23:08 +0100)
committerAndrey Kutejko <andy128k@gmail.com>
Tue, 19 Mar 2019 22:08:56 +0000 (23:08 +0100)
29 files changed:
.gitignore
composer.json
composer.lock
src/algorithm.php [deleted file]
src/cli.php [deleted file]
src/collection.php
src/container.php [deleted file]
src/dateformat.php
src/htmlbuilder.php
src/io/pushback.php [deleted file]
src/maplike.php [new file with mode: 0644]
src/mixins.php [deleted file]
src/native_template.php [deleted file]
src/regexp.php
src/shell.php [deleted file]
src/str.php
src/symbol.php [deleted file]
src/topsort.php [new file with mode: 0644]
t/ArrTest.php
t/ContainerTest.php [deleted file]
t/FormatTest.php
t/HtmlBuilderTest.php
t/MapLikeTest.php [new file with mode: 0644]
t/MixinsTest.php [deleted file]
t/RegexpTest.php [new file with mode: 0644]
t/TopSortTest.php [new file with mode: 0644]
t/native_template/NativeTemplateTest.php [deleted file]
t/native_template/simple.html [deleted file]
t/native_template/syntax_error.html [deleted file]

index fcac4a70c7dcb7dd5a38f322d2af8ff6a07cc04c..bf00556f4cf4d535bf3787b7db2863f1da771a35 100644 (file)
@@ -1,2 +1,4 @@
 /vendor
-
+/coverage
+*.iml
+.idea
index 8dbdfc7c5db558a57cadfc8bd22e307b341ee2d1..8a78decc7c0aeceaf60caac9afca731a09f9e080 100644 (file)
     "classmap" : ["src/"]
   },
   "require": {
-    "php": ">=5.3",
+    "php": ">=5.6",
     "andy128k/pegp": "0.2"
   },
   "require-dev": {
-    "phpunit/phpunit": "4.4.*"
+    "phpunit/phpunit": "~5"
   },
   "config": {
     "platform": {
@@ -24,6 +24,7 @@
     }
   },
   "scripts": {
-    "test": "phpunit ./t"
+    "test": "phpunit ./t",
+    "coverage": "phpunit t --coverage-html coverage --whitelist src"
   }
 }
index 6763bc86707bc77cc49c9d577f2ac99a0cb76cc3..725c9b418d9738eed2bb31add8955440eff0b2e2 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "2bdd3ecd1c14aff8b1e4786ee9bf123c",
+    "content-hash": "34b720d947e75b0bb44ede913e37a788",
     "packages": [
         {
             "name": "andy128k/pegp",
             ],
             "time": "2015-06-14T21:17:01+00:00"
         },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.7.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
+                "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.0",
+                "doctrine/common": "^2.6",
+                "phpunit/phpunit": "^4.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                },
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "time": "2017-10-19T19:58:43+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.6"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
+                        "src"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "FQSEN",
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "time": "2017-09-11T18:02:19+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "3.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2",
+                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0",
+                "phpdocumentor/reflection-common": "^1.0.0",
+                "phpdocumentor/type-resolver": "^0.4.0",
+                "webmozart/assert": "^1.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^0.9.4",
+                "phpunit/phpunit": "^4.4"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "time": "2017-11-10T14:09:06+00:00"
+        },
+        {
+            "name": "phpdocumentor/type-resolver",
+            "version": "0.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+                "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.5 || ^7.0",
+                "phpdocumentor/reflection-common": "^1.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^0.9.4",
+                "phpunit/phpunit": "^5.2||^4.8.24"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "time": "2017-07-14T14:27:02+00:00"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "1.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+                "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.0.2",
+                "php": "^5.3|^7.0",
+                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+                "sebastian/comparator": "^1.1|^2.0|^3.0",
+                "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+            },
+            "require-dev": {
+                "phpspec/phpspec": "^2.5|^3.2",
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Prophecy\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Marcello Duarte",
+                    "email": "marcello.duarte@gmail.com"
+                }
+            ],
+            "description": "Highly opinionated mocking framework for PHP 5.3+",
+            "homepage": "https://github.com/phpspec/prophecy",
+            "keywords": [
+                "Double",
+                "Dummy",
+                "fake",
+                "mock",
+                "spy",
+                "stub"
+            ],
+            "time": "2018-08-05T17:53:17+00:00"
+        },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.2.4",
+            "version": "4.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
+                "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
-                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
+                "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3",
-                "phpunit/php-file-iterator": "~1.3",
-                "phpunit/php-text-template": "~1.2",
-                "phpunit/php-token-stream": "~1.3",
-                "sebastian/environment": "^1.3.2",
-                "sebastian/version": "~1.0"
+                "ext-dom": "*",
+                "ext-xmlwriter": "*",
+                "php": "^5.6 || ^7.0",
+                "phpunit/php-file-iterator": "^1.3",
+                "phpunit/php-text-template": "^1.2",
+                "phpunit/php-token-stream": "^1.4.2 || ^2.0",
+                "sebastian/code-unit-reverse-lookup": "^1.0",
+                "sebastian/environment": "^1.3.2 || ^2.0",
+                "sebastian/version": "^1.0 || ^2.0"
             },
             "require-dev": {
-                "ext-xdebug": ">=2.1.4",
-                "phpunit/phpunit": "~4"
+                "ext-xdebug": "^2.1.4",
+                "phpunit/phpunit": "^5.7"
             },
             "suggest": {
-                "ext-dom": "*",
-                "ext-xdebug": ">=2.2.1",
-                "ext-xmlwriter": "*"
+                "ext-xdebug": "^2.5.1"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.2.x-dev"
+                    "dev-master": "4.0.x-dev"
                 }
             },
             "autoload": {
                 "testing",
                 "xunit"
             ],
-            "time": "2015-10-06T15:47:00+00:00"
+            "time": "2017-04-02T07:44:40+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.3.4",
+            "version": "1.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
+                "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+                "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
-                    "File/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
                 "filesystem",
                 "iterator"
             ],
-            "time": "2013-10-10T15:34:57+00:00"
+            "time": "2017-11-27T13:52:08+00:00"
         },
         {
             "name": "phpunit/php-text-template",
         },
         {
             "name": "phpunit/phpunit",
-            "version": "4.4.5",
+            "version": "5.7.27",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "2e8580deebb7d1ac92ac878595e6bffe01069c2a"
+                "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2e8580deebb7d1ac92ac878595e6bffe01069c2a",
-                "reference": "2e8580deebb7d1ac92ac878595e6bffe01069c2a",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
+                "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-json": "*",
-                "ext-pcre": "*",
-                "ext-reflection": "*",
-                "ext-spl": "*",
-                "php": ">=5.3.3",
-                "phpunit/php-code-coverage": "~2.0",
-                "phpunit/php-file-iterator": "~1.3.2",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "myclabs/deep-copy": "~1.3",
+                "php": "^5.6 || ^7.0",
+                "phpspec/prophecy": "^1.6.2",
+                "phpunit/php-code-coverage": "^4.0.4",
+                "phpunit/php-file-iterator": "~1.4",
                 "phpunit/php-text-template": "~1.2",
-                "phpunit/php-timer": "~1.0.2",
-                "phpunit/phpunit-mock-objects": "~2.3",
-                "sebastian/comparator": "~1.0",
-                "sebastian/diff": "~1.1",
-                "sebastian/environment": "~1.1",
-                "sebastian/exporter": "~1.1",
-                "sebastian/global-state": "~1.0",
-                "sebastian/recursion-context": "~1.0",
-                "sebastian/version": "~1.0",
-                "symfony/yaml": "~2.0"
+                "phpunit/php-timer": "^1.0.6",
+                "phpunit/phpunit-mock-objects": "^3.2",
+                "sebastian/comparator": "^1.2.4",
+                "sebastian/diff": "^1.4.3",
+                "sebastian/environment": "^1.3.4 || ^2.0",
+                "sebastian/exporter": "~2.0",
+                "sebastian/global-state": "^1.1",
+                "sebastian/object-enumerator": "~2.0",
+                "sebastian/resource-operations": "~1.0",
+                "sebastian/version": "^1.0.6|^2.0.1",
+                "symfony/yaml": "~2.1|~3.0|~4.0"
+            },
+            "conflict": {
+                "phpdocumentor/reflection-docblock": "3.0.2"
+            },
+            "require-dev": {
+                "ext-pdo": "*"
             },
             "suggest": {
+                "ext-xdebug": "*",
                 "phpunit/php-invoker": "~1.1"
             },
             "bin": [
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.4.x-dev"
+                    "dev-master": "5.7.x-dev"
                 }
             },
             "autoload": {
                 "testing",
                 "xunit"
             ],
-            "time": "2015-01-27T16:06:15+00:00"
+            "time": "2018-02-01T05:50:59+00:00"
         },
         {
             "name": "phpunit/phpunit-mock-objects",
-            "version": "2.3.8",
+            "version": "3.4.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
-                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
+                "reference": "a23b761686d50a560cc56233b9ecf49597cc9118"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
-                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118",
+                "reference": "a23b761686d50a560cc56233b9ecf49597cc9118",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
-                "php": ">=5.3.3",
-                "phpunit/php-text-template": "~1.2",
-                "sebastian/exporter": "~1.2"
+                "php": "^5.6 || ^7.0",
+                "phpunit/php-text-template": "^1.2",
+                "sebastian/exporter": "^1.2 || ^2.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<5.4.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.4"
+                "phpunit/phpunit": "^5.4"
             },
             "suggest": {
                 "ext-soap": "*"
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.3.x-dev"
+                    "dev-master": "3.2.x-dev"
                 }
             },
             "autoload": {
                 "xunit"
             ],
             "abandoned": true,
-            "time": "2015-10-02T06:51:40+00:00"
+            "time": "2017-06-30T09:13:00+00:00"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+                "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7 || ^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "time": "2017-03-04T06:30:41+00:00"
         },
         {
             "name": "sebastian/comparator",
         },
         {
             "name": "sebastian/environment",
-            "version": "1.3.8",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
+                "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
-                "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+                "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.3.3 || ^7.0"
+                "php": "^5.6 || ^7.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^4.8 || ^5.0"
+                "phpunit/phpunit": "^5.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
                 "environment",
                 "hhvm"
             ],
-            "time": "2016-08-18T05:49:44+00:00"
+            "time": "2016-11-26T07:53:53+00:00"
         },
         {
             "name": "sebastian/exporter",
-            "version": "1.2.2",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
+                "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
-                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+                "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3",
-                "sebastian/recursion-context": "~1.0"
+                "sebastian/recursion-context": "~2.0"
             },
             "require-dev": {
                 "ext-mbstring": "*",
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
                 "export",
                 "exporter"
             ],
-            "time": "2016-06-17T09:04:28+00:00"
+            "time": "2016-11-19T08:54:04+00:00"
         },
         {
             "name": "sebastian/global-state",
             ],
             "time": "2015-10-12T03:26:01+00:00"
         },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
+                "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6",
+                "sebastian/recursion-context": "~2.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "time": "2017-02-18T15:18:39+00:00"
+        },
         {
             "name": "sebastian/recursion-context",
-            "version": "1.0.5",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/recursion-context.git",
-                "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
+                "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
-                "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+                "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
             ],
             "description": "Provides functionality to recursively process PHP variables",
             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
-            "time": "2016-10-03T07:41:43+00:00"
+            "time": "2016-11-19T07:33:16+00:00"
+        },
+        {
+            "name": "sebastian/resource-operations",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "time": "2015-07-28T20:34:47+00:00"
         },
         {
             "name": "sebastian/version",
-            "version": "1.0.6",
+            "version": "2.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
                 "shasum": ""
             },
+            "require": {
+                "php": ">=5.6"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
                     "src/"
             ],
             "description": "Library that helps with managing the version number of Git-hosted PHP projects",
             "homepage": "https://github.com/sebastianbergmann/version",
-            "time": "2015-06-21T13:59:46+00:00"
+            "time": "2016-10-03T07:35:21+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.8.49",
+            "version": "v3.4.23",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
+                "reference": "57f1ce82c997f5a8701b89ef970e36bb657fd09c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
-                "reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/57f1ce82c997f5a8701b89ef970e36bb657fd09c",
+                "reference": "57f1ce82c997f5a8701b89ef970e36bb657fd09c",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": "^5.5.9|>=7.0.8",
                 "symfony/polyfill-ctype": "~1.8"
             },
+            "conflict": {
+                "symfony/console": "<3.4"
+            },
+            "require-dev": {
+                "symfony/console": "~3.4|~4.0"
+            },
+            "suggest": {
+                "symfony/console": "For validating YAML files using the lint command"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2018-11-11T11:18:13+00:00"
+            "time": "2019-02-23T15:06:07+00:00"
+        },
+        {
+            "name": "webmozart/assert",
+            "version": "1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozart/assert.git",
+                "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
+                "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.3 || ^7.0",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.6",
+                "sebastian/version": "^1.0.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Webmozart\\Assert\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Assertions to validate method input/output with nice error messages.",
+            "keywords": [
+                "assert",
+                "check",
+                "validate"
+            ],
+            "time": "2018-12-25T11:19:39+00:00"
         }
     ],
     "aliases": [],
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
-        "php": ">=5.3"
+        "php": ">=5.6"
     },
     "platform-dev": [],
     "platform-overrides": {
diff --git a/src/algorithm.php b/src/algorithm.php
deleted file mode 100644 (file)
index 9873e67..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-namespace PFF;
-
-class TopSort
-{
-    private $following, $visited = array(), $result = array();
-
-    private function getFollowing($obj)
-    {
-        return call_user_func($this->following, $obj);
-    }
-
-    private function once($obj)
-    {
-        if (in_array($obj, $this->visited)) {
-            return false;
-        } else {
-            $this->visited[] = $obj;
-            return true;
-        }
-    }
-
-    private function visit($obj, $chain)
-    {
-        if (in_array($obj, $chain)) {
-            $chain[] = $obj;
-            return $chain;
-        }
-
-        if ($this->once($obj)) {
-            $chain[] = $obj;
-            foreach ($this->getFollowing($obj) as $following) {
-                $loop = $this->visit($following, $chain);
-                if ($loop !== false)
-                    return $loop;
-            }
-            $this->result[] = $obj;
-        }
-        return false;
-    }
-
-    public static function sort($initialNodes, $following)
-    {
-        $sort = new self;
-        $sort->following = $following;
-
-        foreach ($initialNodes as $start) {
-            $loop = $sort->visit($start, array());
-            if ($loop !== false)
-                return array(false, $loop);
-        }
-        return array(true, $sort->result);
-    }
-}
-
diff --git a/src/cli.php b/src/cli.php
deleted file mode 100644 (file)
index 05ec6f5..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-
-namespace PFF;
-
-abstract class CLI
-{
-    private function getArgs()
-    {
-        global $argv;
-        if (is_array($argv))
-            return $argv;
-        if (@is_array($_SERVER['argv']))
-            return $_SERVER['argv'];
-        throw new \Exception("Could not read command arguments (register_argc_argv=Off?)");
-    }
-
-    protected abstract function commands();
-
-    public function printUsage($name)
-    {
-        echo "Usage: $name <command> [parameter...]\n\n";
-        echo "Available commands:\n\n";
-
-        $cmds = $this->commands();
-
-        $max_len = 0;
-        foreach ($cmds as $cmd) {
-            list($key, $method, $description) = $cmd;
-            $max_len = max($max_len, strlen($key));
-        }
-
-        $pad = floor(($max_len + 11) / 8) * 8;
-        foreach ($cmds as $cmd) {
-            list($key, $method, $description) = $cmd;
-
-            $prefix = "    ".str_pad($key, $pad);
-            foreach (explode("\n", $description) as $dsc) {
-                echo $prefix.$dsc."\n";
-                $prefix = str_repeat(' ', $pad + 4);
-            }
-            
-        }
-        echo "\n";
-    }
-
-    public function execute()
-    {
-        $args = $this->getArgs();
-
-        if (count($args) <= 1) {
-            $this->printUsage($args[0]);
-            return 1;
-        }
-
-        $command = $args[1];
-        $command_args = array_slice($args, 2);
-
-        foreach ($this->commands() as $cmd) {
-            list($key, $method, $description) = $cmd;
-            if ($key === $command) {
-                $m = new \ReflectionMethod(get_class($this), $method);
-                if ($m->getNumberOfRequiredParameters() > count($command_args)) {
-                    $params = $m->getParameters();
-                    $names = array();
-                    for ($i = count($command_args); $i < $m->getNumberOfRequiredParameters(); ++$i) {
-                        $names[] = $params[$i]->name;
-                    }
-                    echo 'Missing required parameters: '.implode(', ', $names)."\n";
-                    return 1;
-                }
-
-                return $m->invokeArgs($this, $command_args);
-            }
-        }
-
-        echo "Unknown command.\n";
-        return 1;
-    }
-
-    public static function run()
-    {
-        if (php_sapi_name() === 'cli') {
-            $cli = new static;
-            $code = $cli->execute();
-            exit($code);
-        }
-    }
-}
index cbf69347bcd691549ff1c309ab318d56dab332e6..10c374b527a1e1cb245058d03046422bc7636a82 100644 (file)
@@ -59,6 +59,11 @@ final class Collection
         return $result;
     }
 
+    /**
+     * @param \Traversable $collection
+     * @param callable $key
+     * @return array
+     */
     public static function groupBy($collection, $key)
     {
         $groups = array();
@@ -67,39 +72,45 @@ final class Collection
         return $groups;
     }
 
+    /**
+     * @param \Traversable $collection
+     * @param string $propertyName
+     * @return array
+     * @throws \Exception
+     */
     public static function groupByProperty($collection, $propertyName)
     {
-        $groups = array();
-        foreach ($collection as $item) {
-            $key = $item->$propertyName;
-            Arr::pushToKey($groups, $key, $item);
-        }
-        return $groups;
+        return self::groupBy($collection, function ($item) use ($propertyName) {
+            return MapLike::get($item, $propertyName);
+        });
     }
 
-    public static function groupByMethod(/*$collection, $methodName, ...$args*/)
+    /**
+     * @param \Traversable $collection
+     * @param string $methodName
+     * @param mixed ...$methodArgs
+     * @return array
+     */
+    public static function groupByMethod($collection, $methodName, ...$methodArgs)
     {
-        $args = func_get_args();
-        $collection = $args[0];
-        $methodName = $args[1];
-        $methodArgs = array_slice($args, 2);
-
-        $groups = array();
-        foreach ($collection as $item) {
-            $key = call_user_func_array(array($item, $methodName), $methodArgs);
-            Arr::pushToKey($groups, $key, $item);
-        }
-        return $groups;
+        return self::groupBy($collection, function ($item) use ($methodArgs, $methodName) {
+            return call_user_func_array(array($item, $methodName), $methodArgs);
+        });
     }
 
     /**
      * indexByProperty($collection, $propertyName) === array_column($collection, null, $propertyName) for PHP >= 7
+     *
+     * @param \Traversable $collection
+     * @param string $propertyName
+     * @return array
+     * @throws \Exception
      */
     public static function indexByProperty($collection, $propertyName)
     {
         $groups = array();
         foreach ($collection as $item) {
-            $key = is_object($item) ? $item->$propertyName : $item[$propertyName];
+            $key = MapLike::get($item, $propertyName);
             $groups[$key] = $item;
         }
         return $groups;
@@ -107,18 +118,28 @@ final class Collection
 
     /**
      * columnByProperty($collection, $value, $key) === array_column($collection, $value, $key) for PHP >= 7
+     *
+     * @param \Traversable $collection
+     * @param string $valueProperty
+     * @param string $keyProperty
+     * @return array
+     * @throws \Exception
      */
     public static function columnByProperty($collection, $valueProperty, $keyProperty)
     {
         $groups = array();
         foreach ($collection as $item) {
-            $key = is_object($item) ? $item->$keyProperty : $item[$keyProperty];
-            $value = is_object($item) ? $item->$valueProperty : $item[$valueProperty];
+            $key = MapLike::get($item, $keyProperty);
+            $value = MapLike::get($item, $valueProperty);
             $groups[$key] = $value;
         }
         return $groups;
     }
 
+    /**
+     * @param \Traversable $collection
+     * @return array
+     */
     public static function inits($collection)
     {
         $result = array();
@@ -133,4 +154,3 @@ final class Collection
         return $result;
     }
 }
-
diff --git a/src/container.php b/src/container.php
deleted file mode 100644 (file)
index 9f1543b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-namespace PFF;
-
-// Dependency injection container
-
-class Container
-{
-    private $values = array();
-
-    public function getWithArgs($id, $args)
-    {
-        if (!array_key_exists($id, $this->values))
-            throw new \InvalidArgumentException('Identifier "'.$id.'" is not defined.');
-
-        $v = $this->values[$id];
-        if ($v[0] == 'function') {
-            return call_user_func_array($v[1], $args);
-        } elseif ($v[0] == 'factory') {
-            $value = call_user_func_array($v[1], $args);
-            $this->values[$id] = array('value', $value);
-            return $value;
-        } else /*value*/ {
-            return $v[1];
-        }
-    }
-
-    public function get()
-    {
-        $args = func_get_args();
-        $id = array_shift($args);
-        return $this->getWithArgs($id, $args);
-    }
-
-    public function __call($name, $args)
-    {
-        switch ($name) {
-        case 'set':
-            $this->values[$args[0]] = array('value', $args[1]);
-            return $this;
-        case 'setFunction':
-            $this->values[$args[0]] = array('function', $args[1]);
-            return $this;
-        case 'setFactory':
-            $this->values[$args[0]] = array('factory', $args[1]);
-            return $this;
-        default:
-            return $this->getWithArgs($name, $args);
-        }
-    }
-
-    private static $instance = null;
-
-    public static function getInstance()
-    {
-        if (!self::$instance)
-            self::$instance = new self;
-        return self::$instance;
-    }
-
-    public static function __callStatic($name, $args)
-    {
-        return call_user_func_array(array(self::getInstance(), $name), $args);
-    }
-}
index 79a6d428a18308a8bd5b7b6554e6562921f4bfda..b39309d1bd66f8969c8a2d0c2489901db2bebb88 100644 (file)
@@ -141,7 +141,7 @@ final class DateFormat
             case self::DATE_MIDDLE_ENDIAN:
                 return $controls[1].$separator.$controls[2].$separator.$controls[0];
             default:
-                throw new Exception('Bad date format');
+                throw new \Exception('Bad date format');
         }
     }
 
index 9e0a9ed44581daed875ec227b166235cda4066ad..d7f26f8e3b4491b24d17fe55b3c084ad81582679 100644 (file)
@@ -175,7 +175,7 @@ class Tag
     }
 
     /**
-     * @param string $raw
+     * @param string|array $raw
      * @return Tag
      */
     public function raw($raw)
diff --git a/src/io/pushback.php b/src/io/pushback.php
deleted file mode 100644 (file)
index e2dfc8b..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-namespace PFF\IO;
-
-interface PushBackInputStream
-{
-    public function close();
-    public function getc();
-    public function ungetc($char);
-}
-
-class FileInputStream implements PushBackInputStream
-{
-    private $fd, $buffer = array();
-
-    public function __construct($path, $mode)
-    {
-        $this->fd = fopen($path, $mode);
-    }
-
-    public function __destruct()
-    {
-        $this->close();
-    }
-
-    public function close()
-    {
-        if ($this->fd) {
-            fclose($this->fd);
-            $this->fd = null;
-        }
-    }
-
-    public function getc()
-    {
-        if (count($this->buffer)) {
-            return array_shift($this->buffer);
-        } else {
-            return fgetc($this->fd);
-        }
-    }
-
-    public function ungetc($char)
-    {
-        array_unshift($this->buffer, $char);
-    }
-}
-
-class StringInputStream implements PushBackInputStream
-{
-    private $string, $position;
-
-    public function __construct($string)
-    {
-        $this->string = $string;
-        $this->position = 0;
-    }
-
-    public function close()
-    {
-        if ($this->string !== null)
-            $this->string = null;
-    }
-
-    public function getc()
-    {
-        if ($this->position >= strlen($this->string))
-            return false;
-        else
-            return $this->string[$this->position++];
-    }
-
-    public function ungetc($char)
-    {
-        --$this->position;
-    }
-}
-
diff --git a/src/maplike.php b/src/maplike.php
new file mode 100644 (file)
index 0000000..c092a00
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace PFF;
+
+final class MapLike
+{
+    public static function get($mapLike, $key, $default = null)
+    {
+        if (is_array($mapLike)) {
+            if (array_key_exists($key, $mapLike)) {
+                return $mapLike[$key];
+            } else {
+                return $default;
+            }
+        } elseif (is_object($mapLike)) {
+            try {
+                return $mapLike->$key;
+            } catch (\Exception $e) {
+                return $default;
+            }
+        } else {
+            throw new \Exception("Not a map");
+        }
+    }
+}
diff --git a/src/mixins.php b/src/mixins.php
deleted file mode 100644 (file)
index 3026b13..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-namespace PFF;
-
-class Mixins
-{
-    private $methods = array();
-
-    public function __construct($object, $mixins)
-    {
-        foreach ($mixins as $class) {
-            if (!class_exists($class))
-                throw new \Exception('Tried to inherit non-existant class \''.$class.'\'.');
-
-            $mixin = new $class($object);
-            $methods = get_class_methods($mixin);
-            if (is_array($methods))
-                foreach ($methods as $method)
-                    $this->methods[strtolower($method)][] = $mixin;
-        }
-    }
-
-    private $current_call_method = null;
-    private $current_call_mixins = null;
-
-    public function __call($method, $args = array())
-    {
-        $m = strtolower($method);
-        if (!isset($this->methods[$m]))
-            throw new \Exception('Call to undefined method ' . get_class($this) . "::$method()");
-
-        $this->current_call_method = $method;
-        $this->current_call_mixins = $this->methods[$m];
-        $result = call_user_func_array(array($this, 'call_next_method'), $args);
-        $this->current_call_method = null;
-        $this->current_call_mixins = null;
-        return $result;
-    }
-
-    public function call_next_method()
-    {
-        if ($this->current_call_mixins === null)
-            throw new \Exception('call_next_method is invoked outside of mixin method.');
-
-        $mixin = array_pop($this->current_call_mixins);
-        if ($mixin === null)
-            throw new \Exception('No next method for ' . get_class($this) . "::$method()");
-
-        return call_user_func_array(array($mixin, $this->current_call_method), func_get_args());
-    }
-}
-
-abstract class Mixable
-{
-    protected abstract function __mixins();
-
-    protected $mixins;
-
-    public function __construct()
-    {
-        $this->mixins = new Mixins($this, $this->__mixins());
-    }
-
-    public function __call($method, $args = array())
-    {
-        return call_user_func_array(array($this->mixins, $method), $args);
-    }
-
-    public function call_next_method()
-    {
-        return call_user_func_array(array($this->mixins, 'call_next_method'), func_get_args());
-    }
-
-    public function __clone()
-    {
-    }
-}
-
-class Mixin
-{
-    protected $self;
-
-    public function __construct($self)
-    {
-        $this->self = $self;
-    }
-
-    protected function call_next_method()
-    {
-        return $this->self->call_next_method(func_get_args());
-    }
-}
-
diff --git a/src/native_template.php b/src/native_template.php
deleted file mode 100644 (file)
index 286712b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-namespace PFF;
-
-class NativeTemplate
-{
-    private $_dirs, $_context = array(), $_layout = null, $_content = '';
-
-    public function __construct($dirs)
-    {
-        $this->_dirs = $dirs;
-    }
-
-    public function __get($key)
-    {
-        return array_key_exists($key, $this->_context) ? $this->_context[$key] : null;
-    }
-
-    public function __set($key, $value)
-    {
-        $this->_context[$key] = $value;
-    }
-
-    public function render($file, $context=array())
-    {
-        $this->_context = $context;
-
-        while ($file) {
-            $this->_content = $this->renderFile($file);
-
-            $file = $this->_layout;
-            $this->_layout = null;
-        }
-        return $this->_content;
-    }
-
-    private function renderFile($file)
-    {
-        $previous = set_error_handler(array($this, '_errorHandler'));
-        ob_start();
-        try {
-            include $this->findFile($file);
-        } catch (\Exception $e) {
-            ob_end_clean();
-            set_error_handler($previous);
-            throw $e;
-        }
-        $output = ob_get_contents();
-        ob_end_clean();
-        set_error_handler($previous);
-        return $output;
-    }
-
-    public function _errorHandler($errno, $errstr, $errfile, $errline)
-    {
-        if (error_reporting() & $errno)
-            throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
-    }
-
-    private function findFile($file)
-    {
-        foreach ($this->_dirs as $dir) {
-            $f = $dir . DIRECTORY_SEPARATOR . $file;
-            if (is_file($f))
-                return $f;
-        }
-        throw new \Exception("Template '{$file}' was not found.");
-    }
-
-    function escape($text)
-    {
-        return \PFF\HtmlBuilder\Text::escape($text);
-    }
-
-    function e($text)
-    {
-        echo $this->escape($text);
-    }
-
-    function layout($name)
-    {
-        $this->_layout = $name;
-    }
-
-    function content()
-    {
-        return $this->_content;
-    }
-}
-
index 57411a38cba1cade19f0983ae4590e0ee68b913e..640387c74d468b9b17b35ea1d364c60b9a4d3929 100644 (file)
@@ -28,4 +28,3 @@ class Regexp
         return '!^(http|https|ftp|gopher)\://('.$ip.'|'.$dom.')!i';
     }
 }
-
diff --git a/src/shell.php b/src/shell.php
deleted file mode 100644 (file)
index 6aa5f0d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace PFF;
-
-class Shell
-{
-    public static function call()
-    {
-        self::callv(func_get_args());
-    }
-
-    public static function callv(array $command)
-    {
-        $str = '';
-        foreach ($command as $part) {
-            $str .= escapeshellarg($part) . ' ';
-        }
-        $descriptorspec = array(
-            0 => STDIN,
-            1 => STDOUT,
-            2 => STDERR
-        );
-        $process = proc_open($str, $descriptorspec, $pipes);
-        proc_close($process);
-    }
-}
index 31785846ba855767bf442703ea36a6d3c196d961..f063a936d9ae2b78f8e0854eb821b330e9d3f8ef 100644 (file)
@@ -15,4 +15,3 @@ final class Str
         return !$length || substr($haystack, -$length) === $needle;
     }
 }
-
diff --git a/src/symbol.php b/src/symbol.php
deleted file mode 100644 (file)
index 8c140b0..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-namespace PFF;
-
-final class Symbol
-{
-    private static $symbols = array();
-    private $name;
-
-    private function __construct()
-    {
-    }
-
-    function __clone()
-    {
-        throw new \Exception('Cloning of symbols is not allowed.');
-    }
-
-    function __wakeup()
-    {
-        throw new \Exception('Deserialization of symbols is not allowed.');
-    }
-
-    public function name()
-    {
-        return $this->name;
-    }
-
-    public static function intern($name)
-    {
-        if (array_key_exists($name, self::$symbols))
-            return self::$symbols[$name];
-
-        $symbol = new self;
-        $symbol->name = $name;
-        self::$symbols[$name] = $symbol;
-        return $symbol;
-    }
-
-    public static function __callStatic($name, $args)
-    {
-        return self::intern($name);
-    }
-}
-
diff --git a/src/topsort.php b/src/topsort.php
new file mode 100644 (file)
index 0000000..e75a287
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace PFF;
+
+class TopSort
+{
+    private $following, $visited = array(), $result = array();
+
+    private function getFollowing($obj)
+    {
+        return call_user_func($this->following, $obj);
+    }
+
+    private function once($obj)
+    {
+        if (in_array($obj, $this->visited)) {
+            return false;
+        } else {
+            $this->visited[] = $obj;
+            return true;
+        }
+    }
+
+    private function visit($obj, $chain)
+    {
+        if (in_array($obj, $chain)) {
+            $chain[] = $obj;
+            return $chain;
+        }
+
+        if ($this->once($obj)) {
+            $chain[] = $obj;
+            foreach ($this->getFollowing($obj) as $following) {
+                $loop = $this->visit($following, $chain);
+                if ($loop !== false)
+                    return $loop;
+            }
+            $this->result[] = $obj;
+        }
+        return false;
+    }
+
+    public static function sort($initialNodes, $following)
+    {
+        $sort = new self;
+        $sort->following = $following;
+
+        foreach ($initialNodes as $start) {
+            $loop = $sort->visit($start, array());
+            if ($loop !== false)
+                return array(false, $loop);
+        }
+        return array(true, $sort->result);
+    }
+}
index e0def0c10bfac7900d3916d8caa67353dd9aeeb9..bb5d4b060ea79d0a369cf6c81aafbfdc0d4af55d 100644 (file)
@@ -65,5 +65,17 @@ class ArrTest extends PHPUnit_Framework_TestCase
         $flat = \PFF\Arr::flatten($arr);
         $this->assertEquals(array('a', 'b', 'x', 'y', 'z', 'p'), $flat);
     }
-}
 
+    public function testPluck()
+    {
+        $arr = array(
+            (object)array('name' => 'apple',      'color' => 'green'),
+            (object)array('name' => 'carrot',     'color' => 'red'),
+            (object)array('name' => 'tomato',     'color' => 'red'),
+            (object)array('name' => 'grapefruit', 'color' => 'green'),
+        );
+        $colors = \PFF\Arr::pluck($arr, 'color');
+        $this->assertEquals(4, count($colors));
+        $this->assertEquals(['green', 'red', 'red', 'green'], $colors);
+    }
+}
diff --git a/t/ContainerTest.php b/t/ContainerTest.php
deleted file mode 100644 (file)
index 1948e68..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-class ContainerTest extends PHPUnit_Framework_TestCase
-{
-    public function testValue()
-    {
-        \PFF\Container::set('text', 'Hello, World');
-        $this->assertEquals('Hello, World', \PFF\Container::text());
-    }
-
-    public function testFunction()
-    {
-        \PFF\Container::setFunction('wrap', function($str) { return '('.$str.')'; });
-        $this->assertEquals('(i love lisp)', \PFF\Container::wrap('i love lisp'));
-    }
-
-    public function testFactory()
-    {
-        \PFF\Container::setFactory('wrapOnce', function($str) { return '('.$str.')'; });
-        $this->assertEquals('(i love lisp)', \PFF\Container::wrapOnce('i love lisp'));
-        $this->assertEquals('(i love lisp)', \PFF\Container::wrapOnce('i hate lisp'));
-    }
-}
-
index a600516fad0f96cd8d6f07f3ec67b20c4ded216d..2bab90eb6099c030cce3c74b6b84e1525abffb85 100644 (file)
@@ -32,5 +32,72 @@ class FormatTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(\PFF\DateFormat::DATE_BIG_ENDIAN | \PFF\DateFormat::DATE_SPACES | \PFF\DateFormat::TIME_12HOURS_LOWER | \PFF\DateFormat::TIME_SECONDS,
                                                                \PFF\DateFormat::datetimeFlagsFromString("big-endian spaces \n 12-lower Seconds"));
     }
-}
 
+    public function testMakeFormat()
+    {
+        $flags = \PFF\DateFormat::DATETIME_DEFAULT;
+        $this->assertEquals('%Y-%m-%d %H:%M', \PFF\DateFormat::makeFormat($flags, \PFF\DateFormat::$strftimeControls));
+        $this->assertEquals('Y-m-d H:i', \PFF\DateFormat::makeFormat($flags, \PFF\DateFormat::$dateControls));
+        $this->assertEquals('yy-mm-dd HH:mm', \PFF\DateFormat::makeFormat($flags, \PFF\DateFormat::$pickerControls));
+
+        $flags2 = \PFF\DateFormat::DATETIME_US;
+        $this->assertEquals('%m/%d/%Y %l:%M %p', \PFF\DateFormat::makeFormat($flags2, \PFF\DateFormat::$strftimeControls));
+        $this->assertEquals('m/d/Y h:i A', \PFF\DateFormat::makeFormat($flags2, \PFF\DateFormat::$dateControls));
+        $this->assertEquals('mm/dd/yy hh:mm TT', \PFF\DateFormat::makeFormat($flags2, \PFF\DateFormat::$pickerControls));
+
+        $flags3 = \PFF\DateFormat::DATETIME_EUROPEAN;
+        $this->assertEquals('%d.%m.%Y %H:%M', \PFF\DateFormat::makeFormat($flags3, \PFF\DateFormat::$strftimeControls));
+        $this->assertEquals('d.m.Y H:i', \PFF\DateFormat::makeFormat($flags3, \PFF\DateFormat::$dateControls));
+        $this->assertEquals('dd.mm.yy HH:mm', \PFF\DateFormat::makeFormat($flags3, \PFF\DateFormat::$pickerControls));
+
+        $flags4 = \PFF\DateFormat::DATE_US | \PFF\DateFormat::TIME_12HOURS_LOWER;
+        $this->assertEquals('%m/%d/%Y %l:%M %P', \PFF\DateFormat::makeFormat($flags4, \PFF\DateFormat::$strftimeControls));
+        $this->assertEquals('m/d/Y h:i a', \PFF\DateFormat::makeFormat($flags4, \PFF\DateFormat::$dateControls));
+
+        $flags5 = \PFF\DateFormat::DATE_BIG_ENDIAN | \PFF\DateFormat::TIME_24HOURS | \PFF\DateFormat::TIME_SECONDS | \PFF\DateFormat::DATE_SPACES;
+        $this->assertEquals('Y m d H:i:s', \PFF\DateFormat::makeFormat($flags5, \PFF\DateFormat::$dateControls));
+
+        $flags6 = \PFF\DateFormat::DATE_BIG_ENDIAN | \PFF\DateFormat::TIME_12HOURS_LOWER | \PFF\DateFormat::TIME_SECONDS | \PFF\DateFormat::DATE_SLASHES;
+        $this->assertEquals('Y/m/d h:i:s a', \PFF\DateFormat::makeFormat($flags6, \PFF\DateFormat::$dateControls));
+
+        $flags7 = \PFF\DateFormat::DATE_BIG_ENDIAN | \PFF\DateFormat::TIME_12HOURS_UPPER | \PFF\DateFormat::TIME_SECONDS | \PFF\DateFormat::DATE_SLASHES;
+        $this->assertEquals('Y/m/d h:i:s A', \PFF\DateFormat::makeFormat($flags7, \PFF\DateFormat::$dateControls));
+    }
+
+    public function testMakeFormatWOTime()
+    {
+        $flags = \PFF\DateFormat::DATE_DEFAULT;
+        $this->assertEquals(
+            \PFF\DateFormat::makeFormat($flags, \PFF\DateFormat::$strftimeControls),
+            \PFF\DateFormat::makeDateFormat($flags, \PFF\DateFormat::$strftimeControls)
+        );
+    }
+
+    public function testImpossibleDate()
+    {
+        $this->expectException(Exception::class);
+        $this->expectExceptionMessageRegExp('/Bad/');
+        \PFF\DateFormat::makeFormat(\PFF\DateFormat::DATE_LITTLE_ENDIAN | \PFF\DateFormat::DATE_MIDDLE_ENDIAN, \PFF\DateFormat::$dateControls);
+    }
+
+    public function testImpossibleTime()
+    {
+        $this->expectException(Exception::class);
+        $this->expectExceptionMessageRegExp('/Bad/');
+        \PFF\DateFormat::makeTimeFormat(\PFF\DateFormat::TIME_SECONDS, \PFF\DateFormat::$dateControls);
+    }
+
+    public function testParse()
+    {
+        $date = \PFF\DateFormat::parseDate(\PFF\DateFormat::DATE_US, '05/01/2018');
+        $this->assertEquals(118, $date['tm_year']);
+        $this->assertEquals(4, $date['tm_mon']);
+        $this->assertEquals(1, $date['tm_mday']);
+    }
+
+    public function testFormat()
+    {
+        $str = \PFF\DateFormat::formatDate(\PFF\DateFormat::DATE_DEFAULT, 1525132800);
+        $this->assertEquals('2018-05-01', $str);
+    }
+}
index bdef45dc4677dc21493eb1bc3f1a10c49106ec75..cf24739ad6f384a792718c246f7f04538387e106 100644 (file)
@@ -10,5 +10,24 @@ class HtmlBuilderTest extends PHPUnit_Framework_TestCase
 
         $this->assertEquals('<div class="container">Hello, &quot;World&quot;<a>click <b>me</b></a></div>', (string)$tag);
     }
-}
 
+    public function testAttrs()
+    {
+        $tag = \PFF\HtmlBuilder\Tag::div(array('class' => 'container'))
+            ->attrs(['data-somedata' => '', 'class' => 'red', 'rel' => 'what?'])
+            ->append(['Hello', ', "World"'])
+            ->append(\PFF\HtmlBuilder\Tag::create('a', ['href' => '#', 'onClick' => 'clicked()'], 'cli', 'ck', ' ')->raw('<b>me</b>'))
+            ->raw(['&nbsp;', '&mdash;'])
+            ->append((new \PFF\HtmlBuilder\Tag('span', null, 'Thanks!'))->unsetAttr('font'));
+
+        $tag->addClass('button')
+            ->removeClass('container');
+        $tag->toggleAttr("data-somedata", "somedatavalue", true);
+        $tag->toggleClass('red', false);
+        $tag->toggleClass('red', true);
+        $tag->toggleClass('red', false);
+        $tag->unsetAttr('rel');
+
+        $this->assertEquals('<div class="button" data-somedata="somedatavalue">Hello, &quot;World&quot;<a href="#" onClick="clicked()">click <b>me</b></a>&nbsp;&mdash;<span>Thanks!</span></div>', (string)$tag);
+    }
+}
diff --git a/t/MapLikeTest.php b/t/MapLikeTest.php
new file mode 100644 (file)
index 0000000..1320d35
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+class MapLikeTest extends PHPUnit_Framework_TestCase
+{
+    function testGetArray()
+    {
+        $map = ['a' => '1', 'b' => 2];
+
+        $this->assertEquals('1', \PFF\MapLike::get($map, 'a'));
+        $this->assertEquals(33, \PFF\MapLike::get($map, 'c', 33));
+    }
+
+    function testGetObject()
+    {
+        $map = (object)['a' => '1', 'b' => 2];
+
+        $this->assertEquals('1', \PFF\MapLike::get($map, 'a'));
+        $this->assertEquals(33, \PFF\MapLike::get($map, 'c', 33));
+    }
+
+    function testGetUnsupported()
+    {
+        $this->expectException(Exception::class);
+        $this->expectExceptionMessage('Not a map');
+        \PFF\MapLike::get('map', 'a');
+    }
+}
diff --git a/t/MixinsTest.php b/t/MixinsTest.php
deleted file mode 100644 (file)
index fb0970c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-class SomeMixin extends \PFF\Mixin
-{
-    public function getSmthUseful()
-    {
-        return 'a';
-    }
-
-    public function setB($newValue)
-    {
-        $this->self->b = $newValue;
-    }
-}
-
-class WrapMixin extends \PFF\Mixin
-{
-    public function getSmthUseful()
-    {
-        return '(' . $this->call_next_method() . ')';
-    }
-
-    public function doSmthElse($str)
-    {
-        return strrev($str);
-    }
-}
-
-class Mixture extends \PFF\Mixable
-{
-    protected function __mixins() { return array('SomeMixin', 'WrapMixin'); }
-
-    public $b = 'b';
-
-    public function doSmthElse($str)
-    {
-        return strtoupper($this->mixins->doSmthElse($str));
-    }
-}
-
-class MixinsTest extends PHPUnit_Framework_TestCase
-{
-    public function testSetter()
-    {
-        $mixture = new Mixture;
-        $mixture->setB('B');
-        $this->assertEquals('B', $mixture->b);
-    }
-
-    public function testWrapping()
-    {
-        $mixture = new Mixture;
-        $this->assertEquals('(a)', $mixture->getSmthUseful());
-    }
-
-    public function testOverriding()
-    {
-        $mixture = new Mixture;
-        $this->assertEquals('LARCH', $mixture->doSmthElse('hCraL'));
-    }
-}
-
diff --git a/t/RegexpTest.php b/t/RegexpTest.php
new file mode 100644 (file)
index 0000000..ea5cdbf
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+class RegexpTest extends PHPUnit_Framework_TestCase
+{
+    function testEmail()
+    {
+        $this->assertTrue(preg_match(\PFF\Regexp::email(), "a@b.com") !== 0);
+        $this->assertTrue(preg_match(\PFF\Regexp::email(), " a @ b . com ") === 0);
+    }
+
+    function testUrl()
+    {
+        $this->assertTrue(preg_match(\PFF\Regexp::url(), "mailto:a@b.com") === 0);
+        $this->assertTrue(preg_match(\PFF\Regexp::url(), "https://ab.com") !== 0);
+    }
+}
diff --git a/t/TopSortTest.php b/t/TopSortTest.php
new file mode 100644 (file)
index 0000000..ed200eb
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+use PFF\Arr;
+
+class TopSortTest extends PHPUnit_Framework_TestCase
+{
+    function testAlchemy()
+    {
+        $nodes = [
+            'time' => ['sand', 'glass'],
+            'fruit' => ['sun', 'tree'],
+            'stone' => ['air', 'lava'],
+            'steam' => ['water', 'fire'],
+            'lava' => ['earth', 'fire'],
+            'sand' => ['air', 'stone'],
+            'sun' => ['fire', 'sky'],
+            'glass' => ['fire', 'sand'],
+            'sky' => ['air', 'cloud'],
+            'cloud' => ['air', 'steam'],
+            'alcohol' => ['fruit', 'time'],
+        ];
+
+        list($success, $sorted) = \PFF\TopSort::sort(['alcohol'], function ($node) use ($nodes) {
+            return Arr::get($nodes, $node, []);
+        });
+
+        $this->assertTrue($success, 'Sorted successfully');
+        $this->assertEquals([
+            'fire',
+            'air',
+            'water',
+            'steam',
+            'cloud',
+            'sky',
+            'sun',
+            'tree',
+            'fruit',
+            'earth',
+            'lava',
+            'stone',
+            'sand',
+            'glass',
+            'time',
+            'alcohol',
+        ], $sorted);
+    }
+
+    function testLoop()
+    {
+        $nodes = [
+            'a' => ['b', 'c'],
+            'b' => ['c', 'a'],
+            'c' => ['a', 'b'],
+        ];
+
+        list($success, $loop) = \PFF\TopSort::sort(['a'], function ($node) use ($nodes) {
+            return Arr::get($nodes, $node, []);
+        });
+
+        $this->assertFalse($success, 'Sort impossible');
+        $this->assertEquals(['a', 'b', 'c', 'a'], $loop);
+    }
+}
diff --git a/t/native_template/NativeTemplateTest.php b/t/native_template/NativeTemplateTest.php
deleted file mode 100644 (file)
index ba2cf9a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-class NativeTemplateTest extends PHPUnit_Framework_TestCase
-{
-    public function testEscaping()
-    {
-        $nt = new \PFF\NativeTemplate(array(dirname(__FILE__)));
-        $this->assertEquals(
-            '<b>\'test\', &quot;test&quot; &amp; test.</b>',
-            trim($nt->render('simple.html', array('text' => '\'test\', "test" & test.'))));
-    }
-
-    public function testErrorCatching()
-    {
-        $nt = new \PFF\NativeTemplate(array(dirname(__FILE__)));
-
-        $this->setExpectedExceptionRegExp('ErrorException', '/undefined_variable/');
-        $this->expectOutputString('');
-        $nt->render('syntax_error.html');
-    }
-}
-
diff --git a/t/native_template/simple.html b/t/native_template/simple.html
deleted file mode 100644 (file)
index 1101b3f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<b><?php $this->e($this->text) ?></b>
diff --git a/t/native_template/syntax_error.html b/t/native_template/syntax_error.html
deleted file mode 100644 (file)
index e968140..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo $undefined_variable ?>