playgroundbook 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +2 -0
  5. data/.ruby-version +1 -0
  6. data/Changelog.md +17 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +103 -0
  9. data/Guardfile +14 -0
  10. data/LICENSE +21 -0
  11. data/README.md +92 -0
  12. data/Rakefile +8 -0
  13. data/bin/playgroundbook +22 -0
  14. data/lib/playgroundbook.rb +9 -0
  15. data/lib/playgroundbook_lint/abstract_linter.rb +23 -0
  16. data/lib/playgroundbook_lint/chapter_linter.rb +34 -0
  17. data/lib/playgroundbook_lint/chapter_manifest_linter.rb +43 -0
  18. data/lib/playgroundbook_lint/contents_linter.rb +20 -0
  19. data/lib/playgroundbook_lint/cutscene_page_linter.rb +17 -0
  20. data/lib/playgroundbook_lint/cutscene_page_manifest_linter.rb +18 -0
  21. data/lib/playgroundbook_lint/manifest_linter.rb +39 -0
  22. data/lib/playgroundbook_lint/page_linter.rb +23 -0
  23. data/lib/playgroundbook_lint/page_manifest_linter.rb +18 -0
  24. data/lib/playgroundbook_lint/playgroundbook_lint.rb +31 -0
  25. data/lib/playgroundbook_lint/root_manifest_linter.rb +36 -0
  26. data/lib/playgroundbook_renderer/chapter_collator.rb +77 -0
  27. data/lib/playgroundbook_renderer/contents_manifest_generator.rb +33 -0
  28. data/lib/playgroundbook_renderer/page_writer.rb +34 -0
  29. data/lib/playgroundbook_renderer/playgroundbook_renderer.rb +75 -0
  30. data/lib/version.rb +3 -0
  31. data/playground_book_lint.gemspec +21 -0
  32. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Manifest.plist +15 -0
  33. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Contents.swift +8 -0
  34. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Manifest.plist +12 -0
  35. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Contents.swift +8 -0
  36. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Manifest.plist +12 -0
  37. data/spec/fixtures/Starter.playgroundbook/Contents/Manifest.plist +20 -0
  38. data/spec/fixtures/assets/file.jpeg +0 -0
  39. data/spec/fixtures/book.yml +5 -0
  40. data/spec/fixtures/test_chapter.playground/Contents.swift +17 -0
  41. data/spec/fixtures/test_chapter.playground/contents.xcplayground +4 -0
  42. data/spec/playground_book_lint/chapter_linter_spec.rb +30 -0
  43. data/spec/playground_book_lint/chapter_manifest_linter_spec.rb +40 -0
  44. data/spec/playground_book_lint/contents_linter_spec.rb +18 -0
  45. data/spec/playground_book_lint/cutscene_page_linter_spec.rb +14 -0
  46. data/spec/playground_book_lint/cutscene_page_manifest_linter_spec.rb +63 -0
  47. data/spec/playground_book_lint/manfiest_linter_spec.rb +71 -0
  48. data/spec/playground_book_lint/page_linter_spec.rb +19 -0
  49. data/spec/playground_book_lint/page_manifest_linter_spec.rb +43 -0
  50. data/spec/playground_book_lint/playgroundbook_lint_spec.rb +38 -0
  51. data/spec/playground_book_lint/root_manifest_linter_spec.rb +35 -0
  52. data/spec/playgroundbook_renderer_spec/chapter_collator_spec.rb +70 -0
  53. data/spec/playgroundbook_renderer_spec/contents_manfiest_generator_spec.rb +37 -0
  54. data/spec/playgroundbook_renderer_spec/page_writer_spec.rb +57 -0
  55. data/spec/playgroundbook_renderer_spec/playgroundbook_renderer_spec.rb +112 -0
  56. data/spec/spec_helper.rb +75 -0
  57. metadata +141 -0
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Playgroundbook
2
+ VERSION = '0.2.0'.freeze
3
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'playgroundbook'
8
+ s.version = Playgroundbook::VERSION
9
+ s.licenses = ['MIT']
10
+ s.summary = 'Lints/renders Swift Playground books.'
11
+ s.description = 'Tooks for Swift Playground books on iOS, a renderer and a linter.'
12
+ s.authors = ['Ash Furrow']
13
+ s.homepage = 'https://github.com/ashfurrow/playground-book-lint'
14
+ s.email = 'ash@ashfurrow.com'
15
+ s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
+ s.require_paths = ['lib']
17
+ s.executables = ['playgroundbook']
18
+ s.add_runtime_dependency 'plist', '~> 3.2'
19
+ s.add_runtime_dependency 'colored', '~> 1.2'
20
+ s.add_runtime_dependency 'cork', '~> 0.1'
21
+ end
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Version</key>
6
+ <string>1.0</string>
7
+ <key>Name</key>
8
+ <string>Sample Chapter</string>
9
+ <key>Pages</key>
10
+ <array>
11
+ <string>Page1.playgroundpage</string>
12
+ <string>Page2.playgroundpage</string>
13
+ </array>
14
+ </dict>
15
+ </plist>
@@ -0,0 +1,8 @@
1
+ /*
2
+ Copyright (C) 2016 Apple Inc. All Rights Reserved.
3
+ See LICENSE.txt for this sample’s licensing information.
4
+
5
+ This is an example playground page.
6
+ */
7
+
8
+ print("Hello World")
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Version</key>
6
+ <string>1.0</string>
7
+ <key>Name</key>
8
+ <string>Example Page</string>
9
+ <key>LiveViewMode</key>
10
+ <string>HiddenByDefault</string>
11
+ </dict>
12
+ </plist>
@@ -0,0 +1,8 @@
1
+ /*
2
+ Copyright (C) 2016 Apple Inc. All Rights Reserved.
3
+ See LICENSE.txt for this sample’s licensing information.
4
+
5
+ This is a second example page.
6
+ */
7
+
8
+ print("Hello World")
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Version</key>
6
+ <string>1.0</string>
7
+ <key>Name</key>
8
+ <string>Second Example Page</string>
9
+ <key>LiveViewMode</key>
10
+ <string>HiddenByDefault</string>
11
+ </dict>
12
+ </plist>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Version</key>
6
+ <string>1.0</string>
7
+ <key>ContentVersion</key>
8
+ <string>1.0</string>
9
+ <key>Name</key>
10
+ <string>Starter</string>
11
+ <key>ContentIdentifier</key>
12
+ <string>com.example.apple-samplecode.Starter</string>
13
+ <key>DeploymentTarget</key>
14
+ <string>ios10.0</string>
15
+ <key>Chapters</key>
16
+ <array>
17
+ <string>Chapter1.playgroundchapter</string>
18
+ </array>
19
+ </dict>
20
+ </plist>
Binary file
@@ -0,0 +1,5 @@
1
+ name: Testing book
2
+ identifier: com.ashfurrow.example
3
+ resources: assets
4
+ chapters:
5
+ - test_chapter
@@ -0,0 +1,17 @@
1
+ import UIKit
2
+
3
+ public var str = "Hello, playground"
4
+
5
+ public func sharedFunc() {
6
+ print("This should be accessible to all pages.")
7
+ }
8
+
9
+ //// Page 1
10
+
11
+ str = "Yo, it's page 1."
12
+ sharedFunc()
13
+
14
+ //// Page 2
15
+
16
+ sharedFunc()
17
+ str = "Page 2 awww yeah."
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <playground version='5.0' target-platform='ios'>
3
+ <timeline fileName='timeline.xctimeline'/>
4
+ </playground>
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe RootManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:chapter_linter) { ChapterLinter.new(chapter_manifest_linter) }
7
+ let(:chapter_manifest_linter) { double(ChapterManifestLinter) }
8
+ let!(:chapter_directory_name) { 'test_chapter' }
9
+
10
+ it 'fails when chapter directory does not exist' do
11
+ expect { chapter_linter.lint(chapter_directory_name) }.to raise_error(SystemExit)
12
+ end
13
+
14
+ it 'fails when Pages subdirectory of chapter dir does not exist' do
15
+ FakeFS do
16
+ Dir.mkdir(chapter_directory_name)
17
+ expect { chapter_linter.lint(chapter_directory_name) }.to raise_error(SystemExit)
18
+ end
19
+ end
20
+
21
+ it 'calls through to chapter manifest linter' do
22
+ FakeFS do
23
+ expect(chapter_manifest_linter).to receive(:lint)
24
+ FileUtils.mkdir_p("#{chapter_directory_name}/Pages")
25
+
26
+ expect { chapter_linter.lint(chapter_directory_name) }.to_not raise_error
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe ChapterManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:chapter_manifest_linter) { ChapterManifestLinter.new(page_linter) }
7
+ let(:page_linter) { double(PageLinter) }
8
+ let!(:page_directory_name) { 'test.playgroundpage' }
9
+
10
+ it 'fails if no Pages defined in Manifest' do
11
+ FakeFS do
12
+ plist = { 'Name' => 'Test' }.to_plist
13
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
14
+
15
+ expect { chapter_manifest_linter.lint }.to raise_error(SystemExit)
16
+ end
17
+ end
18
+
19
+ it 'fails if Pages dir specified in Manifest does not exist' do
20
+ FakeFS do
21
+ plist = { 'Name' => 'Test', 'Pages' => [page_directory_name] }.to_plist
22
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
23
+ Dir.mkdir('Pages')
24
+
25
+ expect { chapter_manifest_linter.lint }.to raise_error(SystemExit)
26
+ end
27
+ end
28
+
29
+ it 'calls through to page linter' do
30
+ FakeFS do
31
+ expect(page_linter).to receive(:lint)
32
+ plist = { 'Name' => 'Test', 'Pages' => [page_directory_name] }.to_plist
33
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
34
+ FileUtils.mkdir_p("Pages/#{page_directory_name}")
35
+
36
+ expect { chapter_manifest_linter.lint }.to_not raise_error
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe ContentsLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:contents_linter) { ContentsLinter.new(root_manifest_linter) }
7
+ let(:root_manifest_linter) { double(RootManifestLinter) }
8
+
9
+ it 'calls through to root manifest linter' do
10
+ expect(root_manifest_linter).to receive(:lint)
11
+
12
+ FakeFS do
13
+ Dir.mkdir 'Contents'
14
+ contents_linter.lint
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe CutscenePageLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:cutscene_page_linter) { CutscenePageLinter.new(cutscene_page_manifest_linter) }
7
+ let(:cutscene_page_manifest_linter) { double(CutscenePageManifestLinter) }
8
+
9
+ it 'passes through to cutscene_page_manifest_linter' do
10
+ expect(cutscene_page_manifest_linter).to receive(:lint)
11
+ expect { cutscene_page_linter.lint }.to_not raise_error
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe CutscenePageManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:cutscene_page_manifest_linter) { CutscenePageManifestLinter.new }
7
+
8
+ it 'given a valid manifest does not fail' do
9
+ FakeFS do
10
+ cutscene_reference = 'RealFile.html'
11
+ plist = {
12
+ 'Name' => 'Test Page',
13
+ 'CutsceneReference' => cutscene_reference
14
+ }.to_plist
15
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
16
+ File.open(cutscene_reference, 'w')
17
+
18
+ expect { cutscene_page_manifest_linter.lint }.not_to raise_error
19
+ end
20
+ end
21
+
22
+ context 'given a cutscene path' do
23
+ it "fails if the key doesn't exist" do
24
+ FakeFS do
25
+ cutscene_reference = 'FakeFile.html'
26
+ plist = {
27
+ 'Name' => 'Test Page',
28
+ }.to_plist
29
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
30
+
31
+ expect { cutscene_page_manifest_linter.lint }.to raise_error(SystemExit)
32
+ end
33
+ end
34
+
35
+ it "fails if that file doesn't exist" do
36
+ FakeFS do
37
+ cutscene_reference = 'FakeFile.html'
38
+ plist = {
39
+ 'Name' => 'Test Page',
40
+ 'CutsceneReference' => cutscene_reference
41
+ }.to_plist
42
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
43
+
44
+ expect { cutscene_page_manifest_linter.lint }.to raise_error(SystemExit)
45
+ end
46
+ end
47
+
48
+ it 'fails with a non-HTML file' do
49
+ FakeFS do
50
+ cutscene_reference = 'RealFile.xml'
51
+ plist = {
52
+ 'Name' => 'Test Page',
53
+ 'CutsceneReference' => cutscene_reference
54
+ }.to_plist
55
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
56
+ File.open(cutscene_reference, 'w')
57
+
58
+ expect { cutscene_page_manifest_linter.lint }.to raise_error(SystemExit)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe RootManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:manifest_linter) { ManifestLinter.new }
7
+
8
+ it 'fails if a Manifest.plist file does not exist' do
9
+ expect { manifest_linter.lint }.to raise_error(SystemExit)
10
+ end
11
+
12
+ it 'fails if the Manifest.plist file does not contain a Name value' do
13
+ FakeFS do
14
+ plist = {}.to_plist
15
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
16
+
17
+ expect { manifest_linter.lint }.to raise_error(SystemExit)
18
+ end
19
+ end
20
+
21
+ it 'succeeds if the Manifest.plist file is well-formed' do
22
+ FakeFS do
23
+ plist = { 'Name' => 'My Test Name' }.to_plist
24
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
25
+
26
+ expect { manifest_linter.lint }.to_not raise_error
27
+ end
28
+ end
29
+
30
+ it 'extracts Manfiest.plist contents from pwd' do
31
+ FakeFS do
32
+ contents = { 'key' => 'value' }
33
+ File.open('Manifest.plist', 'w') { |f| f.write(contents.to_plist) }
34
+
35
+ expect(manifest_linter.manifest_plist_contents).to eq(contents)
36
+ end
37
+ end
38
+
39
+ describe 'key-value checking' do
40
+ before do
41
+ end
42
+
43
+ it 'checks for non-defined keys in manifest' do
44
+ FakeFS do
45
+ plist = {}.to_plist
46
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
47
+
48
+ expect(manifest_linter.value_defined_in_manifest?('key')).to be_falsy
49
+ end
50
+ end
51
+
52
+ it 'checks for nil keys in manifest' do
53
+ FakeFS do
54
+ plist = { 'key' => nil }.to_plist
55
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
56
+
57
+ expect(manifest_linter.value_defined_in_manifest?('key')).to be_falsy
58
+ end
59
+ end
60
+
61
+ it 'checks for empty keys in manifest' do
62
+ FakeFS do
63
+ plist = { 'key' => 'value' }.to_plist
64
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
65
+
66
+ expect(manifest_linter.value_defined_in_manifest?('key')).to be_truthy
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe PageLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:page_linter) { PageLinter.new(page_manifest_linter) }
7
+ let(:page_manifest_linter) { double(PageManifestLinter) }
8
+
9
+ it 'fails if Contents.swift does not exist' do
10
+ expect { page_linter.lint }.to raise_error(SystemExit)
11
+ end
12
+
13
+ it 'passes through to page_manifest_linter' do
14
+ File.open(ContentsSwiftFileName, 'w') { |f| f.write('') }
15
+ expect(page_manifest_linter).to receive(:lint)
16
+ expect { page_linter.lint }.to_not raise_error
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Playgroundbook
4
+ describe PageManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:page_manifest_linter) { PageManifestLinter.new }
7
+
8
+ it 'given a valid manifest does not fail' do
9
+ # TODO: We're not checking optional values yet, more tests to come.
10
+ # See page_manifest_linter.rb and https://github.com/ashfurrow/playground-book-lint/issues/3 for details.
11
+
12
+ FakeFS do
13
+ plist = { 'Name' => 'Test Page' }.to_plist
14
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
15
+ expect { page_manifest_linter.lint }.to_not raise_error
16
+ end
17
+ end
18
+
19
+ describe 'context given a live view mode' do
20
+ it 'succeeds with valid values' do
21
+ FakeFS do
22
+ plist = {
23
+ 'Name' => 'Test Page',
24
+ 'LiveViewMode' => 'HiddenByDefault'
25
+ }.to_plist
26
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
27
+ expect { page_manifest_linter.lint }.to_not raise_error
28
+ end
29
+ end
30
+
31
+ it 'fails with invalid values' do
32
+ FakeFS do
33
+ plist = {
34
+ 'Name' => 'Test Page',
35
+ 'LiveViewMode' => 'UnsupportedViewMode'
36
+ }.to_plist
37
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
38
+ expect { page_manifest_linter.lint }.to raise_error(SystemExit)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end