playground-book-lint 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +10 -0
  6. data/Gemfile.lock +92 -0
  7. data/Guardfile +14 -0
  8. data/LICENSE +21 -0
  9. data/README.md +4 -0
  10. data/Rakefile +6 -0
  11. data/bin/playground_book_lint +13 -0
  12. data/lib/playground_book_lint.rb +30 -0
  13. data/lib/playground_book_lint/abstract_linter.rb +21 -0
  14. data/lib/playground_book_lint/chapter_linter.rb +33 -0
  15. data/lib/playground_book_lint/chapter_manifest_linter.rb +33 -0
  16. data/lib/playground_book_lint/contents_linter.rb +19 -0
  17. data/lib/playground_book_lint/manifest_linter.rb +38 -0
  18. data/lib/playground_book_lint/page_linter.rb +24 -0
  19. data/lib/playground_book_lint/page_manifest_linter.rb +11 -0
  20. data/lib/playground_book_lint/root_manifest_linter.rb +35 -0
  21. data/lib/version.rb +3 -0
  22. data/playground_book_lint.gemspec +21 -0
  23. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Manifest.plist +15 -0
  24. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Contents.swift +8 -0
  25. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Manifest.plist +12 -0
  26. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Contents.swift +8 -0
  27. data/spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Manifest.plist +12 -0
  28. data/spec/fixtures/Starter.playgroundbook/Contents/Manifest.plist +20 -0
  29. data/spec/playground_book_lint/chapter_linter_spec.rb +30 -0
  30. data/spec/playground_book_lint/chapter_manifest_linter_spec.rb +40 -0
  31. data/spec/playground_book_lint/contents_linter_spec.rb +18 -0
  32. data/spec/playground_book_lint/manfiest_linter_spec.rb +71 -0
  33. data/spec/playground_book_lint/page_linter_spec.rb +19 -0
  34. data/spec/playground_book_lint/page_manifest_linter_spec.rb +19 -0
  35. data/spec/playground_book_lint/root_manifest_linter_spec.rb +35 -0
  36. data/spec/playground_book_lint_spec.rb +38 -0
  37. data/spec/spec_helper.rb +33 -0
  38. metadata +122 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4a9cd7db59000a89e781c372d8dd903060039fb5
