Skip to content

Commit

Permalink
Merge pull request #8 from bookdown/reschema
Browse files Browse the repository at this point in the history
Use an array instead of an object for `"content"`. Fixes #5
  • Loading branch information
Paul M. Jones committed Mar 5, 2015
2 parents 92b11b8 + 694f167 commit 1af3d55
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 75 deletions.
53 changes: 46 additions & 7 deletions src/Config/IndexConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,62 @@ protected function initTitle()

protected function initContent()
{
$this->content = empty($this->json->content)
$content = empty($this->json->content)
? array()
: (array) $this->json->content;
: $this->json->content;

if (! $this->content) {
if (! $content) {
throw new Exception("No content listed in '{$this->file}'.");
}

if (isset($this->content['index'])) {
throw new Exception("Disallowed 'index' content in {$this->file}.");
if (! is_array($content)) {
throw new Exception("Content must be an array in '{$this->file}'.");
}

foreach ($this->content as $name => $origin) {
$this->content[$name] = $this->fixPath($origin);
foreach ($content as $key => $val) {
$this->initContentItem($val);
}
}

protected function initContentItem($origin)
{
if (is_object($origin)) {
$spec = (array) $origin;
$name = key($spec);
$origin = current($spec);
return $this->addContent($name, $origin);
}

if (! is_string($origin)) {
throw new Exception("Content origin must be object or string in '{$this->file}'.");
}

if (substr($origin, -13) == 'bookdown.json') {
$name = basename(dirname($origin));
return $this->addContent($name, $origin);
}

$name = basename($origin);
$pos = strrpos($name, '.');
if ($pos !== false) {
$name = substr($name, 0, $pos);
}
return $this->addContent($name, $origin);
}

protected function addContent($name, $origin)
{
if ($name == 'index') {
throw new Exception("Disallowed 'index' content name in '{$this->file}'.");
}

if (isset($this->content[$name])) {
throw new Exception("Content name '{$name}' already set in '{$this->file}'.");
}

$this->content[$name] = $this->fixPath($origin);
}

protected function fixPath($path)
{
if (strpos($path, '://') !== false) {
Expand Down
12 changes: 6 additions & 6 deletions tests/BookFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class BookFixture
public $rootConfigFile = '/path/to/bookdown.json';
public $rootConfigData = '{
"title": "Example Book",
"content": {
"chapter": "chapter/bookdown.json"
},
"content": [
{"chapter": "chapter/bookdown.json"}
],
"target": "/_site",
"templates": {
"foo": "/foo.php"
Expand All @@ -24,9 +24,9 @@ class BookFixture
public $indexConfigFile = '/path/to/chapter/bookdown.json';
public $indexConfigData = '{
"title": "Chapter",
"content": {
"section": "section.md"
}
"content": [
{"section": "section.md"}
]
}';
public $indexConfig;
public $indexPage;
Expand Down
10 changes: 5 additions & 5 deletions tests/Config/ConfigFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ class ConfigFactoryTest extends \PHPUnit_Framework_TestCase

protected $data = '{
"title": "Example Title",
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
},
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
],
"target": "/_site"
}';

Expand Down
137 changes: 108 additions & 29 deletions tests/Config/IndexConfigTest.php
Original file line number Diff line number Diff line change
@@ -1,48 +1,78 @@
<?php
namespace Bookdown\Bookdown\Config;

class ConfigTest extends \PHPUnit_Framework_TestCase
class IndexConfigTest extends \PHPUnit_Framework_TestCase
{
protected $config;

protected $validLocalJson = '{
protected $jsonValidLocal = '{
"title": "Example Title",
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
}
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
]
}';

protected $validRemoteJson = '{
protected $jsonValidRemote = '{
"title": "Example Title",
"content": {
"zim": "zim.md",
"dib": "dib.md",
"gir": "http://example.com/gir.md"
}
"content": [
{"zim": "zim.md"},
{"dib": "dib.md"},
{"gir": "http://example.com/gir.md"}
]
}';

protected $malformedJson = '{';

protected $jsonMissingTitle = '{
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
}
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
]
}';

protected $jsonMissingContent = '{
"title": "Example Title",
"content" : {}
"content": []
}';

protected $jsonContentIndex = '{
"title": "Example Title",
"content" : {
"index": "index.md"
}
"content": [
{"index": "index.md"}
]
}';

protected $jsonContentNotArray = '{
"title": "Example Title",
"content": "not an array"
}';

protected $jsonContentItemNotStringOrObject = '{
"title": "Example Title",
"content": [
["neither string", "nor object"]
]
}';

protected $jsonContentConvenience = '{
"title": "Example Title",
"content": [
"foo.md",
"bar/bookdown.json",
"http://example.com/baz.md",
"http://example.dom/dib/bookdown.json"
]
}';

protected $jsonReusedContentName = '{
"title": "Example Title",
"content": [
"foo.md",
"foo/bookdown.json"
]
}';

