Skip to content

Commit f36e248

Browse files
committed
Add idea for acceptance testing
1 parent 4d69c1e commit f36e248

File tree

6 files changed

+315
-1
lines changed

6 files changed

+315
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tests/*.expect
22
tests/*.result
3+
tests/.test_fs
34
build/
45
vendor/
56
phpctags

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@
1313
"autoload": {
1414
"classmap": ["PHPCtags.class.php"]
1515
},
16+
"autoload-dev": {
17+
"psr-4": {
18+
"tests\\PHPCTags\\": "tests/"
19+
}
20+
},
1621
"bin": ["phpctags"]
1722
}

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
<?php
2+
3+
namespace tests\PHPCTags\Acceptance;
4+
5+
use Exception;
6+
use PHPUnit_Framework_TestCase;
7+
use RecursiveDirectoryIterator;
8+
use RecursiveIteratorIterator;
9+
10+
abstract class AcceptanceTestCase extends PHPUnit_Framework_TestCase
11+
{
12+
const FORMAT = "<name>\t<file>\t/^<line content>$/;\"\t<short kind>\tline:<line number>\t<scope>\t<access>";
13+
14+
const KIND_TRAIT = 't';
15+
const KIND_CLASS = 'c';
16+
const KIND_METHOD = 'm';
17+
const KIND_FUNCTION = 'f';
18+
const KIND_PROPERTY = 'p';
19+
const KIND_CONSTANT = 'd';
20+
const KIND_VARIABLE = 'v';
21+
const KIND_INTERFACE = 'i';
22+
const KIND_NAMESPACE = 'n';
23+
24+
/**
25+
* @var string
26+
*/
27+
private $testDir;
28+
29+
/**
30+
* @var string
31+
*/
32+
private $tagsFileContent;
33+
34+
protected function setUp()
35+
{
36+
$this->testDir = __DIR__ . '/../.test_fs';
37+
38+
if (!file_exists($this->testDir)) {
39+
mkdir($this->testDir);
40+
}
41+
42+
$this->testDir = realpath($this->testDir);
43+
44+
$this->emptyTestDir();
45+
}
46+
47+
/**
48+
* @param string $filename
49+
* @param string $content
50+
*
51+
* @return void
52+
*/
53+
protected function givenSourceFile($filename, $content)
54+
{
55+
$filename = $this->testDir . DIRECTORY_SEPARATOR . $filename;
56+
57+
file_put_contents($filename, $content);
58+
}
59+
60+
/**
61+
* @return void
62+
*/
63+
protected function runPHPCtags()
64+
{
65+
$entryPoint = realpath(__DIR__ . '/../../bootstrap.php');
66+
67+
exec("php \"$entryPoint\" --recurse=yes -f - {$this->testDir}", $output);
68+
69+
$this->tagsFileContent = $output;
70+
}
71+
72+
/**
73+
* @return void
74+
*/
75+
protected function assertTagsFileHeaderIsCorrect()
76+
{
77+
$expectedHeader = array(
78+
"!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/",
79+
"!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/",
80+
"!_TAG_PROGRAM_AUTHOR\ttechlivezheng\t/techlivezheng@gmail.com/",
81+
"!_TAG_PROGRAM_NAME\tphpctags\t//",
82+
"!_TAG_PROGRAM_URL\thttps://github.com/techlivezheng/phpctags\t/official site/",
83+
"!_TAG_PROGRAM_VERSION\t0.5.1\t//",
84+
);
85+
86+
$realHeader = array_splice($this->tagsFileContent, 0, count($expectedHeader));
87+
88+
$this->assertEquals($expectedHeader, $realHeader, 'Tags file header is incorrect');
89+
}
90+
91+
/**
92+
* @return void
93+
*/
94+
protected function assertNumberOfTagsInTagsFileIs($count)
95+
{
96+
$this->assertCount(
97+
$count,
98+
$this->tagsFileContent,
99+
'Tags file contains the wrong number of tags'
100+
);
101+
}
102+
103+
/**
104+
* @param string $filename
105+
* @param string $name
106+
* @param string $kind
107+
* @param int $line
108+
* @param string $scope
109+
* @param string $access
110+
*
111+
* @return void
112+
*/
113+
protected function assertTagsFileContainsTag(
114+
$filename,
115+
$name,
116+
$kind,
117+
$line,
118+
$scope = '',
119+
$access = ''
120+
) {
121+
$this->assertContains(
122+
$this->createTagLine($filename, $name, $kind, $line, $scope, $access),
123+
$this->tagsFileContent,
124+
"Tag file content:\n" . print_r($this->tagsFileContent, true)
125+
);
126+
}
127+
128+
/**
129+
* @return void
130+
*/
131+
private function emptyTestDir()
132+
{
133+
if (empty($this->testDir)) {
134+
throw \RuntimeException('Test directory does not exist');
135+
}
136+
137+
$files = new RecursiveIteratorIterator(
138+
new RecursiveDirectoryIterator(
139+
$this->testDir,
140+
RecursiveDirectoryIterator::SKIP_DOTS
141+
),
142+
RecursiveIteratorIterator::CHILD_FIRST
143+
);
144+
145+
foreach ($files as $fileinfo) {
146+
if ($fileinfo->isDir()) {
147+
rmdir($fileinfo->getRealPath());
148+
} else {
149+
unlink($fileinfo->getRealPath());
150+
}
151+
}
152+
}
153+
154+
/**
155+
* @param string $filename
156+
* @param string $name
157+
* @param string $kind
158+
* @param int $line
159+
* @param string $scope
160+
* @param string $access
161+
*
162+
* @return string
163+
*/
164+
private function createTagLine($filename, $name, $kind, $line, $scope, $access)
165+
{
166+
$kinds = array(
167+
self::KIND_TRAIT => 'trait',
168+
self::KIND_CLASS => 'class',
169+
self::KIND_METHOD => 'method',
170+
self::KIND_FUNCTION => 'function',
171+
self::KIND_PROPERTY => 'property',
172+
self::KIND_CONSTANT => 'constant',
173+
self::KIND_VARIABLE => 'variable',
174+
self::KIND_INTERFACE => 'interface',
175+
self::KIND_NAMESPACE => 'namespace',
176+
);
177+
178+
if(!empty($define['access'])) {
179+
$access = 'access:' . $access;
180+
}
181+
182+
$patterns = array(
183+
'/<name>/',
184+
'/<file>/',
185+
'/<line content>/',
186+
'/<short kind>/',
187+
'/<full kind>/',
188+
'/<line number>/',
189+
'/<scope>/',
190+
'/<access>/'
191+
);
192+
193+
$replacements = array(
194+
$name,
195+
$this->testDir . DIRECTORY_SEPARATOR . $filename,
196+
$this->getSourceFileLineContent($filename, $line),
197+
$kind,
198+
$kinds[$kind],
199+
$line,
200+
$scope,
201+
$access
202+
);
203+
204+
$line = preg_replace($patterns, $replacements, self::FORMAT);
205+
206+
return rtrim($line, "\t");
207+
}
208+
209+
/**
210+
* @param string $filename
211+
* @param int $line
212+
*
213+
* @return string
214+
*/
215+
private function getSourceFileLineContent($filename, $line)
216+
{
217+
$filename = $this->testDir . DIRECTORY_SEPARATOR . $filename;
218+
$line--;
219+
220+
return rtrim(file($filename)[$line], PHP_EOL);
221+
}
222+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace tests\PHPCTags\Acceptance;
4+
5+
final class BasicTagKindsTest extends AcceptanceTestCase
6+
{
7+
public function testItCreatesTagFileForSingleVariable()
8+
{
9+
$this->givenSourceFile('SingleVarExample.php', <<<'EOS'
10+
<?php
11+
12+
$var = 'test value';
13+
EOS
14+
);
15+
16+
$this->runPHPCtags();
17+
18+
$this->assertTagsFileHeaderIsCorrect();
19+
$this->assertNumberOfTagsInTagsFileIs(1);
20+
$this->assertTagsFileContainsTag(
21+
'SingleVarExample.php',
22+
'var',
23+
self::KIND_VARIABLE,
24+
3
25+
);
26+
}
27+
28+
public function testItCreatesTagFileForSingleClass()
29+
{
30+
$this->givenSourceFile('SingleClassExample.php', <<<'EOS'
31+
<?php
32+
33+
class TestClass
34+
{
35+
}
36+
EOS
37+
);
38+
39+
$this->runPHPCtags();
40+
41+
$this->assertTagsFileHeaderIsCorrect();
42+
$this->assertNumberOfTagsInTagsFileIs(1);
43+
$this->assertTagsFileContainsTag(
44+
'SingleClassExample.php',
45+
'TestClass',
46+
self::KIND_CLASS,
47+
3
48+
);
49+
}
50+
}

tests/Acceptance/NamespaceTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace tests\PHPCTags\Acceptance;
4+
5+
final class NamespaceTest extends AcceptanceTestCase
6+
{
7+
public function testItAddsTagForNamespacedVariable()
8+
{
9+
$this->givenSourceFile('NamespacedVariableExample.php', <<<'EOS'
10+
<?php
11+
12+
namespace TestNamespace;
13+
14+
$var = 'test value';
15+
EOS
16+
);
17+
18+
$this->runPHPCtags();
19+
20+
$this->assertTagsFileHeaderIsCorrect();
21+
$this->assertNumberOfTagsInTagsFileIs(2);
22+
$this->assertTagsFileContainsTag(
23+
'NamespacedVariableExample.php',
24+
'TestNamespace',
25+
self::KIND_NAMESPACE,
26+
3
27+
);
28+
$this->assertTagsFileContainsTag(
29+
'NamespacedVariableExample.php',
30+
'var',
31+
self::KIND_VARIABLE,
32+
5,
33+
'namespace:TestNamespace'
34+
);
35+
}
36+
}

0 commit comments

Comments
 (0)