Skip to content

Commit bc25fc0

Browse files
committed
Merge pull request #79 from phpcr/cnd-parser
[WIP] Cnd parser test
2 parents 5ce38c9 + 23a1981 commit bc25fc0

File tree

6 files changed

+911
-0
lines changed

6 files changed

+911
-0
lines changed

tests/PhpcrUtils/CndParserTest.php

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
<?php
2+
3+
namespace PHPCR\Tests\PhpcrUtils;
4+
5+
require_once(__DIR__ . '/../../inc/BaseCase.php');
6+
7+
use PHPCR\NodeType\NodeTypeDefinitionInterface;
8+
use PHPCR\NodeType\NodeTypeManagerInterface;
9+
use PHPCR\PropertyType;
10+
use PHPCR\NodeType\PropertyDefinitionTemplateInterface;
11+
use PHPCR\Version\OnParentVersionAction;
12+
13+
use PHPCR\Util\CND\Parser\CndParser;
14+
15+
16+
class CndParserTest extends \PHPCR\Test\BaseCase
17+
{
18+
/** @var CndParser */
19+
private $cndParser;
20+
21+
public function setUp()
22+
{
23+
parent::setUp();
24+
$this->cndParser = new CndParser($this->sharedFixture['session']->getWorkspace()->getNodeTypeManager());
25+
}
26+
27+
public function testParseNormal()
28+
{
29+
$res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.cnd');
30+
$this->assertExampleCnd($res);
31+
}
32+
33+
public function testParseCompact()
34+
{
35+
$res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.compact.cnd');
36+
$this->assertExampleCnd($res);
37+
38+
}
39+
40+
public function testParseVerbose()
41+
{
42+
$res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.verbose.cnd');
43+
$this->assertExampleCnd($res);
44+
}
45+
46+
47+
public function testParseString()
48+
{
49+
// the "worst case" example from http://jackrabbit.apache.org/node-type-notation.html
50+
$cnd = <<<EOT
51+
/** An example node type definition */
52+
<ns ='http://namespace.com/ns'>
53+
[ns:NodeType] > ns:ParentType1, ns:ParentType2
54+
orderable mixin
55+
- ex:property (STRING)
56+
= 'default1' , 'default2'
57+
mandatory autocreated protected multiple
58+
VERSION
59+
< 'constraint1', 'constraint2'
60+
+ ns:node (ns:reqType1, ns:reqType2)
61+
= ns:defaultType
62+
mandatory autocreated protected VERSION
63+
EOT;
64+
65+
66+
$res = $this->cndParser->parseString($cnd);
67+
$this->assertExampleCnd($res);
68+
}
69+
70+
/**
71+
* @expectedException \PHPCR\Util\CND\Exception\ParserException
72+
*/
73+
public function testParseError()
74+
{
75+
$cnd = <<<EOT
76+
/** An example node type definition */
77+
<ns ='http://namespace.com/ns'>
78+
[ns:NodeType] > ns:ParentType1, ns:ParentType2
79+
orderable mixin
80+
- ex:property (STRING)
81+
= 'default1' , 'default2'
82+
mandatory invalid-string protected multiple
83+
VERSION
84+
< 'constraint1', 'constraint2'
85+
+ ns:node (ns:reqType1, ns:reqType2)
86+
= ns:defaultType
87+
mandatory autocreated protected VERSION
88+
EOT;
89+
90+
$this->cndParser->parseString($cnd);
91+
}
92+
93+
/**
94+
* @expectedException \InvalidArgumentException
95+
*/
96+
public function testErrorNoFile()
97+
{
98+
$this->cndParser->parseFile('/not/found');
99+
}
100+
101+
/**
102+
* @expectedException \PHPCR\Util\CND\Exception\ScannerException
103+
*/
104+
public function testScannerErrorComment()
105+
{
106+
$cnd = <<<EOT
107+
la /*
108+
EOT;
109+
110+
$this->cndParser->parseString($cnd);
111+
}
112+
113+
/**
114+
* @expectedException \PHPCR\Util\CND\Exception\ScannerException
115+
*/
116+
public function testScannerErrorNewline()
117+
{
118+
$cnd = <<<EOT
119+
/** An example node type definition */
120+
<ns ='http://namespace.com/ns
121+
'>
122+
[ns:NodeType] > ns:ParentType1, ns:ParentType2
123+
orderable mixin
124+
- ex:property (STRING)
125+
EOT;
126+
127+
$this->cndParser->parseString($cnd);
128+
}
129+
130+
/**
131+
* Test the case where the parser did not parse correctly
132+
* the default values at the end of the parsed file.
133+
*
134+
* Assert no exception is thrown
135+
*/
136+
public function testNoStopAtEofError()
137+
{
138+
$res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/no-stop-at-eof.cnd');
139+
140+
$this->assertTrue(isset($res['namespaces']));
141+
$this->assertEquals(array('phpcr' => 'http://www.doctrine-project.org/projects/phpcr_odm'), $res['namespaces']);
142+
143+
$this->assertTrue(isset($res['nodeTypes']));
144+
}
145+
146+
public function testBigFile()
147+
{
148+
//var_dump($this->sharedFixture['session']->getWorkspace()->getNodeTypeManager()->getNodeType('nt:file')->hasOrderableChildNodes());die;
149+
$res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/jackrabbit_nodetypes.cnd');
150+
151+
// some random sanity checks
152+
$this->assertTrue(isset($res['nodeTypes']));
153+
154+
$def = $res['nodeTypes'];
155+
$this->assertTrue(isset($def['nt:file']));
156+
/** @var $parsed NodeTypeDefinitionInterface */
157+
$parsed = $def['nt:file'];
158+
$this->assertEquals('nt:file', $parsed->getName());
159+
$this->assertFalse($parsed->isAbstract());
160+
$this->assertFalse($parsed->hasOrderableChildNodes());
161+
$this->assertFalse($parsed->isMixin());
162+
// queryable default is implementation specific
163+
}
164+
165+
/**
166+
* Check if $res matches the expected node type definition from the
167+
* "worst case" example.
168+
*
169+
* @param array $res namespaces and node types
170+
*/
171+
protected function assertExampleCnd($res)
172+
{
173+
$this->assertTrue(isset($res['namespaces']));
174+
$this->assertEquals(array('ns' => 'http://namespace.com/ns'), $res['namespaces']);
175+
176+
$this->assertTrue(isset($res['nodeTypes']));
177+
// get first node type
178+
reset($res['nodeTypes']);
179+
/** @var $def NodeTypeDefinitionInterface */
180+
list($name, $def) = each($res['nodeTypes']);
181+
182+
$this->assertEquals('ns:NodeType', $name);
183+
$this->assertInstanceOf('\PHPCR\NodeType\NodeTypeTemplateInterface', $def);
184+
$this->assertEquals('ns:NodeType', $def->getName());
185+
$this->assertEquals(array('ns:ParentType1', 'ns:ParentType2'), $def->getDeclaredSuperTypeNames());
186+
$this->assertTrue($def->hasOrderableChildNodes());
187+
$this->assertTrue($def->isMixin());
188+
// queryable default is implementation specific
189+
$this->assertFalse($def->isAbstract());
190+
$this->assertEquals(1, count($def->getPropertyDefinitionTemplates()));
191+
192+
/** @var $prop PropertyDefinitionTemplateInterface */
193+
$prop = $def->getPropertyDefinitionTemplates()->getIterator()->current();
194+
195+
$this->assertEquals('ex:property', $prop->getName());
196+
$this->assertEquals(PropertyType::STRING, $prop->getRequiredType());
197+
$this->assertEquals(array('default1', 'default2'), $prop->getDefaultValues());
198+
$this->assertEquals(array('constraint1', 'constraint2'), $prop->getValueConstraints());
199+
$this->assertTrue($prop->isAutoCreated());
200+
$this->assertTrue($prop->isMandatory());
201+
$this->assertTrue($prop->isProtected());
202+
$this->assertTrue($prop->isMultiple());
203+
$this->assertEquals(OnParentVersionAction::VERSION, $prop->getOnParentVersion());
204+
$this->assertEquals(array(), $prop->getAvailableQueryOperators());
205+
$this->assertTrue($prop->isFullTextSearchable()); // True because there was no "nofulltext" attribute
206+
$this->assertTrue($prop->isQueryOrderable()); // True because there was no "noqueryorder" attribute
207+
}
208+
209+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* An example node type definition */
2+
<ns ='http://namespace.com/ns'>
3+
[ns:NodeType] > ns:ParentType1, ns:ParentType2
4+
orderable mixin
5+
- ex:property (STRING)
6+
= 'default1' , 'default2'
7+
mandatory autocreated protected multiple
8+
VERSION
9+
< 'constraint1', 'constraint2'
10+
+ ns:node (ns:reqType1, ns:reqType2)
11+
= ns:defaultType
12+
mandatory autocreated protected VERSION
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<ns= 'http://namespace.com/ns'>
2+
[ns:NodeType]>ns:ParentType1, ns:ParentType2 o m
3+
-ex:property(STRING)='default1','default2' m a p * VERSION
4+
<'constraint1', 'constraint2'
5+
+ns:node(ns:reqType1,ns:reqType2)=ns:defaultType
6+
m a p VERSION
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* An example node type definition */
2+
3+
// The namespace declaration
4+
<ns = 'http://namespace.com/ns'>
5+
6+
// Node type name
7+
[ns:NodeType]
8+
9+
// Supertypes
10+
> ns:ParentType1, ns:ParentType2
11+
12+
// This node type supports orderable child nodes
13+
orderable
14+
15+
// This is a mixin node type
16+
mixin
17+
18+
// Nodes of this node type have a property called 'ex:property' of type STRING
19+
- ex:property (STRING)
20+
21+
// The default values for this
22+
// (multi-value) property are...
23+
= 'default1', 'default2'
24+
25+
// and it is...
26+
mandatory autocreated protected
27+
28+
// and multi-valued
29+
multiple
30+
31+
// and has an on-parent-version setting of ...
32+
VERSION
33+
34+
// The constraint settings are...
35+
< 'constraint1', 'constraint2'
36+
37+
// Nodes of this node type have a child node called ns:node which must be of
38+
// at least the node types ns:reqType1 and ns:reqType2
39+
+ ns:node (ns:reqType1, ns:reqType2)
40+
41+
// and the default primary node type of the child node is...
42+
= ns:defaultType
43+
44+
// This child node is...
45+
mandatory autocreated protected
46+
47+
// and has an on-parent-version setting of ...
48+
VERSION

0 commit comments

Comments
 (0)