4
+ data.tar.gz: 89947202a1f3f8de3c3ba5475fd0ff775c800e10
5
+ SHA512:
6
+ metadata.gz: 532f5f3df487894832c008adfa88c1a35aa50dea33e82a1f368204d0fcfaa3cfdb5c3331c0c36911630714b916c67ab90fd7acab199377ffca91fc59c5bae1ab
7
+ data.tar.gz: 267257810a36d42b4dcc4225dd26c9888718a96cecc287ba5d468e449a72b4f5dc831971c34b4c3e0a20f964154a60db20cf916be78db3b359087a4404d844a7
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1 @@
1
+ ruby-2.0.0-p247
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'guard-rspec'
4
+ gem 'mocha'
5
+ gem 'bacon'
6
+ gem 'mocha-on-bacon'
7
+ gem 'prettybacon'
8
+ gem 'fakefs'
9
+
10
+ gemspec
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ playground-book-lint (0.0.1)
5
+ colored (~> 1.2)
6
+ cork (~> 0.1)
7
+ plist (~> 3.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ bacon (1.2.0)
13
+ coderay (1.1.1)
14
+ colored (1.2)
15
+ cork (0.1.0)
16
+ colored (~> 1.2)
17
+ diff-lcs (1.2.5)
18
+ fakefs (0.9.0)
19
+ ffi (1.9.10)
20
+ formatador (0.2.5)
21
+ guard (2.14.0)
22
+ formatador (>= 0.2.4)
23
+ listen (>= 2.7, < 4.0)
24
+ lumberjack (~> 1.0)
25
+ nenv (~> 0.1)
26
+ notiffany (~> 0.0)
27
+ pry (>= 0.9.12)
28
+ shellany (~> 0.0)
29
+ thor (>= 0.18.1)
30
+ guard-compat (1.2.1)
31
+ guard-rspec (4.7.2)
32
+ guard (~> 2.1)
33
+ guard-compat (~> 1.1)
34
+ rspec (>= 2.99.0, < 4.0)
35
+ listen (3.0.7)
36
+ rb-fsevent (>= 0.9.3)
37
+ rb-inotify (>= 0.9.7)
38
+ lumberjack (1.0.10)
39
+ metaclass (0.0.4)
40
+ method_source (0.8.2)
41
+ mocha (1.1.0)
42
+ metaclass (~> 0.0.1)
43
+ mocha-on-bacon (0.2.2)
44
+ mocha (>= 0.13.0)
45
+ nenv (0.3.0)
46
+ notiffany (0.1.0)
47
+ nenv (~> 0.1)
48
+ shellany (~> 0.0)
49
+ plist (3.2.0)
50
+ prettybacon (0.0.2)
51
+ bacon (~> 1.2)
52
+ pry (0.10.3)
53
+ coderay (~> 1.1.0)
54
+ method_source (~> 0.8.1)
55
+ slop (~> 3.4)
56
+ rb-fsevent (0.9.7)
57
+ rb-inotify (0.9.7)
58
+ ffi (>= 0.5.0)
59
+ rspec (3.5.0)
60
+ rspec-core (~> 3.5.0)
61
+ rspec-expectations (~> 3.5.0)
62
+ rspec-mocks (~> 3.5.0)
63
+ rspec-core (3.5.1)
64
+ rspec-support (~> 3.5.0)
65
+ rspec-expectations (3.5.0)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.5.0)
68
+ rspec-mocks (3.5.0)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.5.0)
71
+ rspec-support (3.5.0)
72
+ shellany (0.0.1)
73
+ slop (3.6.0)
74
+ thor (0.19.1)
75
+
76
+ PLATFORMS
77
+ ruby
78
+
79
+ DEPENDENCIES
80
+ bacon
81
+ fakefs
82
+ guard-rspec
83
+ mocha
84
+ mocha-on-bacon
85
+ playground-book-lint!
86
+ prettybacon
87
+
88
+ RUBY VERSION
89
+ ruby 2.0.0p247
90
+
91
+ BUNDLED WITH
92
+ 1.12.5
@@ -0,0 +1,14 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ require 'guard/rspec/dsl'
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Ash Furrow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ [![CircleCI](https://circleci.com/gh/ashfurrow/playground-book-lint.svg?style=svg)](https://circleci.com/gh/ashfurrow/playground-book-lint)
2
+
3
+ # playground-book-lint
4
+ Linter for Swift Playground books
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ playground_file_name = ARGV.first
4
+
5
+ unless playground_file_name
6
+ puts "You must specify a playground file name."
7
+ exit 1
8
+ end
9
+
10
+ require 'playground_book_lint'
11
+
12
+ linter = PlaygroundBookLint::Linter.new(playground_file_name)
13
+ linter.lint()
@@ -0,0 +1,30 @@
1
+ require 'colored'
2
+ require 'playground_book_lint/abstract_linter'
3
+ require 'playground_book_lint/contents_linter'
4
+ require 'pathname'
5
+
6
+ module PlaygroundBookLint
7
+ class Linter < AbstractLinter
8
+ attr_accessor :playground_file_name
9
+ attr_accessor :contents_linter
10
+
11
+ def initialize(playground_file_name, contents_linter = ContentsLinter.new())
12
+ @playground_file_name = playground_file_name
13
+ @contents_linter = contents_linter
14
+ end
15
+
16
+ def lint
17
+ message "Validating #{playground_file_name.yellow}..."
18
+
19
+ fail_lint 'No Contents directory' unless contents_dir_exists?
20
+
21
+ Dir.chdir playground_file_name do
22
+ contents_linter.lint()
23
+ end
24
+ end
25
+
26
+ def contents_dir_exists?
27
+ return Dir.exists?(playground_file_name + '/Contents')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ require 'colored'
2
+ require 'cork'
3
+
4
+ module PlaygroundBookLint
5
+ class AbstractLinter
6
+ @@ui = Cork::Board.new()
7
+
8
+ def self.ui=(value)
9
+ @@ui = value
10
+ end
11
+
12
+ def fail_lint(msg)
13
+ @@ui.puts msg.red
14
+ exit 1
15
+ end
16
+
17
+ def message(msg)
18
+ @@ui.puts msg
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ require 'plist'
2
+ require 'playground_book_lint/abstract_linter'
3
+ require 'playground_book_lint/chapter_manifest_linter'
4
+
5
+ module PlaygroundBookLint
6
+ PAGES_DIRECTORY_NAME = 'Pages'
7
+
8
+ class ChapterLinter < AbstractLinter
9
+ attr_accessor :chapter_manifest_linter
10
+
11
+ def initialize(chapter_manifest_linter = ChapterManifestLinter.new())
12
+ @chapter_manifest_linter = chapter_manifest_linter
13
+ end
14
+
15
+ def lint(chapter_directory_name)
16
+ fail_lint "Chapter specified in manifest does not exist: #{chapter_directory_name}." unless chapter_directory_exists?(chapter_directory_name)
17
+
18
+ Dir.chdir chapter_directory_name do
19
+ fail_lint "Pages directory in chapter does not exist: #{chapter_directory_name}." unless pages_directory_exists?
20
+
21
+ chapter_manifest_linter.lint()
22
+ end
23
+ end
24
+
25
+ def chapter_directory_exists?(chapter_directory_name)
26
+ return Dir.exist? chapter_directory_name
27
+ end
28
+
29
+ def pages_directory_exists?
30
+ return Dir.exist? PAGES_DIRECTORY_NAME
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'playground_book_lint/manifest_linter'
2
+ require 'playground_book_lint/page_linter'
3
+
4
+ module PlaygroundBookLint
5
+ class ChapterManifestLinter < ManifestLinter
6
+ attr_accessor :page_linter
7
+
8
+ def initialize(page_linter = PageLinter.new())
9
+ @page_linter = page_linter
10
+ end
11
+
12
+ def lint
13
+ super()
14
+
15
+ fail_lint "Chapter has no pages in #{Dir.pwd}" unless chapter_has_manifest_pages?
16
+
17
+ manifest_plist_contents['Pages'].each do |page_directory_name|
18
+ # All pages exist inside the /Pages subdirectory, we need to chdir to there first.
19
+ Dir.chdir PAGES_DIRECTORY_NAME do
20
+ fail_lint "Chapter page directory #{page_directory_name} missing in #{Dir.pwd}" unless Dir.exist?(page_directory_name)
21
+
22
+ Dir.chdir page_directory_name do
23
+ page_linter.lint()
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def chapter_has_manifest_pages?
30
+ value_defined_in_manifest?('Pages')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ require 'playground_book_lint/abstract_linter'
2
+ require 'playground_book_lint/root_manifest_linter'
3
+
4
+ module PlaygroundBookLint
5
+ class ContentsLinter < AbstractLinter
6
+ attr_accessor :root_manfiest_linter
7
+
8
+ def initialize(root_manfiest_linter = RootManifestLinter.new())
9
+ @root_manfiest_linter = root_manfiest_linter
10
+ end
11
+
12
+ def lint
13
+ Dir.chdir 'Contents' do
14
+ root_manfiest_linter.lint()
15
+ # TODO: Other linting?
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require 'plist'
2
+ require 'playground_book_lint/abstract_linter'
3
+
4
+ module PlaygroundBookLint
5
+ MANIFEST_FILE_NAME = 'Manifest.plist'
6
+
7
+ class ManifestLinter < AbstractLinter
8
+
9
+ #TODO: Should load manifest file in initialize instead of lazily.
10
+
11
+ def lint
12
+ fail_lint "No Manifest file in #{Dir.pwd}" unless manifest_file_exists?
13
+ fail_lint "Manifest file missing Name in #{Dir.pwd}" unless has_name?
14
+ end
15
+
16
+ def manifest_file_exists?
17
+ return File.exists? MANIFEST_FILE_NAME
18
+ end
19
+
20
+ def manifest_plist_contents
21
+ return @manifest_plist_contents unless @manifest_plist_contents.nil?
22
+ require 'plist'
23
+ @manifest_plist_contents = Plist::parse_xml(MANIFEST_FILE_NAME)
24
+ return @manifest_plist_contents
25
+ end
26
+
27
+ def has_name?
28
+ value_defined_in_manifest?('Name')
29
+ end
30
+
31
+ def value_defined_in_manifest?(key)
32
+ return false if manifest_plist_contents.nil?
33
+ return false if manifest_plist_contents[key].nil?
34
+ return false if manifest_plist_contents[key].empty?
35
+ return true
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,24 @@
1
+ require 'playground_book_lint/abstract_linter'
2
+ require 'playground_book_lint/page_manifest_linter'
3
+
4
+ module PlaygroundBookLint
5
+ CONTENTS_SWIFT_FILE_NAME = 'Contents.swift'
6
+
7
+ class PageLinter < AbstractLinter
8
+ attr_accessor :page_manifest_linter
9
+
10
+ def initialize(page_manifest_linter = PageManifestLinter.new())
11
+ @page_manifest_linter = page_manifest_linter
12
+ end
13
+
14
+ def lint
15
+ fail_lint "Missing #{CONTENTS_SWIFT_FILE_NAME} in #{Dir.pwd}" unless contents_swift_file_exists?
16
+
17
+ page_manifest_linter.lint()
18
+ end
19
+
20
+ def contents_swift_file_exists?
21
+ return File.exist? CONTENTS_SWIFT_FILE_NAME
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'plist'
2
+ require 'playground_book_lint/manifest_linter'
3
+
4
+ module PlaygroundBookLint
5
+ class PageManifestLinter < ManifestLinter
6
+ def lint
7
+ super()
8
+ # TODO: Check for valid LiveViewMode values.
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ require 'plist'
2
+ require 'playground_book_lint/manifest_linter'
3
+ require 'playground_book_lint/chapter_linter'
4
+
5
+ module PlaygroundBookLint
6
+ class RootManifestLinter < ManifestLinter
7
+ attr_accessor :chapter_linter
8
+
9
+ def initialize(chapter_linter = ChapterLinter.new())
10
+ @chapter_linter = chapter_linter
11
+ end
12
+
13
+ def lint
14
+ super()
15
+
16
+ fail_lint "No Chapters directory" unless chapters_directory_exist?
17
+ fail_lint "No Chapters specified" unless chapters_exist?
18
+
19
+ # Go into Chapters/ and then each chapter directory, then lint it.
20
+ Dir.chdir 'Chapters' do
21
+ manifest_plist_contents['Chapters'].each do |chapter_directory_name|
22
+ chapter_linter.lint(chapter_directory_name)
23
+ end
24
+ end
25
+ end
26
+
27
+ def chapters_directory_exist?
28
+ return Dir.exist? 'Chapters'
29
+ end
30
+
31
+ def chapters_exist?
32
+ value_defined_in_manifest?('Chapters')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module PlaygroundBookLint
2
+ VERSION = '0.0.1'.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 = 'playground-book-lint'
8
+ s.version = PlaygroundBookLint::VERSION
9
+ s.licenses = ['MIT']
10
+ s.summary = "Lints Swift Playground books."
11
+ s.description = "Lints books for Swift Playgrounds on iOS"
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($/)
16
+ s.require_paths = ["lib"]
17
+ s.executables = ['playground_book_lint']
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>
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module PlaygroundBookLint
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 PlaygroundBookLint
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_page_directory_name' }
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 PlaygroundBookLint
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,71 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module PlaygroundBookLint
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 PlaygroundBookLint
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('Contents.swift', '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,19 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module PlaygroundBookLint
4
+ describe PageManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:page_manifest_linter) { PageManifestLinter.new() }
7
+
8
+ it '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
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module PlaygroundBookLint
4
+ describe RootManifestLinter do
5
+ include FakeFS::SpecHelpers
6
+ let(:root_manifest_linter) { RootManifestLinter.new(chapter_linter) }
7
+ let(:chapter_linter) { double(ChapterLinter) }
8
+
9
+ it 'fails if Chapters directory does not exist' do
10
+ expect{ root_manifest_linter.lint() }.to raise_error(SystemExit)
11
+ end
12
+
13
+ it 'fails if manfiest does not include Chapters' do
14
+ FakeFS do
15
+ Dir.mkdir('Chapters')
16
+ plist = {'Name' => 'Test'}.to_plist
17
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
18
+
19
+ expect{ root_manifest_linter.lint() }.to raise_error(SystemExit)
20
+ end
21
+ end
22
+
23
+ it 'calls through to lint each chapter' do
24
+ FakeFS do
25
+ plist = {'Chapters' => ['test_chapter_name'], 'Name' => 'Test'}.to_plist
26
+ File.open('Manifest.plist', 'w') { |f| f.write(plist) }
27
+ Dir.mkdir('Chapters')
28
+
29
+ expect(chapter_linter).to receive(:lint).with('test_chapter_name')
30
+
31
+ expect{ root_manifest_linter.lint() }.to_not raise_error
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ module PlaygroundBookLint
4
+ describe Linter do
5
+ let(:linter) { Linter.new(test_playground_book, contents_linter) }
6
+ let(:contents_linter) { double(ContentsLinter) }
7
+
8
+ it 'initializes correctly' do
9
+ expect(linter.playground_file_name) == test_playground_book
10
+ end
11
+
12
+ it 'exits on lint failure' do
13
+ allow(linter).to receive(:contents_dir_exists?)
14
+ .and_return(false)
15
+
16
+ expect{ linter.lint() }.to raise_error(SystemExit)
17
+ end
18
+
19
+ it 'fails when file does not exist' do
20
+ allow(linter).to receive(:contents_dir_exists?)
21
+ .and_return(false)
22
+ allow(linter).to receive(:fail_lint)
23
+ .with('No Contents directory')
24
+ .and_raise(SystemExit)
25
+
26
+ expect{ linter.lint() }.to raise_error(SystemExit)
27
+ end
28
+
29
+ it 'lints' do
30
+ allow(linter).to receive(:contents_dir_exists?)
31
+ .and_return(true)
32
+ allow(contents_linter).to receive(:lint)
33
+ expect(Dir).to receive(:chdir).with(test_playground_book)
34
+
35
+ linter.lint()
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ require 'pathname'
2
+ require 'cork'
3
+ require 'rspec'
4
+ require 'plist'
5
+ require 'fakefs/spec_helpers'
6
+
7
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
8
+ $LOAD_PATH.unshift((ROOT + 'lib').to_s)
9
+ $LOAD_PATH.unshift((ROOT + 'spec').to_s)
10
+
11
+ require 'playground_book_lint'
12
+ require 'playground_book_lint/abstract_linter'
13
+ require 'playground_book_lint/chapter_linter'
14
+ require 'playground_book_lint/chapter_manifest_linter'
15
+ require 'playground_book_lint/contents_linter'
16
+ require 'playground_book_lint/manifest_linter'
17
+ require 'playground_book_lint/page_linter'
18
+ require 'playground_book_lint/page_manifest_linter'
19
+ require 'playground_book_lint/root_manifest_linter'
20
+
21
+
22
+ RSpec.configure do |config|
23
+ config.color = true
24
+
25
+ config.order = :random
26
+ Kernel.srand config.seed
27
+ end
28
+
29
+ def test_playground_book
30
+ 'spec/fixtures/Starter.playgroundbook'
31
+ end
32
+
33
+ PlaygroundBookLint::AbstractLinter.ui = Cork::Board.new(silent: true)
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: playground-book-lint
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ash Furrow
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: plist
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colored
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cork
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
55
+ description: Lints books for Swift Playgrounds on iOS
56
+ email: ash@ashfurrow.com
57
+ executables:
58
+ - playground_book_lint
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - .ruby-version
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - Guardfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - bin/playground_book_lint
72
+ - lib/playground_book_lint.rb
73
+ - lib/playground_book_lint/abstract_linter.rb
74
+ - lib/playground_book_lint/chapter_linter.rb
75
+ - lib/playground_book_lint/chapter_manifest_linter.rb
76
+ - lib/playground_book_lint/contents_linter.rb
77
+ - lib/playground_book_lint/manifest_linter.rb
78
+ - lib/playground_book_lint/page_linter.rb
79
+ - lib/playground_book_lint/page_manifest_linter.rb
80
+ - lib/playground_book_lint/root_manifest_linter.rb
81
+ - lib/version.rb
82
+ - playground_book_lint.gemspec
83
+ - spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Manifest.plist
84
+ - spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Contents.swift
85
+ - spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page1.playgroundpage/Manifest.plist
86
+ - spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Contents.swift
87
+ - spec/fixtures/Starter.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Page2.playgroundpage/Manifest.plist
88
+ - spec/fixtures/Starter.playgroundbook/Contents/Manifest.plist
89
+ - spec/playground_book_lint/chapter_linter_spec.rb
90
+ - spec/playground_book_lint/chapter_manifest_linter_spec.rb
91
+ - spec/playground_book_lint/contents_linter_spec.rb
92
+ - spec/playground_book_lint/manfiest_linter_spec.rb
93
+ - spec/playground_book_lint/page_linter_spec.rb
94
+ - spec/playground_book_lint/page_manifest_linter_spec.rb
95
+ - spec/playground_book_lint/root_manifest_linter_spec.rb
96
+ - spec/playground_book_lint_spec.rb
97
+ - spec/spec_helper.rb
98
+ homepage: https://github.com/ashfurrow/playground-book-lint
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.4.8
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Lints Swift Playground books.
122
+ test_files: []