smashing_docs 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 22b7029c0973147b6d3a28e53a5f3cab6c77b9a0
4
+ data.tar.gz: 0d6744dbb8ebdd8a92dccc1302bdd51c2100ddc9
5
+ SHA512:
6
+ metadata.gz: bf8e59d70429b63875b0a3f405f26b598d644fd3dfc9a0cb8bc8f6dc0dd45e25d99711a11ba4ccb2a7b6e9260b56e31b2f5e37e267fa6d4e4df668437d11677b
7
+ data.tar.gz: 9ad103afe3b8f88ffa85ab7df2c0b716d9169f2134022b147855bb0e00d7d971e28220d6d66464d21880b12a9cc55834b2fad439ad477285cfd4f96e2a58fb9a
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /coverage/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # SmashingDocs
2
+
3
+ ### Based on [SmarfDoc](https://github.com/RickCarlino/smarf_doc) by [Rick Carlino](https://github.com/RickCarlino/)
4
+
5
+ ## Gem Installation in Rails
6
+
7
+ In your gemfile add the following to your test group:
8
+
9
+ `gem 'smashing_docs', git: 'https://github.com/smashingboxes/smashing_docs.git'`
10
+
11
+ Installation differs for RSpec/Minitest, so scroll to the appropriate section for guidance.
12
+
13
+ ## Rspec Installation
14
+
15
+ Add this to your `rails_helper.rb` It should go outside of other blocks
16
+ (Do not place it inside the `RSpec.configure` block).
17
+ ```ruby
18
+ SmarfDoc.config do |c|
19
+ c.template_file = 'spec/template.md.erb'
20
+ c.output_file = 'api_docs.md'
21
+ end
22
+ ```
23
+
24
+ Add the following line to `spec_helper.rb` inside the `RSpec.configure` block
25
+
26
+ `config.after(:suite) { SmashingDocs.finish! }`
27
+
28
+ It should look like this
29
+ ```ruby
30
+ RSpec.configure do |config|
31
+ # Existing code
32
+ config.after(:suite) { SmashingDocs.finish! }
33
+ end
34
+ ```
35
+ #### To run on all controller tests
36
+
37
+ Add this to your `spec_helper.rb`
38
+ ```ruby
39
+ config.after(:each, type: :controller) do
40
+ SmashingDocs.run!(request, response)
41
+ end
42
+ ```
43
+
44
+ The whole file should look like this
45
+ ```ruby
46
+ RSpec.configure do |config|
47
+ # Existing code
48
+ config.after(:each, type: :controller) do
49
+ SmashingDocs.run!(request, response)
50
+ end
51
+ config.after(:suite) { SmashingDocs.finish! }
52
+ end
53
+ ```
54
+ #### To run on only select tests
55
+ Just add `SmashingDocs.run!(request, response)` to specific tests
56
+ ```ruby
57
+ it "responds with 200" do
58
+ get :index
59
+ expect(response).to be_success
60
+ SmashingDocs.run!(request, response)
61
+ end
62
+ ```
63
+
64
+ ## Minitest Installation
65
+
66
+ Add the code from below to `test_helper.rb`:
67
+ ```ruby
68
+ class ActiveSupport::TestCase
69
+ # Already existing code
70
+ SmashingDocs.config do |c|
71
+ c.template_file = 'test/template.md.erb'
72
+ c.output_file = 'api_docs.md'
73
+ end
74
+ # More code
75
+ end
76
+
77
+ MiniTest::Unit.after_tests { SmashingDocs.finish! }
78
+ ```
79
+ #### To run on all controller tests
80
+ Add this to `test_helper.rb` as well:
81
+ ```ruby
82
+ class ActionController::TestCase < ActiveSupport::TestCase
83
+ def teardown
84
+ SmashingDocs.run!(request, response)
85
+ end
86
+ end
87
+ ```
88
+
89
+ Your code should look like this:
90
+ ```ruby
91
+ class ActiveSupport::TestCase
92
+ # Already existing code
93
+ SmashingDocs.config do |c|
94
+ c.template_file = 'test/template.md.erb'
95
+ c.output_file = 'api_docs.md'
96
+ end
97
+ # More code
98
+ end
99
+
100
+ class ActionController::TestCase < ActiveSupport::TestCase
101
+ def teardown
102
+ SmashingDocs.run!(request, response)
103
+ end
104
+ end
105
+
106
+ MiniTest::Unit.after_tests { SmashingDocs.finish! }
107
+ ```
108
+
109
+
110
+ #### To run on only select tests
111
+ Just add `SmashingDocs.run!(request, response)` to specific tests
112
+ ```ruby
113
+ def get_index
114
+ get :index
115
+ assert response.status == 200
116
+ SmashingDocs.run!(request, response)
117
+ end
118
+ ```
119
+
120
+ ## Setting a template
121
+
122
+ If you copied the code from above, SmashingDocs will look for a template file located at either
123
+ `test/template.md.erb` or `spec/template.md.erb`, depending on your test suite.
124
+ This template may be customized to fit your needs.
125
+
126
+ ```erb
127
+ <%= request.method %>
128
+ <%= request.path %>
129
+ <%= request.params %>
130
+ <%= response.body %>
131
+ <%= information[:note] %>
132
+ <%= aside %>
133
+ ```
134
+
135
+ ## Where to find the docs
136
+
137
+ By default, the docs are output to `api_docs.md` in the root of the Rails project.
138
+ You can change this by altering the config in `test_helper.rb` or `rails_helper.rb`.
139
+
140
+ ## Additional Features
141
+
142
+ #### Skipping documentation on tests
143
+
144
+ To leave certain tests out of the documentation, just add `SmashingDocs.skip` to the test.
145
+
146
+ ```ruby
147
+ it "responds with 200" do
148
+ SmashingDocs.skip
149
+ # test code
150
+ end
151
+ ```
152
+
153
+ #### Adding information, e.g. notes
154
+ SmashingDocs will log all requests and responses by default, but you can add some
155
+ **optional** parameters as well.
156
+
157
+ ```ruby
158
+ it "responds with 200" do
159
+ SmashingDocs.information(:note, "This endpoint only responds on Tuesdays")
160
+ # test code
161
+ end
162
+ ```
163
+ You can store any information with `:note`, `:message`, or any other key you can think of.
164
+ To access information in the template, just use `<%= information[:key] %>`
data/Rakefile ADDED
@@ -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
data/api_docs.md ADDED
File without changes
data/documentation.md ADDED
@@ -0,0 +1,80 @@
1
+ You can use ERB to format each test case.
2
+ GET
3
+ api/aaa
4
+ {:id=>12}
5
+ {"id": 12, "name": "rick"}
6
+ You can use ERB to format each test case.
7
+ GET
8
+ api/users
9
+ {:id=>12}
10
+ {"id": 12, "name": "rick"}
11
+ You can use ERB to format each test case.
12
+ GET
13
+ api/users
14
+ {:id=>12}
15
+ {"id": 12, "name": "rick"}
16
+ You can use ERB to format each test case.
17
+ GET
18
+ api/zzz
19
+ {:id=>12}
20
+ {"id": 12, "name": "rick"}
21
+ You can use ERB to format each test case.
22
+ GET
23
+ api/aaa
24
+ {:id=>12}
25
+ {"id": 12, "name": "rick"}
26
+ You can use ERB to format each test case.
27
+ GET
28
+ api/users
29
+ {:id=>12}
30
+ {"id": 12, "name": "rick"}
31
+ You can use ERB to format each test case.
32
+ GET
33
+ api/users
34
+ {:id=>12}
35
+ {"id": 12, "name": "rick"}
36
+ You can use ERB to format each test case.
37
+ GET
38
+ api/zzz
39
+ {:id=>12}
40
+ {"id": 12, "name": "rick"}
41
+ You can use ERB to format each test case.
42
+ GET
43
+ api/aaa
44
+ {:id=>12}
45
+ {"id": 12, "name": "rick"}
46
+ You can use ERB to format each test case.
47
+ GET
48
+ api/zzz
49
+ {:id=>12}
50
+ {"id": 12, "name": "rick"}
51
+ You can use ERB to format each test case.
52
+ GET
53
+ api/users
54
+ {:id=>12}
55
+ {"id": 12, "name": "rick"}
56
+ You can use ERB to format each test case.
57
+ GET
58
+ api/users
59
+ {:id=>12}
60
+ {"id": 12, "name": "rick"}
61
+ You can use ERB to format each test case.
62
+ GET
63
+ api/aaa
64
+ {:id=>12}
65
+ {"id": 12, "name": "rick"}
66
+ You can use ERB to format each test case.
67
+ GET
68
+ api/zzz
69
+ {:id=>12}
70
+ {"id": 12, "name": "rick"}
71
+ You can use ERB to format each test case.
72
+ GET
73
+ api/aaa
74
+ {:id=>12}
75
+ {"id": 12, "name": "rick"}
76
+ You can use ERB to format each test case.
77
+ GET
78
+ api/zzz
79
+ {:id=>12}
80
+ {"id": 12, "name": "rick"}
data/lib/base.rb ADDED
@@ -0,0 +1,99 @@
1
+ class SmashingDocs
2
+ attr_accessor :tests
3
+ def initialize
4
+ @tests = []
5
+ @skip = false
6
+ @information = {}
7
+ end
8
+
9
+ def sort_by_url!
10
+ @tests.sort! do |x, y|
11
+ x.request.path <=> y.request.path
12
+ end
13
+ end
14
+
15
+ def clean_up!
16
+ @tests = []
17
+ end
18
+
19
+ def aside(msg)
20
+ @aside = ''
21
+ @aside = "<aside class='notice'>\n #{msg}\n</aside>"
22
+ end
23
+
24
+ def information(key, value)
25
+ @information[key] = value
26
+ end
27
+
28
+ def run!(request, response)
29
+ if @skip
30
+ @skip = false
31
+ return
32
+ end
33
+ add_test_case(request, response)
34
+ @information = {}
35
+ @skip = false
36
+ self
37
+ end
38
+
39
+ def add_test_case(request, response)
40
+ test = self.class::TestCase.new(request, response, @information, @aside)
41
+ test.template = self.class::Conf.template
42
+ self.tests << test
43
+ end
44
+
45
+ def skip
46
+ @skip = true
47
+ end
48
+
49
+ def output_testcases_to_file
50
+ docs = self.class::Conf.output_file
51
+ raise 'No output file specific for SmashingDocs' unless docs
52
+ File.delete docs if File.exists? docs
53
+ write_to_file
54
+ end
55
+
56
+ def write_to_file
57
+ File.open(self.class::Conf.output_file, 'a') do |file|
58
+ @tests.each do |test|
59
+ file.write(test.compile_template)
60
+ end
61
+ end
62
+ end
63
+
64
+ # = = = =
65
+ # These class methods are used to persist test data across tests
66
+ # RSpec and Minitest do not support hooks that would allow
67
+ # for an instance variable to be declared and used
68
+
69
+ def self.finish!
70
+ current.sort_by_url!
71
+ current.output_testcases_to_file
72
+ current.clean_up!
73
+ end
74
+
75
+ def self.run!(request, response)
76
+ current.run!(request, response)
77
+ end
78
+
79
+ def self.skip
80
+ current.skip
81
+ end
82
+
83
+ def self.information(key, value)
84
+ current.information(key, value)
85
+ end
86
+
87
+ def self.aside(message)
88
+ current.aside(message)
89
+ end
90
+
91
+ def self.current
92
+ # Behaves like an instance of SmashingDocs class
93
+ Thread.current[:instance] ||= self.new
94
+ end
95
+
96
+ def self.config(&block)
97
+ yield(self::Conf)
98
+ end
99
+ end
data/lib/conf.rb ADDED
@@ -0,0 +1,12 @@
1
+ class SmashingDocs::Conf
2
+ class << self
3
+ attr_accessor :template_file, :output_file
4
+
5
+ @output_file = 'documentation.md'
6
+
7
+ def template
8
+ raise 'You must set a template file.' unless template_file
9
+ @template ||= File.read(template_file)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ require 'base'
2
+ require 'conf'
3
+ require 'test_case'
4
+
data/lib/test_case.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'erb'
2
+
3
+ class SmashingDocs::TestCase
4
+ attr_reader :request, :response, :created_at, :information, :aside
5
+ attr_accessor :template
6
+
7
+ def initialize(request, response, information = {}, aside = '')
8
+ @request, @response, @information, @aside = request, response, information, aside
9
+ @created_at = Time.now
10
+ end
11
+
12
+ def compile_template
13
+ ERB.new(template).result binding
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.authors = ['Tyler Rockwell', 'Annie Baer', 'Rick Carlino']
5
+ s.description = "Write API documentation using existing controller tests."
6
+ s.files = `git ls-files`.split("\n")
7
+ s.homepage = 'https://github.com/smashingboxes/smashing_docs'
8
+ s.license = 'MIT'
9
+ s.name = 'smashing_docs'
10
+ s.require_paths = ['lib']
11
+ s.summary = "Uses your test cases to write example documentation for your API."
12
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+ s.version = '0.0.2'
14
+
15
+ s.add_development_dependency "bundler", "~> 1.11"
16
+ s.add_development_dependency "rake", "~> 10.0"
17
+ s.add_development_dependency "rspec", "~> 3.0"
18
+ end
data/spec/base_spec.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SmashingDocs do
4
+ let(:file) { SmashingDocs::Conf.output_file }
5
+ let(:first) { Request.new("GET", {id: 12}, 'api/aaa') }
6
+ let(:middle) { Request.new("GET", { id: 12 }, 'api/ooo') }
7
+ let(:last) { Request.new("GET", {id: 12}, 'api/zzz') }
8
+ let(:tests) { SmashingDocs.current.tests }
9
+
10
+ describe ".run!(request, response)" do
11
+ context "when no tests have been run" do
12
+ it "has done nothing" do
13
+ expect(tests.length).to eq(0)
14
+ end
15
+ end
16
+ context "running 1 test" do
17
+ it "adds the test to the list of tests" do
18
+ SmashingDocs.run!(request, response)
19
+ expect(tests.length).to eq(1)
20
+ expect(tests.first).to be_a(SmashingDocs::TestCase)
21
+ end
22
+ end
23
+ context "running 2 tests" do
24
+ it "adds both tests to the list of tests" do
25
+ 2.times { SmashingDocs.run!(request, response) }
26
+ expect(tests.length).to eq(2)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe ".sort!" do
32
+ let(:results) { SmashingDocs.current.sort_by_url!.map{|tc| tc.request.path} }
33
+ it "sorts tests alphabetically by endpoint" do
34
+ SmashingDocs.run!(first, response)
35
+ SmashingDocs.run!(last, response)
36
+ SmashingDocs.run!(middle, response)
37
+ expect(results).to eq(["api/aaa", "api/ooo", "api/zzz"])
38
+ end
39
+ end
40
+
41
+ describe ".finish!" do
42
+ it "creates the docs file with output from the template" do
43
+ SmashingDocs.run!(first, response)
44
+ SmashingDocs.run!(last, response)
45
+ SmashingDocs.finish!
46
+ expect(File).to exist(file)
47
+ expect(File.read(file)).to include("You can use ERB")
48
+ end
49
+ end
50
+
51
+ describe ".skip" do
52
+ context "one skip" do
53
+ it "skips a single test" do
54
+ SmashingDocs.skip
55
+ SmashingDocs.run!(first, response)
56
+ SmashingDocs.run!(last, response)
57
+ expect(tests.length).to eq(1)
58
+ expect(tests.first.request.path).to eq("api/zzz")
59
+ end
60
+ end
61
+ context "multiple skips" do
62
+ it "skips multiple tests" do
63
+ SmashingDocs.skip
64
+ SmashingDocs.run!(first, response)
65
+ SmashingDocs.skip
66
+ SmashingDocs.run!(middle, response)
67
+ SmashingDocs.run!(last, response)
68
+ expect(tests.length).to eq(1)
69
+ expect(tests.first.request.path).to eq("api/zzz")
70
+ end
71
+ end
72
+ end
73
+
74
+ describe ".information(key, value)" do
75
+ # The template file must have <%= information[:note] %>
76
+ it "sends information to be displayed about the endpoint" do
77
+ SmashingDocs.information(:note, "Endpoint note")
78
+ SmashingDocs.run!(first, response)
79
+ expect(tests.first.compile_template).to include("Endpoint note")
80
+ end
81
+ end
82
+
83
+ describe ".aside(message)" do
84
+ # The template file must have <%= information[:note] %>
85
+ it "sends information to be displayed about the endpoint" do
86
+ SmashingDocs.aside("I am an aside")
87
+ SmashingDocs.run!(first, response)
88
+ expect(tests.first.compile_template).to include("<aside class='notice'>")
89
+ expect(tests.first.compile_template).to include("I am an aside")
90
+ end
91
+ end
92
+ end
data/spec/conf_spec.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SmashingDocs::Conf do
4
+ let!(:config) {
5
+ SmashingDocs.config do |c|
6
+ c.template_file = "spec/template.md.erb"
7
+ c.output_file = "api_docs.md"
8
+ end
9
+ }
10
+ it "sets the template file" do
11
+ expect(SmashingDocs::Conf.output_file).to eq("api_docs.md")
12
+ end
13
+
14
+ it "sets the output file" do
15
+ expect(SmashingDocs::Conf.template_file).to eq("spec/template.md.erb")
16
+ end
17
+ end
File without changes
@@ -0,0 +1,7 @@
1
+ You can use ERB to format each test case.
2
+ <%= request.method %>
3
+ <%= request.path %>
4
+ <%= request.params %>
5
+ <%= response.body %>
6
+ <%= information[:note] %>
7
+ <%= aside %>
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'smashing_docs'
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
+ end
8
+ config.before(:each) do
9
+ SmashingDocs.config do |c|
10
+ c.template_file = 'spec/fake_template.md.erb'
11
+ c.output_file = 'spec/fake_output.md'
12
+ end
13
+ end
14
+ config.after(:each) do
15
+ SmashingDocs.finish!
16
+ end
17
+ end
18
+
19
+ # Include some fake structs that act like response/request objects.
20
+ Request = Struct.new :method, :params, :path
21
+ Response = Struct.new :body, :success?
22
+
23
+ def request
24
+ Request.new("GET", {id: 12}, 'api/users')
25
+ end
26
+
27
+ def response
28
+ Response.new('{"id": 12, "name": "rick"}', true)
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SmashingDocs::TestCase do
4
+ let(:test_case) { SmashingDocs::TestCase.new(request, response) }
5
+
6
+ describe "#compile_template" do
7
+ context "with text" do
8
+ let(:template) { "<%= 2 + 2 %>" }
9
+ it "evaluates erb and returns a value" do
10
+ test_case.template = template
11
+ expect(test_case.compile_template).to eq("4")
12
+ end
13
+ end
14
+
15
+ context "with a template file" do
16
+ let!(:template) { SmashingDocs.config { |c| c.template_file = 'spec/fake_template.md.erb' } }
17
+ it "sets the template file and returns docs matching the template" do
18
+ test_case.template = SmashingDocs::Conf.template
19
+ expect(test_case.compile_template).to include("use ERB")
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#created_at" do
25
+ it "returns the time the TestCase was created" do
26
+ expect(test_case.created_at).to be_a(Time)
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smashing_docs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tyler Rockwell
8
+ - Annie Baer
9
+ - Rick Carlino
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2016-02-18 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.11'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.11'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '10.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '3.0'
57
+ description: Write API documentation using existing controller tests.
58
+ email:
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - README.md
66
+ - Rakefile
67
+ - api_docs.md
68
+ - documentation.md
69
+ - lib/base.rb
70
+ - lib/conf.rb
71
+ - lib/smashing_docs.rb
72
+ - lib/test_case.rb
73
+ - smashing_docs.gemspec
74
+ - spec/base_spec.rb
75
+ - spec/conf_spec.rb
76
+ - spec/fake_output.md
77
+ - spec/fake_template.md.erb
78
+ - spec/spec_helper.rb
79
+ - spec/test_case_spec.rb
80
+ homepage: https://github.com/smashingboxes/smashing_docs
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.5
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Uses your test cases to write example documentation for your API.
104
+ test_files:
105
+ - spec/base_spec.rb
106
+ - spec/conf_spec.rb
107
+ - spec/fake_output.md
108
+ - spec/fake_template.md.erb
109
+ - spec/spec_helper.rb
110
+ - spec/test_case_spec.rb