diff --git a/.gitattributes b/.gitattributes
index 7f822be..34ec487 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,6 +2,8 @@
/build export-ignore
/tests export-ignore
+/resources/data/Zip32_11208.json.zip
+/resources/data/Zip32_11208.csv.zip
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
@@ -9,3 +11,4 @@
.php_cs export-ignore
.travis.yml export-ignore
phpunit.xml.dist export-ignore
+
diff --git a/.nitpick.json b/.nitpick.json
deleted file mode 100644
index 3881d8d..0000000
--- a/.nitpick.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ignore": [
- "tests/*"
- ]
-}
diff --git a/.php_cs b/.php_cs
deleted file mode 100644
index 53e4c34..0000000
--- a/.php_cs
+++ /dev/null
@@ -1,114 +0,0 @@
- [
- 'syntax' => 'short',
- ],
- 'binary_operator_spaces' => [
- 'align_double_arrow' => false,
- 'align_equals' => false,
- ],
- 'blank_line_after_namespace' => true,
- 'blank_line_after_opening_tag' => true,
- 'blank_line_before_return' => true,
- 'braces' => true,
- 'cast_spaces' => true,
- 'class_definition' => true,
- 'concat_space' => [
- 'spacing' => 'none',
- ],
- 'declare_equal_normalize' => true,
- 'elseif' => true,
- 'encoding' => true,
- 'full_opening_tag' => true,
- 'function_declaration' => true,
- 'function_typehint_space' => true,
- 'hash_to_slash_comment' => true,
- 'heredoc_to_nowdoc' => true,
- 'include' => true,
- 'indentation_type' => true,
- 'lowercase_cast' => true,
- 'lowercase_constants' => true,
- 'lowercase_keywords' => true,
- 'method_argument_space' => true,
- 'method_separation' => true,
- 'native_function_casing' => true,
- 'no_alias_functions' => true,
- 'no_blank_lines_after_class_opening' => true,
- 'no_blank_lines_after_phpdoc' => true,
- 'no_closing_tag' => true,
- 'no_empty_phpdoc' => true,
- 'no_empty_statement' => true,
- 'no_extra_consecutive_blank_lines' => true,
- 'no_leading_import_slash' => true,
- 'no_leading_namespace_whitespace' => true,
- 'no_mixed_echo_print' => true,
- 'no_multiline_whitespace_around_double_arrow' => true,
- 'no_multiline_whitespace_before_semicolons' => true,
- 'no_short_bool_cast' => true,
- 'no_singleline_whitespace_before_semicolons' => true,
- 'no_spaces_after_function_name' => true,
- 'no_spaces_inside_parenthesis' => true,
- 'no_trailing_comma_in_list_call' => true,
- 'no_trailing_comma_in_singleline_array' => true,
- 'no_trailing_whitespace_in_comment' => true,
- 'no_trailing_whitespace' => true,
- 'no_unneeded_control_parentheses' => true,
- 'no_unreachable_default_argument_value' => true,
- 'no_unused_imports' => true,
- 'no_useless_return' => true,
- 'no_whitespace_before_comma_in_array' => true,
- 'no_whitespace_in_blank_line' => true,
- 'normalize_index_brace' => true,
- 'not_operator_with_successor_space' => true,
- 'object_operator_without_whitespace' => true,
- 'ordered_class_elements' => true,
- 'ordered_imports' => [
- 'sortAlgorithm' => 'length',
- ],
- 'phpdoc_indent' => true,
- 'phpdoc_inline_tag' => true,
- 'phpdoc_no_access' => true,
- 'phpdoc_no_package' => true,
- 'phpdoc_no_useless_inheritdoc' => true,
- 'phpdoc_scalar' => true,
- 'phpdoc_single_line_var_spacing' => true,
- 'phpdoc_summary' => true,
- 'phpdoc_to_comment' => true,
- 'phpdoc_trim' => true,
- 'phpdoc_types' => true,
- 'phpdoc_var_without_name' => true,
- 'phpdoc_var_without_name' => true,
- 'psr4' => true,
- 'self_accessor' => true,
- 'short_scalar_cast' => true,
- 'simplified_null_return' => true,
- 'single_blank_line_at_eof' => true,
- 'single_blank_line_before_namespace' => true,
- 'single_class_element_per_statement' => true,
- 'single_import_per_statement' => true,
- 'single_line_after_imports' => true,
- 'single_quote' => true,
- 'space_after_semicolon' => true,
- 'standardize_not_equals' => true,
- 'switch_case_semicolon_to_colon' => true,
- 'switch_case_space' => true,
- 'ternary_operator_spaces' => true,
- 'trailing_comma_in_multiline_array' => true,
- 'trim_array_spaces' => true,
- 'unary_operator_spaces' => true,
- 'visibility_required' => [
- 'method',
- 'property',
- ],
- 'whitespace_after_comma_in_array' => true,
-];
-
-return Config::create()
- ->setFinder(Finder::create()->in(__DIR__))
- ->setRules($rules)
- ->setRiskyAllowed(true)
- ->setUsingCache(true);
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index 6fad5be..0000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-filter:
- excluded_paths: [tests/*]
-
-checks:
- php:
- remove_extra_empty_lines: true
- remove_php_closing_tag: true
- remove_trailing_whitespace: true
- fix_use_statements:
- remove_unused: true
- preserve_multiple: false
- preserve_blanklines: true
- order_alphabetically: true
- fix_php_opening_tag: true
- fix_linefeed: true
- fix_line_ending: true
- fix_identation_4spaces: true
- fix_doc_comments: true
-
-tools:
- external_code_coverage: true
diff --git a/.styleci.yml b/.styleci.yml
deleted file mode 100644
index 916d27e..0000000
--- a/.styleci.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-preset: laravel
-
-linting: true
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c8ae8ca..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-language: php
-
-php:
- - 5.5.9
- - 5.5
- - 5.6
- - 7.0
- - 7.1
- - 7.2
- - hhvm
-
-env:
- global:
- - setup=basic
-
-sudo: false
-
-matrix:
- allow_failures:
- - php: hhvm
- fast_finish: true
- include:
- - php: 5.5.9
- env: setup=lowest
- - php: hhvm
- dist: trusty
-
-cache:
- directories:
- - $HOME/.composer/cache
-
-before_install:
- - travis_retry composer self-update
-
-install:
- - if [[ $setup = 'basic' ]]; then travis_retry composer install --no-interaction --prefer-dist --no-suggest; fi
- - if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable --no-suggest; fi
- - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable --no-suggest; fi
-
-script: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
-
-after_script:
- - wget https://scrutinizer-ci.com/ocular.phar
- - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
diff --git a/phpcs.xml b/phpcs.xml
deleted file mode 100644
index bb63b97..0000000
--- a/phpcs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
- *.blade.php
- *.twig.php
- bootstrap/
- node_modules/
- public/build/
- public/css/
- public/js/
- public/vendor/
- resources/assets/
- resources/views/
- storage/
- vendor/
-
diff --git a/resources/Zip32_11208.json.zip b/resources/Zip32_11208.json.zip
new file mode 100644
index 0000000..9373398
Binary files /dev/null and b/resources/Zip32_11208.json.zip differ
diff --git a/resources/Zip32_utf8_10501_1.zip b/resources/Zip32_utf8_10501_1.zip
deleted file mode 100644
index 0e469b2..0000000
Binary files a/resources/Zip32_utf8_10501_1.zip and /dev/null differ
diff --git a/resources/converter.php b/resources/converter.php
index 5441faf..2c5d8e0 100644
--- a/resources/converter.php
+++ b/resources/converter.php
@@ -2,21 +2,21 @@
include __DIR__.'/../vendor/autoload.php';
-use Recca0120\Twzipcode\Sources\CSV;
+use Recca0120\Twzipcode\Sources\Csv;
+use Recca0120\Twzipcode\Sources\Json;
use Recca0120\Twzipcode\Storages\File;
+// https://data.gov.tw/dataset/5948
+$downloadUrl = 'https://quality.data.gov.tw/dq_download_json.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';
+$extension = 'json';
+$file = __DIR__.'/Zip32_11208.'.$extension.'.zip';
+
set_error_handler(static function ($severity, $message, $file, $line) {
throw new ErrorException($message, $severity, $severity, $file, $line);
});
-$start = microtime(true);
-$file = __DIR__.'/Zip32_utf8_10501_1.zip';
-
-// https://data.gov.tw/dataset/5948
-$url = 'https://quality.data.gov.tw/dq_download_csv.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';
-
-if (file_exists($file) === false) {
- touch($file);
+function csv($url)
+{
$contents = file_get_contents($url);
$encoding = mb_detect_encoding($contents, ['UCS-2LE', 'BIG5', 'UTF-8']);
@@ -30,11 +30,29 @@
throw new RuntimeException($contents);
}
+ return $contents;
+}
+
+function json($url)
+{
+ return file_get_contents($url);
+}
+
+$start = microtime(true);
+if (file_exists($file) === false) {
+ $contents = $extension($downloadUrl);
+
+ touch($file);
$zip = new ZipArchive;
$zip->open($file, ZipArchive::OVERWRITE);
- $zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.csv', $contents);
+ $zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.'.$extension, $contents);
$zip->close();
}
-(new File)->load(new CSV($file));
+$lookup = ['csv' => Csv::class, 'json' => Json::class];
+$class = $lookup[$extension];
+
+$source = new $class($file);
+
+(new File)->load($source);
echo 'benchmark: '.(microtime(true) - $start)."\n";
diff --git a/resources/data/zip5.rules b/resources/data/zip5.rules
index 75270a0..6b87d0a 100644
Binary files a/resources/data/zip5.rules and b/resources/data/zip5.rules differ
diff --git a/ruleset.xml b/ruleset.xml
deleted file mode 100644
index 88a68d6..0000000
--- a/ruleset.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
- 1
-
-
-
-
-
-
diff --git a/src/Address.php b/src/Address.php
index 13da642..9c5a3a4 100644
--- a/src/Address.php
+++ b/src/Address.php
@@ -21,9 +21,6 @@ class Address
/** @var Normalizer */
public $normalizer;
- /** @var Tricky */
- public $tricky;
-
/** @var JArray */
public $tokens = [];
diff --git a/src/Rule.php b/src/Rule.php
index dabf7c7..f426d44 100644
--- a/src/Rule.php
+++ b/src/Rule.php
@@ -138,7 +138,8 @@ private function tokenize($rule, Closure $addressResolver)
'[連至單雙全](?=[\d全]|$)',
];
- $addressResolver($this->normalize($rule)->replace('/'.implode('|', $pattern).'/u',
+ $addressResolver($this->normalize($rule)->replace(
+ '/'.implode('|', $pattern).'/u',
function ($m) use (&$tokens) {
$token = &$m[0];
if ($token === '連') {
@@ -148,7 +149,8 @@ function ($m) use (&$tokens) {
$tokens[] = $token;
return $token === '附號全' ? '號' : '';
- }));
+ }
+ ));
return $tokens;
}
@@ -187,8 +189,11 @@ private function normalizeAddress(Address $address, JArray $ruleAddressTokens)
return new Address(
new JArray($address->tokens()->filter(function ($token) use ($removeUnits) {
- return isset($token[Address::UNIT]) === true && in_array($token[Address::UNIT], $removeUnits,
- true) === false;
+ return isset($token[Address::UNIT]) === true && in_array(
+ $token[Address::UNIT],
+ $removeUnits,
+ true
+ ) === false;
})->map(function ($token) {
return implode('', $token);
}))
diff --git a/src/Rules.php b/src/Rules.php
index 692051b..8864ec7 100644
--- a/src/Rules.php
+++ b/src/Rules.php
@@ -14,9 +14,6 @@ class Rules
*/
private $storage;
- /**
- * @param Storage|null $storage
- */
public function __construct(Storage $storage = null)
{
$this->storage = $storage ?: new File;
diff --git a/src/Sources/CSV.php b/src/Sources/Csv.php
similarity index 94%
rename from src/Sources/CSV.php
rename to src/Sources/Csv.php
index e00710b..6f32253 100644
--- a/src/Sources/CSV.php
+++ b/src/Sources/Csv.php
@@ -2,7 +2,7 @@
namespace Recca0120\Twzipcode\Sources;
-class CSV extends Source
+class Csv extends Source
{
/** @var string */
protected $file;
diff --git a/src/Sources/Json.php b/src/Sources/Json.php
new file mode 100644
index 0000000..1324844
--- /dev/null
+++ b/src/Sources/Json.php
@@ -0,0 +1,21 @@
+ $data['郵遞區號'],
+ 'county' => $data['縣市名稱'],
+ 'district' => $data['鄉鎮市區'],
+ 'rule' => implode(',', $data),
+ ];
+ }, json_decode($this->contents(), true));
+ }
+}
diff --git a/src/Sources/Source.php b/src/Sources/Source.php
index a611bec..72ad37c 100644
--- a/src/Sources/Source.php
+++ b/src/Sources/Source.php
@@ -33,10 +33,15 @@ protected function rows()
return ! empty(trim($line));
});
- return array_map(static function ($line) {
- $data = explode(',', $line);
+ return array_map(static function ($rule) {
+ $data = explode(',', $rule);
- return ['zipcode' => $data[0], 'county' => $data[1], 'district' => $data[2], 'text' => $line];
+ return [
+ 'zipcode' => $data[0],
+ 'county' => $data[1],
+ 'district' => $data[2],
+ 'rule' => $rule,
+ ];
}, $lines);
}
@@ -51,7 +56,7 @@ protected static function prepare($rows)
? self::$tricks[$row['county'].$row['district']]
: substr($row['zipcode'], 0, 3);
- $results[$row['county']][$row['district']][$zip3][] = $row['text'];
+ $results[$row['county']][$row['district']][$zip3][] = $row['rule'];
return $results;
}, []);
diff --git a/src/Tricky.php b/src/Tricky.php
index 55034c5..f2ebe78 100644
--- a/src/Tricky.php
+++ b/src/Tricky.php
@@ -6,6 +6,7 @@ class Tricky
{
/** @var Tricky */
private static $instance;
+
private static $cached = [];
/*
@@ -87,7 +88,7 @@ public function flip($token)
public static function instance()
{
if (! self::$instance) {
- self::$instance = new self();
+ self::$instance = new self;
self::$instance->init();
}
diff --git a/src/Zipcode.php b/src/Zipcode.php
index 7dd777a..f1ca275 100644
--- a/src/Zipcode.php
+++ b/src/Zipcode.php
@@ -16,7 +16,6 @@ class Zipcode
/**
* @param string|Address $address
- * @param ?Rules $rules
*/
public function __construct($address, Rules $rules = null)
{
@@ -44,7 +43,6 @@ public function __construct($address, Rules $rules = null)
/**
* @param string|Address $address
- * @param ?Rules $rules
* @return static
*/
public static function parse($address, Rules $rules = null)
diff --git a/tests/NormalizerKaohsiungTest.php b/tests/NormalizerKaohsiungTest.php
index b7bf323..8c41889 100644
--- a/tests/NormalizerKaohsiungTest.php
+++ b/tests/NormalizerKaohsiungTest.php
@@ -1396,7 +1396,8 @@ public function testNormalizeKaohsiungAddress()
);
$this->assertSame(
'高雄市桃源區梅山里',
- (string) Normalizer::factory('高雄縣桃源鄉梅山村')->normalizeAddress());
+ (string) Normalizer::factory('高雄縣桃源鄉梅山村')->normalizeAddress()
+ );
$this->assertSame(
'高雄市那瑪夏區達卡努瓦里',
(string) Normalizer::factory('高雄縣那瑪夏鄉達卡努瓦村')->normalizeAddress()
diff --git a/tests/Sources/CsvTest.php b/tests/Sources/CsvTest.php
new file mode 100644
index 0000000..dd9e85d
--- /dev/null
+++ b/tests/Sources/CsvTest.php
@@ -0,0 +1,42 @@
+setContents('10058,臺北市,中正區,八德路1段,全
+10079,臺北市,中正區,三元街,單全
+');
+
+ $source->each(function ($zipcode, $county, $district, $rules) {
+ self::assertEquals(100, $zipcode);
+ self::assertEquals('臺北市', $county);
+ self::assertEquals('中正區', $district);
+ self::assertEquals([
+ '10058,臺北市,中正區,八德路1段,全',
+ '10079,臺北市,中正區,三元街,單全',
+ ], $rules);
+ });
+ }
+}
+
+class StubCsv extends Csv
+{
+ private $contents = '';
+
+ public function setContents($contents)
+ {
+ $this->contents = $contents;
+ }
+
+ public function contents()
+ {
+ return $this->contents;
+ }
+}
diff --git a/tests/Sources/JsonTest.php b/tests/Sources/JsonTest.php
new file mode 100644
index 0000000..3c928c4
--- /dev/null
+++ b/tests/Sources/JsonTest.php
@@ -0,0 +1,40 @@
+setContents('[{"郵遞區號":"10058","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"八德路1段","投遞範圍":"全"},{"郵遞區號":"10079","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"三元街","投遞範圍":"單全"}]');
+
+ $source->each(function ($zipcode, $county, $district, $rules) {
+ self::assertEquals(100, $zipcode);
+ self::assertEquals('臺北市', $county);
+ self::assertEquals('中正區', $district);
+ self::assertEquals([
+ '10058,臺北市,中正區,八德路1段,全',
+ '10079,臺北市,中正區,三元街,單全',
+ ], $rules);
+ });
+ }
+}
+
+class StubJson extends Json
+{
+ private $contents = '';
+
+ public function setContents($contents)
+ {
+ $this->contents = $contents;
+ }
+
+ public function contents()
+ {
+ return $this->contents;
+ }
+}
diff --git a/tests/Storages/FileTest.php b/tests/Storages/FileTest.php
index 7dfc3a6..a6454fa 100644
--- a/tests/Storages/FileTest.php
+++ b/tests/Storages/FileTest.php
@@ -7,7 +7,7 @@
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;
use Recca0120\Twzipcode\Address;
-use Recca0120\Twzipcode\Sources\CSV;
+use Recca0120\Twzipcode\Sources\Json;
use Recca0120\Twzipcode\Sources\Text;
use Recca0120\Twzipcode\Storages\File as Storage;
@@ -125,7 +125,7 @@ public function testLoadResources()
Storage::$cached = ['zip3' => null, 'zip5' => null];
$root = vfsStream::setup();
$storage = new Storage($root->url());
- $storage->flush()->load(new CSV(__DIR__.'/../../resources/Zip32_utf8_10501_1.zip'));
+ $storage->flush()->load(new Json(__DIR__.'/../../resources/Zip32_11208.json.zip'));
$address = m::mock(Address::class);