Skip to content

Commit d038663

Browse files
committed
TDD core class
1 parent 3b36efb commit d038663

File tree

3 files changed

+240
-6
lines changed

3 files changed

+240
-6
lines changed

blueprint.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
require 'vendor/autoload.php';
44

5-
use Blueprint\Lexers\Lexer;
6-
use Blueprint\Parsers\Parser;
7-
use Blueprint\Generators\Generator;
5+
use Blueprint\Blueprint;
86

97
$contents = file_get_contents('sample.yaml');
108

11-
$tokens = Parser::parse($contents);
12-
$registry = Lexer::analyze($tokens);
13-
Generator::generate($registry);
9+
$blueprint = new Blueprint();
10+
// $blueprint->registerLexer(new Lexer());
11+
12+
$tokens = $blueprint->parse($contents);
13+
$registry = $blueprint->analyze($tokens);
14+
$blueprint->generate($tokens);
1415

src/Blueprint.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Blueprint;
4+
5+
6+
use Symfony\Component\Yaml\Yaml;
7+
8+
class Blueprint
9+
{
10+
private $lexers = [];
11+
private $generators = [];
12+
13+
public function parse($content)
14+
{
15+
$content = preg_replace('/^(\s+)(id|timestamps)$/m', '$1$2: $2', $content);
16+
17+
return Yaml::parse($content);
18+
}
19+
20+
public function analyze(array $tokens)
21+
{
22+
$registry = [
23+
'models' => [],
24+
'controllers' => []
25+
];
26+
27+
foreach ($this->lexers as $lexer) {
28+
$registry = array_merge($registry, $lexer->analyze($tokens));
29+
}
30+
31+
return $registry;
32+
}
33+
34+
public function generate(array $tree)
35+
{
36+
foreach ($this->generators as $generator) {
37+
$generator::generate($tree);
38+
}
39+
}
40+
41+
public function registerLexer($lexer)
42+
{
43+
$this->lexers[] = $lexer;
44+
}
45+
46+
public function registerGenerator($generator)
47+
{
48+
$this->generators[] = $generator;
49+
}
50+
}

tests/Feature/BlueprintTest.php

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
3+
namespace Tests\Feature;
4+
5+
use Blueprint\Blueprint;
6+
use Symfony\Component\Yaml\Exception\ParseException;
7+
use Tests\TestCase;
8+
9+
class BlueprintTest extends TestCase
10+
{
11+
/**
12+
* @var Blueprint
13+
*/
14+
private $subject;
15+
16+
protected function setUp()
17+
{
18+
parent::setUp();
19+
20+
$this->subject = new Blueprint();
21+
}
22+
23+
/**
24+
* @test
25+
*/
26+
public function it_parses_models()
27+
{
28+
$blueprint = $this->fixture('definitions/models-only.bp');
29+
30+
$this->assertEquals([
31+
'models' => [
32+
'ModelOne' => [
33+
'column' => 'datatype modifier',
34+
],
35+
'ModelTwo' => [
36+
'column' => 'datatype',
37+
'another_column' => 'datatype modifier',
38+
],
39+
],
40+
], $this->subject->parse($blueprint));
41+
}
42+
43+
/**
44+
* @test
45+
*/
46+
public function it_parses_controllers()
47+
{
48+
$blueprint = $this->fixture('definitions/controllers-only.bp');
49+
50+
$this->assertEquals([
51+
'controllers' => [
52+
'UserController' => [
53+
'index' => [
54+
'action' => 'detail'
55+
],
56+
'create' => [
57+
'action' => 'additional detail'
58+
],
59+
],
60+
'RoleController' => [
61+
'index' => [
62+
'action' => 'detail',
63+
'another_action' => 'so much detail',
64+
],
65+
],
66+
],
67+
], $this->subject->parse($blueprint));
68+
}
69+
70+
/**
71+
* @test
72+
*/
73+
public function it_parses_shorthands()
74+
{
75+
$blueprint = $this->fixture('definitions/shorthands.bp');
76+
77+
$this->assertEquals([
78+
'models' => [
79+
'Name' => [
80+
'id' => 'id',
81+
'timestamps' => 'timestamps',
82+
],
83+
],
84+
], $this->subject->parse($blueprint));
85+
}
86+
87+
/**
88+
* @test
89+
*/
90+
public function it_parses_the_readme_example()
91+
{
92+
$blueprint = $this->fixture('definitions/readme-example.bp');
93+
94+
$this->assertEquals([
95+
'models' => [
96+
'Post' => [
97+
'id' => 'id',
98+
'title' => 'string',
99+
'content' => 'bigtext',
100+
'published_at' => 'nullable timestamp',
101+
'timestamps' => 'timestamps'
102+
],
103+
],
104+
'controllers' => [
105+
'Post' => [
106+
'index' => [
107+
'query' => 'all posts',
108+
'render' => 'post.index with posts',
109+
],
110+
'store' => [
111+
'validate' => 'title, content',
112+
'save' => 'post',
113+
'send' => 'ReviewNotifcation to post.author',
114+
'queue' => 'SyncMedia',
115+
'flash' => 'post.title',
116+
'redirect' => 'post.index',
117+
],
118+
],
119+
],
120+
], $this->subject->parse($blueprint));
121+
}
122+
123+
/**
124+
* @test
125+
*/
126+
public function it_throws_a_custom_error_when_parsing_fails()
127+
{
128+
$this->expectException(ParseException::class);
129+
130+
$blueprint = $this->fixture('definitions/invalid.bp');
131+
132+
$this->subject->parse($blueprint);
133+
}
134+
135+
/**
136+
* @test
137+
*/
138+
public function analyze_return_default_tree_for_empty_tokens()
139+
{
140+
$tokens = [];
141+
142+
$this->assertEquals([
143+
'models' => [],
144+
'controllers' => []
145+
],
146+
$this->subject->analyze($tokens));
147+
}
148+
149+
/**
150+
* @test
151+
*/
152+
public function analyze_uses_register_lexers_to_analyze_tokens()
153+
{
154+
$lexer = \Mockery::mock();
155+
$tokens = ['tokens' => ['are', 'here']];
156+
$lexer->expects('analyze')
157+
->with($tokens)
158+
->andReturn(['mock' => 'lexer']);
159+
160+
$this->subject->registerLexer($lexer);
161+
162+
$this->assertEquals([
163+
'models' => [],
164+
'controllers' => [],
165+
'mock' => 'lexer'
166+
], $this->subject->analyze($tokens));
167+
}
168+
169+
/**
170+
* @test
171+
*/
172+
public function generate_uses_register_generators_to_generate_code()
173+
{
174+
$generator = \Mockery::mock();
175+
$tree = ['branch' => ['code', 'attributes']];
176+
$generator->expects('generate')
177+
->with($tree);
178+
179+
$this->subject->registerGenerator($generator);
180+
181+
$this->subject->generate($tree);
182+
}
183+
}

0 commit comments

Comments
 (0)