Skip to content

Commit bc30de0

Browse files
author
rozbo
committed
增加html dom操作及其单元测试。
release 1.3.0
1 parent c34c789 commit bc30de0

5 files changed

Lines changed: 197 additions & 39 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"joshcam/mysqli-database-class": "dev-master",
2222
"twig/twig":"~1.0",
2323
"overtrue/pinyin": "~3.0",
24-
"vlucas/phpdotenv": "^2.4"
24+
"vlucas/phpdotenv": "^2.4",
25+
"imangazaliev/didom": "^1.9.1"
2526
},
2627
"require-dev": {
2728
"phpunit/phpunit": "6.*"

core/App.php

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77

88

99
use Dotenv\Dotenv;
10-
use puck\Config;
11-
use puck\Route;
12-
use puck\tools\Arr;
1310
use Whoops\Run;
1411

1512
class App extends Container {
@@ -32,9 +29,6 @@ public function __construct($basePath) {
3229
$this->initContainer();
3330
$this->initConfig();
3431
}
35-
private function initConfig(){
36-
$this->configure('core');
37-
}
3832

3933
private function initEnv(){
4034
try{
@@ -60,9 +54,15 @@ private function initEnv(){
6054

6155
}
6256

63-
public function run() {
64-
$this->route->dispatch();
57+
/**
58+
* 判断是否是cli模式
59+
*
60+
* @return bool
61+
*/
62+
public function runningInConsole() {
63+
return php_sapi_name() == 'cli';
6564
}
65+
6666
/**
6767
* 初始化容器
6868
*/
@@ -74,37 +74,13 @@ private function initContainer() {
7474
$this->instance('route',new Route($this->request));
7575
$this->bind('pinyin','\puck\helpers\PinYin');
7676
$this->bind('curl','\puck\helpers\Curl');
77+
$this->bind('dom', '\puck\helpers\Dom');
7778
}
7879

79-
/**
80-
* Get the base path for the application.
81-
*
82-
* @param string|null $path
83-
* @return string
84-
*/
85-
public function basePath($path = null)
86-
{
87-
if (isset($this->basePath)) {
88-
return $this->basePath.($path ? '/'.$path : $path);
89-
}
90-
91-
if ($this->runningInConsole()) {
92-
$this->basePath = getcwd();
93-
} else {
94-
$this->basePath = realpath(getcwd().'/../');
95-
}
96-
97-
return $this->basePath($path);
98-
}
99-
/**
100-
* 判断是否是cli模式
101-
*
102-
* @return bool
103-
*/
104-
public function runningInConsole()
105-
{
106-
return php_sapi_name() == 'cli';
80+
private function initConfig() {
81+
$this->configure('core');
10782
}
83+
10884
/**
10985
* 加载一个配置文件
11086
*
@@ -124,7 +100,6 @@ public function configure($name)
124100
}
125101
}
126102

127-
128103
/**
129104
* 获取配置文件的路径。
130105
*
@@ -154,4 +129,28 @@ public function getConfigurationPath($name = null)
154129
}
155130
}
156131
}
132+
133+
/**
134+
* Get the base path for the application.
135+
*
136+
* @param string|null $path
137+
* @return string
138+
*/
139+
public function basePath($path = null) {
140+
if (isset($this->basePath)) {
141+
return $this->basePath . ($path ? '/' . $path : $path);
142+
}
143+
144+
if ($this->runningInConsole()) {
145+
$this->basePath = getcwd();
146+
} else {
147+
$this->basePath = realpath(getcwd() . '/../');
148+
}
149+
150+
return $this->basePath($path);
151+
}
152+
153+
public function run() {
154+
$this->route->dispatch();
155+
}
157156
}

core/configs/core.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
* Created by rozbo at 2017/3/19 下午5:11
44
*/
55
return [
6-
"version"=>'1.1.3',
6+
"version" => '1.3.0',
77
'url_html_suffix'=>'html|aspx|h5|do'
88
];

core/helpers/Dom.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/**
3+
* Created by rozbo at 2017/4/17 下午6:34
4+
*/
5+
6+
namespace puck\helpers;
7+
8+
use DiDom\Document;
9+
10+
class Dom extends Document {
11+
public function __construct() {
12+
$this->init();
13+
}
14+
15+
public function init($encoding = 'UTF-8') {
16+
$this->document = new \DOMDocument('1.0', $encoding);
17+
$this->preserveWhiteSpace(false);
18+
return $this;
19+
}
20+
21+
public function release() {
22+
unset($this->document);
23+
return $this;
24+
}
25+
}

tests/puck/helpers/DomTest.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* Created by rozbo at 2017/4/17 下午6:37
4+
*/
5+
6+
namespace tests\puck\helpers;
7+
8+
use PHPUnit\Framework\TestCase;
9+
10+
class DomTest extends TestCase {
11+
/**
12+
* @var \puck\helpers\Dom;
13+
*/
14+
private $dom;
15+
16+
public function setUp() {
17+
$this->dom = app('dom');
18+
}
19+
20+
/**
21+
* @expectedException InvalidArgumentException
22+
*/
23+
public function testLoadWithInvalidArgument() {
24+
$this->dom->load([]);
25+
}
26+
27+
28+
public function loadHtmlCharsetTests() {
29+
return array(
30+
array('<html><div class="foo">English language</html>', 'English language'),
31+
array('<html><div class="foo">Русский язык</html>', 'Русский язык'),
32+
array('<html><div class="foo">اللغة العربية</html>', 'اللغة العربية'),
33+
array('<html><div class="foo">漢語</html>', '漢語'),
34+
array('<html><div class="foo">Tiếng Việt</html>', 'Tiếng Việt'),
35+
);
36+
}
37+
38+
/**
39+
* @dataProvider loadHtmlCharsetTests
40+
*/
41+
public function testLoadHtmlCharset($html, $text) {
42+
$document = $this->dom->load($html, false);
43+
$this->assertEquals($text, $document->first('div')->text());
44+
}
45+
46+
47+
public function testCreateElementBySelector() {
48+
$document = $this->dom;
49+
$element = $document->createElementBySelector('a.external-link[href=http://example.com]');
50+
$this->assertEquals('a', $element->tag);
51+
$this->assertEquals('', $element->text());
52+
$this->assertEquals(['href' => 'http://example.com', 'class' => 'external-link'], $element->attributes());
53+
$element = $document->createElementBySelector('#block', 'Foo');
54+
$this->assertEquals('div', $element->tag);
55+
$this->assertEquals('Foo', $element->text());
56+
$this->assertEquals(['id' => 'block'], $element->attributes());
57+
$element = $document->createElementBySelector('input', null, ['name' => 'name', 'placeholder' => 'Enter your name']);
58+
$this->assertEquals('input', $element->tag);
59+
$this->assertEquals('', $element->text());
60+
$this->assertEquals(['name' => 'name', 'placeholder' => 'Enter your name'], $element->attributes());
61+
}
62+
63+
public function testAppendChild() {
64+
$html = '<!DOCTYPE html>
65+
<html lang="en">
66+
<head>
67+
<meta charset="UTF-8">
68+
<title>Document</title>
69+
</head>
70+
<body>
71+
</body>
72+
</html>';
73+
$document = $this->dom;
74+
$this->assertCount(0, $document->find('span'));
75+
$node = $document->createElement('span');
76+
$appendedChild = $document->appendChild($node);
77+
$this->assertCount(1, $document->find('span'));
78+
$this->assertTrue($appendedChild->is($document->first('span')));
79+
$appendedChild->remove();
80+
$this->assertCount(0, $document->find('span'));
81+
$nodes = [];
82+
$nodes[] = $document->createElement('span');
83+
$nodes[] = $document->createElement('span');
84+
$appendedChildren = $document->appendChild($nodes);
85+
$nodes = $document->find('span');
86+
$this->assertCount(2, $appendedChildren);
87+
$this->assertCount(2, $nodes);
88+
foreach ($appendedChildren as $index => $child) {
89+
$this->assertTrue($child->is($nodes[$index]));
90+
}
91+
}
92+
93+
/**
94+
* @expectedException RuntimeException
95+
*/
96+
public function testLoadWithNotExistingFile() {
97+
$this->dom->load('path/to/file', true);
98+
}
99+
100+
101+
public function testFirst() {
102+
$html = '<ul><li>One</li><li>Two</li><li>Three</li></ul>';
103+
$document = $this->dom;
104+
$this->dom->loadHtml($html);
105+
$items = $document->find('ul > li');
106+
$this->assertEquals($items[0]->getNode(), $document->first('ul > li')->getNode());
107+
$this->assertEquals('One', $document->first('ul > li::text'));
108+
$document = $this->dom->release()->init();
109+
$this->assertNull($document->first('ul > li'));
110+
}
111+
112+
113+
public function testCount() {
114+
$html = '<ul><li>One</li><li>Two</li><li>Three</li></ul>';
115+
$this->assertEquals(3, $this->dom->loadHtml($html)->count('li'));
116+
$this->assertEquals(0, $this->dom->release()->init()->count('li'));
117+
}
118+
119+
120+
public function testHtmlWithOptions() {
121+
$html = '<html><body><span></span></body></html>';
122+
$document = $this->dom->loadHtml($html);
123+
$this->assertEquals('<html><body><span></span></body></html>', $document->html());
124+
$this->assertEquals('<html><body><span/></body></html>', $document->html(0));
125+
}
126+
127+
128+
public function testText() {
129+
$html = '<html>foo</html>';
130+
$document = $this->dom->loadHtml($html);
131+
$this->assertEquals('foo', $document->text());
132+
}
133+
}

0 commit comments

Comments
 (0)