protected function newIndexConfig($file, $data)
Expand Down Expand Up @@ -77,18 +107,36 @@ public function testMissingContent()
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->jsonMissingContent);
}

public function testContentNotArray()
{
$this->setExpectedException(
'Bookdown\Bookdown\Exception',
"Content must be an array in '/path/to/bookdown.json'."
);
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->jsonContentNotArray);
}

public function testContentItemNotStringOrObject()
{
$this->setExpectedException(
'Bookdown\Bookdown\Exception',
"Content origin must be object or string in '/path/to/bookdown.json'."
);
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->jsonContentItemNotStringOrObject);
}

public function testContentIndex()
{
$this->setExpectedException(
'Bookdown\Bookdown\Exception',
"Disallowed 'index' content in /path/to/bookdown.json."
"Disallowed 'index' content name in '/path/to/bookdown.json'."
);
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->jsonContentIndex);
}

public function testValidLocalJson()
public function testValidLocal()
{
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->validLocalJson);
$config = $this->newIndexConfig('/path/to/bookdown.json', $this->jsonValidLocal);

$this->assertSame('/path/to/bookdown.json', $config->getFile());
$this->assertSame('/path/to/', $config->getDir());
Expand All @@ -101,11 +149,11 @@ public function testValidLocalJson()
$this->assertSame($expect, $config->getContent());
}

public function testValidRemoteJson()
public function testValidRemote()
{
$config = $this->newIndexConfig(
'http://example.net/path/to/bookdown.json',
$this->validRemoteJson
$this->jsonValidRemote
);

$this->assertSame('http://example.net/path/to/bookdown.json', $config->getFile());
Expand All @@ -118,15 +166,46 @@ public function testValidRemoteJson()
$this->assertSame($expect, $config->getContent());
}

public function testInvalidRemoteJson()
public function testContentConvenience()
{
$config = $this->newIndexConfig(
'/path/to/bookdown.json',
$this->jsonContentConvenience
);

$this->assertSame('/path/to/bookdown.json', $config->getFile());

$expect = array(
'foo' => '/path/to/foo.md',
'bar' => '/path/to/bar/bookdown.json',
'baz' => 'http://example.com/baz.md',
'dib' => 'http://example.dom/dib/bookdown.json',
);

$this->assertSame($expect, $config->getContent());
}

public function testReusedContentName()
{
$this->setExpectedException(
'Bookdown\Bookdown\Exception',
"Content name 'foo' already set in '/path/to/bookdown.json'."
);
$config = $this->newIndexConfig(
'/path/to/bookdown.json',
$this->jsonReusedContentName
);
}

public function testInvalidRemote()
{
$this->setExpectedException(
'Bookdown\Bookdown\Exception',
"Cannot handle absolute content path '/bar.md' in remote 'http://example.net/path/to/bookdown.json'."
);
$config = $this->newIndexConfig(
'http://example.net/path/to/bookdown.json',
$this->validLocalJson
$this->jsonValidLocal
);
}
}
30 changes: 15 additions & 15 deletions tests/Config/RootConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ class RootConfigTest extends \PHPUnit_Framework_TestCase

protected $maxRootJson = '{
"title": "Example Title",
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
},
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
],
"target": "my/target",
"template": "../templates/master.php",
"conversionProcess": "My\\\\Conversion\\\\Builder",
Expand All @@ -23,21 +23,21 @@ class RootConfigTest extends \PHPUnit_Framework_TestCase

protected $minRootJson = '{
"title": "Example Title",
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
},
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
],
"target": "_site"
}';

protected $missingTargetJson = '{
"title": "Example Title",
"content": {
"foo": "foo.md",
"bar": "/bar.md",
"baz": "http://example.com/baz.md"
}
"content": [
{"foo": "foo.md"},
{"bar": "/bar.md"},
{"baz": "http://example.com/baz.md"}
]
}';

protected function newRootConfig($file, $data)
Expand Down
14 changes: 7 additions & 7 deletions tests/Service/ProcessorBuilderTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
namespace Bookdown\Bookdown;
namespace Bookdown\Bookdown\Service;

use Bookdown\Bookdown\BookFixture;
use Bookdown\Bookdown\Config\RootConfig;
Expand All @@ -20,9 +20,9 @@ public function testNewProcessor()
{
$rootConfig = new RootConfig('/path/to/bookdown.json', '{
"title": "Example Book",
"content": {
"foo": "foo.md"
},
"content": [
{"foo": "foo.md"}
],
"target": "_site/"
}');

Expand All @@ -36,9 +36,9 @@ public function testNewProcessUnimplementedContainer()
{
$rootConfig = new RootConfig('/path/to/bookdown.json', '{
"title": "Example Book",
"content": {
"foo": "foo.md"
},
"content": [
{"foo": "foo.md"}
],
"target": "_site/",
"tocProcess": "Bookdown\\\\Bookdown\\\\Process\\\\Fake\\\\FakeProcessUnimplementedBuilder"
}');
Expand Down
Loading

0 comments on commit 1af3d55

Please sign in to comment.