bookery 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -8
- data/.travis.yml +5 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +26 -11
- data/Rakefile +2 -1
- data/bookery.gemspec +18 -14
- data/docs/config.md +61 -0
- data/docs/contributing.md +47 -0
- data/docs/editing.md +82 -0
- data/docs/project.md +77 -0
- data/lib/bookery.rb +27 -4
- data/lib/bookery/book.rb +13 -15
- data/lib/bookery/cli.rb +29 -12
- data/lib/bookery/config.rb +42 -0
- data/lib/bookery/factories/chapter_factory.rb +35 -0
- data/lib/bookery/factories/publisher_factory.rb +13 -0
- data/lib/bookery/processors/include_processor.rb +17 -0
- data/lib/bookery/project.rb +75 -0
- data/lib/bookery/publishers/html_publisher.rb +68 -0
- data/lib/bookery/version.rb +1 -1
- data/{bin → libexec}/bookery +1 -4
- data/templates/basic/Gemfile.tt +2 -0
- data/templates/basic/assets/css/base.css +7 -0
- data/templates/basic/assets/css/layout.css +23 -0
- data/templates/basic/assets/css/modules/code-block.css +132 -0
- data/templates/{book/assets → basic/assets/includes}/.empty_directory +0 -0
- data/templates/basic/assets/style.css +3 -0
- data/templates/basic/assets/templates/template.html.erb +30 -0
- data/templates/basic/book/en/001-first-chapter/01-chapter-file.md +9 -0
- data/templates/basic/config.yml +14 -0
- data/test/bookery/book_test.rb +32 -9
- data/test/bookery/cli_test.rb +25 -14
- data/test/bookery/config_test.rb +26 -0
- data/test/bookery/factories/chapter_factory_test.rb +24 -0
- data/test/bookery/factories/publisher_factory_test.rb +16 -0
- data/test/bookery/processor/include_processor_test.rb +38 -0
- data/test/bookery/project_test.rb +37 -0
- data/test/bookery/publishers/html_publisher_test.rb +78 -0
- data/test/data/project/Gemfile.tt +2 -0
- data/{templates/book/book/.empty_directory → test/data/project/assets/images/cover.png} +0 -0
- data/test/data/project/assets/includes/ruby/chapter2.rb +3 -0
- data/test/data/project/assets/style.css +1 -0
- data/test/data/project/assets/templates/template.html.erb +15 -0
- data/test/data/project/book/en/001-first-chapter/01-chapter-file.md +9 -0
- data/test/data/project/book/en/002-second-chapter/01-chapter-file.md +7 -0
- data/test/data/project/book/en/002-second-chapter/02-second-chapter-file.md +1 -0
- data/{templates/book/book/en/.empty_directory → test/data/project/book/es/.git-keep} +0 -0
- data/test/data/project/config.yml +19 -0
- data/test/test_helper.rb +3 -46
- metadata +107 -79
- data/Gemfile.lock +0 -64
- data/Guardfile +0 -9
- data/lib/bookery/chapter.rb +0 -30
- data/templates/book/Gemfile +0 -2
- data/templates/book/README.md +0 -3
- data/templates/book/config.yml +0 -5
- data/templates/sample/Gemfile +0 -2
- data/templates/sample/README.md +0 -3
- data/templates/sample/book/en/01-introduction/01-intro-to-book.md +0 -0
- data/templates/sample/book/en/02-second-chapter/01-first-things-first.md +0 -1
- data/templates/sample/book/en/02-second-chapter/02-before_intro.md +0 -1
- data/templates/sample/config.yml +0 -5
- data/test/bookery/chapter_test.rb +0 -21
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="<%= language %>">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
|
+
<title><%= title %> by <%= authors %></title>
|
7
|
+
<meta name="author" content="<%= authors %>">
|
8
|
+
<meta name="description" content="<%= title %>">
|
9
|
+
<meta name="generator" content="bookery">
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
11
|
+
<link rel="stylesheet" type="text/css" href="assets/style.css">
|
12
|
+
</head>
|
13
|
+
<body>
|
14
|
+
<header>
|
15
|
+
<div class="container">
|
16
|
+
<h1><%= title %></h1>
|
17
|
+
</div>
|
18
|
+
</header>
|
19
|
+
|
20
|
+
<section class="container">
|
21
|
+
<%= body %>
|
22
|
+
</section>
|
23
|
+
|
24
|
+
<footer>
|
25
|
+
<div class="container">
|
26
|
+
Copyright © <%= Time.now.year %> <%= authors %>
|
27
|
+
</div>
|
28
|
+
</footer>
|
29
|
+
</body>
|
30
|
+
</html>
|
data/test/bookery/book_test.rb
CHANGED
@@ -1,19 +1,42 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class BookTest <
|
3
|
+
class BookTest < Minitest::Test
|
4
4
|
def setup
|
5
|
-
|
6
|
-
|
5
|
+
config = Bookery::Config.new('en', {
|
6
|
+
title: 'My Title',
|
7
|
+
authors: ['David Muto', 'Jesus Christ'],
|
8
|
+
editors: ['Kevin Centeno', 'Kevin Ackland'],
|
9
|
+
language: 'en'
|
10
|
+
})
|
11
|
+
|
12
|
+
book_dir = 'test/data/project/book/en'
|
13
|
+
chapters = Bookery::Factories::ChapterFactory.create_chapters(book_dir)
|
14
|
+
|
15
|
+
@book = Bookery::Book.new(chapters, config)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_title_pulled_from_options
|
19
|
+
refute_empty @book.title
|
7
20
|
end
|
8
21
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
22
|
+
def test_authors_pulled_from_options
|
23
|
+
assert_equal 2, @book.authors.size
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_editors_pulled_from_options
|
27
|
+
assert_equal 2, @book.editors.size
|
28
|
+
end
|
12
29
|
|
13
|
-
|
30
|
+
def test_language_pulled_from_options
|
31
|
+
refute_empty @book.language
|
14
32
|
end
|
15
33
|
|
16
|
-
def
|
17
|
-
|
34
|
+
def test_content_combines_all_chapters
|
35
|
+
expected = [
|
36
|
+
'# The First Chapter',
|
37
|
+
'# The Second Chapter'
|
38
|
+
]
|
39
|
+
|
40
|
+
expected.each { |heading| assert_includes @book.content, heading }
|
18
41
|
end
|
19
42
|
end
|
data/test/bookery/cli_test.rb
CHANGED
@@ -1,28 +1,39 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class CLITest <
|
4
|
-
|
5
|
-
|
6
|
-
assert_file 'README.md'
|
3
|
+
class CLITest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@cli = Bookery::CLI.new
|
7
6
|
end
|
8
7
|
|
9
|
-
def
|
10
|
-
|
8
|
+
def test_source_root_points_to_templates
|
9
|
+
templates_dir = File.expand_path('../../../templates', __FILE__)
|
10
|
+
assert_equal templates_dir, Bookery::CLI.source_root
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
13
|
+
def test_version_returns_gem_version
|
14
|
+
expected = Bookery::VERSION
|
15
|
+
|
16
|
+
output, _ = capture_io { @cli.version }
|
17
|
+
assert_equal expected, output.chomp
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
|
20
|
+
def test_new_creates_project
|
21
|
+
@cli.stubs(:directory).with('basic', 'project').once
|
22
|
+
@cli.new('project')
|
19
23
|
end
|
20
24
|
|
21
|
-
def
|
22
|
-
|
25
|
+
def test_new_creates_project_from_template
|
26
|
+
@cli.stubs(:directory).with('example', 'project').once
|
27
|
+
@cli.stubs(:options).returns({ template: 'example' })
|
28
|
+
@cli.new('project')
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
26
|
-
|
31
|
+
def test_publish_publishes_book
|
32
|
+
FileUtils.stubs(:mkdir_p)
|
33
|
+
FileUtils.stubs(:cp)
|
34
|
+
File.stubs(:write)
|
35
|
+
|
36
|
+
@cli.stubs(:options).returns({ project_dir: 'test/data/project' })
|
37
|
+
@cli.publish
|
27
38
|
end
|
28
39
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConfigTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
options = YAML.load_file('test/data/project/config.yml')
|
6
|
+
@config = Bookery::Config.new('es', options['book'])
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_language_specific_keys_override_globals
|
10
|
+
assert_equal 'El libro Testing', @config.title
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_global_values_returns_when_languages_specifics_not_found
|
14
|
+
assert_equal 2, @config.authors.size
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_can_retrieve_values_like_hashes
|
18
|
+
assert_equal @config.title, @config[:title]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_method_missing_bubbles_to_super
|
22
|
+
assert_raises(NoMethodError) do
|
23
|
+
@config.invalid_meta_method
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ChapterFactoryTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
book_dir = 'test/data/project/book/en'
|
7
|
+
@chapters = Bookery::Factories::ChapterFactory.create_chapters(book_dir)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_create_chapters_loads_each_chapter
|
11
|
+
assert_equal 2, @chapters.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_each_chapter_loads_chapter_files
|
15
|
+
expected = [
|
16
|
+
'# The Second Chapter',
|
17
|
+
'# Another File in Chapter 2'
|
18
|
+
]
|
19
|
+
|
20
|
+
expected.each do |string|
|
21
|
+
assert_includes @chapters.last.content, string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PublisherFactoryTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@options = {
|
7
|
+
enable_coderay: false,
|
8
|
+
project_dir: './',
|
9
|
+
template: 'test/data/project/assets/template/template.html.erb'
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_create_publishers
|
14
|
+
refute_equal 0, Bookery::Factories::PublisherFactory.create_publishers(@options)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IncludeProcessorTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@processor = Bookery::Processors::IncludeProcessor.new('./')
|
7
|
+
|
8
|
+
File.stubs('read').with('./js/file.js').returns('function someThing() {}')
|
9
|
+
File.stubs('read').with('./ruby/chapter2.rb').returns('def some_method; end')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_replaces_includes_with_file_content
|
13
|
+
input = <<-EOF
|
14
|
+
```javascript
|
15
|
+
includes::js/file.js
|
16
|
+
```
|
17
|
+
EOF
|
18
|
+
|
19
|
+
output = @processor.process(input)
|
20
|
+
assert_includes output, 'function someThing() {}'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_supports_multiple_includes
|
24
|
+
input = <<-EOF
|
25
|
+
```javascript
|
26
|
+
includes::js/file.js
|
27
|
+
```
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
includes::ruby/chapter2.rb
|
31
|
+
```
|
32
|
+
EOF
|
33
|
+
|
34
|
+
output = @processor.process(input)
|
35
|
+
assert_includes output, 'function someThing() {}'
|
36
|
+
assert_includes output, 'def some_method'
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ProjectTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
config = YAML.load_file('test/data/project/config.yml').symbolize_keys
|
6
|
+
@project = Bookery::Project.new('test/data/project', config)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_book_config
|
10
|
+
refute_empty @project.book_config[:title]
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_generator_config
|
14
|
+
refute_empty @project.generator_config[:input]
|
15
|
+
assert_equal @project.dir, @project.generator_config[:project_dir]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_books_returns_a_book_for_each_language
|
19
|
+
assert_equal 2, @project.books.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_publish_sends_each_book_to_each_publisher
|
23
|
+
books = @project.books
|
24
|
+
publishers = [mock(), mock()]
|
25
|
+
publishers.each { |pub| pub.expects(:publish).twice }
|
26
|
+
|
27
|
+
@project.stubs(:prepare_output_dir)
|
28
|
+
@project.publish(publishers)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_assets_return_without_includes_and_templates
|
32
|
+
assert_equal 2, @project.assets.size
|
33
|
+
assert_equal 'test/data/project/assets/images/cover.png', @project.assets.first
|
34
|
+
assert_equal 'test/data/project/assets/style.css', @project.assets.last
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HTMLPublisherTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@publisher = Bookery::Publishers::HTMLPublisher.new({
|
6
|
+
project_dir: 'test/data/project'
|
7
|
+
})
|
8
|
+
|
9
|
+
FileUtils.stubs(:mkdir_p)
|
10
|
+
File.stubs(:write)
|
11
|
+
end
|
12
|
+
|
13
|
+
def with_stubbed_book(content)
|
14
|
+
book = OpenStruct.new({
|
15
|
+
content: content,
|
16
|
+
title: 'Some Title',
|
17
|
+
authors: [],
|
18
|
+
editors: [],
|
19
|
+
language: 'en',
|
20
|
+
template: 'test/data/project/assets/templates/template.html.erb'
|
21
|
+
})
|
22
|
+
|
23
|
+
yield(book)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_publish_renders_html_from_markdown
|
27
|
+
with_stubbed_book('# Introduction') do |book|
|
28
|
+
expected = '<h1 id="introduction">Introduction</h1>'
|
29
|
+
assert_includes @publisher.publish(book), expected
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_publish_ignores_intra_emphasis
|
34
|
+
with_stubbed_book('_some_method_def_') do |book|
|
35
|
+
expected = '<p><em>some_method_def</em></p>'
|
36
|
+
assert_includes @publisher.publish(book), expected
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_publish_uses_pre_tags_for_standard_code_blocks
|
41
|
+
content = <<-EOF
|
42
|
+
def some_method(with, *params)
|
43
|
+
# Do Something
|
44
|
+
end
|
45
|
+
EOF
|
46
|
+
|
47
|
+
with_stubbed_book(content) do |book|
|
48
|
+
assert_includes @publisher.publish(book), '<pre><code>'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_publish_uses_coderay_for_fenced_code_blocks
|
53
|
+
content = <<-EOF
|
54
|
+
```ruby
|
55
|
+
def some_method(with, *params)
|
56
|
+
# Do Something
|
57
|
+
end
|
58
|
+
```
|
59
|
+
EOF
|
60
|
+
|
61
|
+
with_stubbed_book(content) do |book|
|
62
|
+
assert_includes @publisher.publish(book), '<div class="CodeRay">'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_publish_supports_includes
|
67
|
+
content = <<-EOF
|
68
|
+
```ruby
|
69
|
+
includes::ruby/chapter2.rb
|
70
|
+
```
|
71
|
+
EOF
|
72
|
+
|
73
|
+
with_stubbed_book(content) do |book|
|
74
|
+
assert_includes @publisher.publish(book), 'some_included_method'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
/*stylesheet for book*/
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="<%= language %>">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
|
+
<title><%= title %></title>
|
7
|
+
<meta name="author" content="<%= authors %>">
|
8
|
+
<meta name="description" content="<%= title %>">
|
9
|
+
<meta name="generator" content="bookery">
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<%= body %>
|
14
|
+
</body>
|
15
|
+
</html>
|