rspec-documentation 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/Gemfile.lock +3 -3
- data/Makefile +9 -0
- data/README.md +17 -21
- data/exe/rspec-documentation +5 -1
- data/lib/rspec/documentation/version.rb +1 -1
- data/lib/rspec/documentation.rb +1 -51
- data/lib/rspec_documentation/configuration.rb +17 -4
- data/lib/rspec_documentation/document.rb +17 -5
- data/lib/rspec_documentation/documentation.rb +85 -0
- data/lib/rspec_documentation/formatters/ansi.rb +44 -0
- data/lib/rspec_documentation/formatters/html.rb +31 -0
- data/lib/rspec_documentation/formatters/json.rb +32 -0
- data/lib/rspec_documentation/formatters/ruby.rb +31 -0
- data/lib/rspec_documentation/formatters/yaml.rb +36 -0
- data/lib/rspec_documentation/formatters.rb +20 -0
- data/lib/rspec_documentation/html_element.rb +21 -18
- data/lib/rspec_documentation/javascript_bundle.rb +17 -0
- data/lib/rspec_documentation/page_collection.rb +24 -9
- data/lib/rspec_documentation/page_tree.rb +16 -8
- data/lib/rspec_documentation/page_tree_element.rb +31 -9
- data/lib/rspec_documentation/parsed_document.rb +5 -3
- data/lib/rspec_documentation/project_initialization.rb +52 -0
- data/lib/rspec_documentation/rspec/failure.rb +20 -5
- data/lib/rspec_documentation/rspec.rb +0 -2
- data/lib/rspec_documentation/spec.rb +58 -12
- data/lib/rspec_documentation/stylesheet_bundle.rb +17 -0
- data/lib/rspec_documentation/summary.rb +87 -0
- data/lib/rspec_documentation/util.rb +12 -0
- data/lib/rspec_documentation.rb +16 -3
- data/lib/templates/000-Introduction.md.erb +35 -0
- data/lib/templates/010-Usage.md.erb +3 -0
- data/lib/templates/500-License.md.erb +3 -0
- data/lib/templates/bootstrap.js.erb +7 -0
- data/lib/templates/footer.html.erb +5 -0
- data/lib/templates/header.html.erb +16 -3
- data/lib/templates/layout.css.erb +381 -2
- data/lib/templates/layout.html.erb +13 -82
- data/lib/templates/layout.js.erb +67 -0
- data/lib/templates/modal_spec.html.erb +51 -0
- data/lib/templates/moon.svg.erb +1 -0
- data/lib/templates/script_tags.html.erb +1 -0
- data/lib/templates/stylesheet_links.html.erb +1 -0
- data/lib/templates/sun.svg.erb +1 -0
- data/lib/templates/tabbed_spec.html.erb +12 -49
- data/lib/templates/themes/bootstrap.min.css +11 -0
- data/lib/templates/themes/cerulean.css +5 -6
- data/lib/templates/themes/cosmo.css +5 -6
- data/lib/templates/themes/cyborg.css +5 -6
- data/lib/templates/themes/darkly.css +5 -6
- data/lib/templates/themes/flatly.css +5 -6
- data/lib/templates/themes/journal.css +5 -6
- data/lib/templates/themes/litera.css +5 -6
- data/lib/templates/themes/lumen.css +5 -6
- data/lib/templates/themes/lux.css +5 -6
- data/lib/templates/themes/materia.css +5 -6
- data/lib/templates/themes/minty.css +5 -6
- data/lib/templates/themes/morph.css +5 -6
- data/lib/templates/themes/pulse.css +5 -6
- data/lib/templates/themes/quartz.css +5 -6
- data/lib/templates/themes/sandstone.css +5 -6
- data/lib/templates/themes/simplex.css +5 -6
- data/lib/templates/themes/sketchy.css +5 -6
- data/lib/templates/themes/slate.css +5 -6
- data/lib/templates/themes/solar.css +5 -6
- data/lib/templates/themes/spacelab.css +5 -6
- data/lib/templates/themes/superhero.css +5 -6
- data/lib/templates/themes/united.css +5 -6
- data/lib/templates/themes/vapor.css +5 -6
- data/lib/templates/themes/yeti.css +5 -6
- data/lib/templates/themes/zephyr.css +5 -6
- data/rspec-documentation/pages/000-Introduction/000-Quickstart.md +17 -0
- data/rspec-documentation/pages/000-Introduction.md +14 -30
- data/rspec-documentation/pages/010-File System/000-Ordering.md +1 -1
- data/rspec-documentation/pages/010-File System/010-Documentation Bundle.md +9 -0
- data/rspec-documentation/pages/010-File System.md +1 -1
- data/rspec-documentation/pages/020-Running Tests.md +41 -0
- data/rspec-documentation/pages/030-Examples/010-Basic.md +51 -0
- data/rspec-documentation/pages/030-Examples/020-HTML.md +45 -0
- data/rspec-documentation/pages/030-Examples/030-ANSI.md +33 -0
- data/rspec-documentation/pages/030-Examples/040-JSON.md +39 -0
- data/rspec-documentation/pages/030-Examples/050-YAML.md +40 -0
- data/rspec-documentation/pages/030-Examples.md +7 -0
- data/rspec-documentation/pages/040-Spec Helper.md +11 -0
- data/rspec-documentation/pages/050-Linking.md +20 -0
- data/rspec-documentation/pages/060-Configuration/010-Context.md +26 -0
- data/rspec-documentation/pages/060-Configuration/020-Build Paths.md +33 -0
- data/rspec-documentation/pages/060-Configuration/030-Attribution.md +23 -0
- data/rspec-documentation/pages/060-Configuration.md +13 -0
- data/rspec-documentation/pages/070-Publishing.md +13 -0
- data/rspec-documentation/pages/500-License.md +11 -0
- data/rspec-documentation/spec_helper.rb +8 -0
- data/rspec-documentation.gemspec +2 -1
- metadata +46 -12
- data/lib/rspec_documentation/ansi_html.rb +0 -28
- data/lib/rspec_documentation/context.rb +0 -44
- data/lib/rspec_documentation/rspec/example_group.rb +0 -26
- data/lib/rspec_documentation/rspec/reporter.rb +0 -45
- data/rspec-documentation/pages/010-File System/010-Standalone Directories.md +0 -17
- data/rspec-documentation/pages/010-File System/020-Standalone Directory/Example Page.md +0 -3
- data/rspec-documentation/pages/020-Running Specs.md +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a33d3b35a6feaea6cdb730424eabca522ee5592f7e944b9c751713b12c3c35d5
|
4
|
+
data.tar.gz: 90be4151f65ecb8e0e4a74f70c85cdae67df5d78ed31acd0cc2fa2c7da72a2f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f357c76176c0f5cc9a2061a51dfa3fceb59f05d75fe5173ed211dee64e1e4c07bb6309448757f1172f7b79f4b80f0c55c8fca99ca430eb17bb2b1766390ca1de
|
7
|
+
data.tar.gz: b5598da557e010fb880dd001297d5d7796f46b7f2f2e7bf39847eec33073402f852f14f8113474c3ba00f950ee5b53b20af2d259b584a0bd5fe23cac707591bb
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rspec-documentation (0.0.
|
4
|
+
rspec-documentation (0.0.4)
|
5
5
|
htmlbeautifier (~> 1.4)
|
6
6
|
kramdown (~> 2.4)
|
7
7
|
kramdown-parser-gfm (~> 1.1)
|
8
|
-
paintbrush (~> 0.1.
|
8
|
+
paintbrush (~> 0.1.3)
|
9
9
|
redcarpet (~> 3.6)
|
10
10
|
rouge (~> 4.1)
|
11
11
|
rspec (~> 3.12)
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
kramdown-parser-gfm (1.1.0)
|
27
27
|
kramdown (~> 2.0)
|
28
28
|
paint (2.3.0)
|
29
|
-
paintbrush (0.1.
|
29
|
+
paintbrush (0.1.3)
|
30
30
|
parallel (1.23.0)
|
31
31
|
parser (3.2.2.1)
|
32
32
|
ast (~> 2.4.1)
|
data/Makefile
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
+
project=rspec-documentation
|
2
|
+
|
1
3
|
.PHONY: test
|
2
4
|
test:
|
3
5
|
bundle exec rspec
|
4
6
|
bundle exec rubocop
|
5
7
|
bundle exec strong_versions
|
8
|
+
exe/rspec-documentation
|
9
|
+
|
10
|
+
.PHONY: publish
|
11
|
+
publish:
|
12
|
+
@RSPEC_DOCUMENTATION_URL_ROOT='/$(project)' exe/rspec-documentation
|
13
|
+
@rsync --delete -r rspec-documentation/bundle/ docs01.bob.frl:/mnt/docs/$(project)/
|
14
|
+
@echo 'Published.'
|
data/README.md
CHANGED
@@ -1,31 +1,27 @@
|
|
1
1
|
# RSpec::Documentation
|
2
2
|
|
3
|
-
|
3
|
+
_RSpec Documentation_ provides a simple but powerful system for generating _Ruby_ documentation using [_RSpec_](https://rspec.info/) designed to help you ensure that all code examples in your documentation really work.
|
4
4
|
|
5
|
-
|
5
|
+
* Create a tree of _Markdown_ files in your project directory under `rspec-documentation/pages/`.
|
6
|
+
* Embed tests in ```` ```rspec ```` code blocks (other output formatters are available - see examples).
|
7
|
+
* Define a `subject` for each test.
|
8
|
+
* Run the provided `rspec-documentation` command.
|
6
9
|
|
7
|
-
|
10
|
+
There is no _DSL_ to learn and vanilla _RSpec_ examples are used to generate inputs and outputs. No _Markdown_ language extensions are used, simply define the language of a fenced code block as `rspec` in any `.md` file and _RSpecDocumentation_ will do the rest.
|
8
11
|
|
9
|
-
|
12
|
+
## Quick Example
|
10
13
|
|
11
|
-
|
14
|
+
The following is an example _Markdown_ file.
|
12
15
|
|
13
|
-
|
16
|
+
````console
|
17
|
+
# An example test
|
14
18
|
|
15
|
-
|
19
|
+
This is a very simple test:
|
16
20
|
|
17
|
-
|
21
|
+
```rspec
|
22
|
+
subject { 'my subject' }
|
23
|
+
it { is_expected.to eql 'my subject' }
|
24
|
+
```
|
25
|
+
````
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
TODO: Write usage instructions here
|
22
|
-
|
23
|
-
## Development
|
24
|
-
|
25
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
26
|
-
|
27
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
28
|
-
|
29
|
-
## Contributing
|
30
|
-
|
31
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rspec-documentation.
|
27
|
+
View the [full documentation](https://docs.bob.frl/rspec-documentation) (built using Rspec Documentation!) for detailed usage instructions.
|
data/exe/rspec-documentation
CHANGED
data/lib/rspec/documentation.rb
CHANGED
@@ -11,63 +11,13 @@ module RSpec
|
|
11
11
|
class Error < StandardError; end
|
12
12
|
|
13
13
|
class << self
|
14
|
-
include Paintbrush
|
15
|
-
|
16
14
|
def generate_documentation
|
17
|
-
|
18
|
-
page_collection.generate
|
19
|
-
page_collection.flush unless failed?
|
20
|
-
print_summary
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def require_spec_helper
|
25
|
-
path = Pathname.new(Dir.pwd).join('rspec-documentation/spec_helper.rb')
|
26
|
-
require path if path.file?
|
15
|
+
RSpecDocumentation::Documentation.new.tap(&:generate)
|
27
16
|
end
|
28
17
|
|
29
18
|
def configure(&block)
|
30
19
|
RSpecDocumentation.configure(&block)
|
31
20
|
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def print_success_summary
|
36
|
-
warn(paintbrush { green("\n Created #{blue(page_paths.size)} pages.\n") })
|
37
|
-
warn(paintbrush { cyan(" View your documentation here: #{white(bundle_index_path)}\n") })
|
38
|
-
end
|
39
|
-
|
40
|
-
def print_failure_summary
|
41
|
-
page_collection.failures.each do |failure|
|
42
|
-
$stderr.write(failure.message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def bundle_index_path
|
47
|
-
RSpecDocumentation::Util.bundle_dir.glob('*.html').first.expand_path
|
48
|
-
end
|
49
|
-
|
50
|
-
def page_paths
|
51
|
-
@page_paths ||= Pathname.new(Dir.pwd).join('rspec-documentation/pages').glob('**/*.md')
|
52
|
-
end
|
53
|
-
|
54
|
-
def page_collection
|
55
|
-
@page_collection ||= RSpecDocumentation::PageCollection.new(page_paths: page_paths)
|
56
|
-
end
|
57
|
-
|
58
|
-
def failed?
|
59
|
-
!page_collection.failures.empty?
|
60
|
-
end
|
61
|
-
|
62
|
-
def print_summary
|
63
|
-
if failed?
|
64
|
-
print_failure_summary
|
65
|
-
else
|
66
|
-
print_success_summary
|
67
|
-
end
|
68
|
-
|
69
|
-
nil
|
70
|
-
end
|
71
21
|
end
|
72
22
|
end
|
73
23
|
end
|
@@ -4,12 +4,25 @@ module RSpecDocumentation
|
|
4
4
|
# Configures the rspec-documentation gem, allows setting a context that makes values available to each example.
|
5
5
|
class Configuration
|
6
6
|
def initialize
|
7
|
-
@
|
7
|
+
@context_defined = false
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
10
|
+
def context_defined?
|
11
|
+
@context_defined
|
12
|
+
end
|
13
|
+
|
14
|
+
def attribution
|
15
|
+
return @attribution if defined?(@attribution)
|
16
|
+
|
17
|
+
'Documentation generated by ' \
|
18
|
+
'<a target="_blank" href="https://github.com/bobf/rspec-documentation">rspec-documentation</a>'
|
19
|
+
end
|
20
|
+
|
21
|
+
def context(&block)
|
22
|
+
raise Error, 'RSpecDocumentation context has already been defined.' if context_defined?
|
23
|
+
|
24
|
+
@context_defined = true
|
25
|
+
::RSpec.shared_context('__rspec_documentation', &block)
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
@@ -5,8 +5,9 @@ module RSpecDocumentation
|
|
5
5
|
class Document
|
6
6
|
attr_reader :failures, :page_tree
|
7
7
|
|
8
|
-
def initialize(document:, page_tree:)
|
8
|
+
def initialize(document:, path:, page_tree:)
|
9
9
|
@document = document
|
10
|
+
@path = path
|
10
11
|
@page_tree = page_tree
|
11
12
|
@failures = []
|
12
13
|
end
|
@@ -30,14 +31,17 @@ module RSpecDocumentation
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def title
|
33
|
-
|
34
|
-
gem_spec&.name
|
34
|
+
gem_spec&.name || 'Documentation'
|
35
35
|
end
|
36
36
|
|
37
37
|
def version
|
38
38
|
gem_spec&.version
|
39
39
|
end
|
40
40
|
|
41
|
+
def homepage
|
42
|
+
gem_spec&.homepage
|
43
|
+
end
|
44
|
+
|
41
45
|
def header
|
42
46
|
RSpecDocumentation.template('header').result(binding)
|
43
47
|
end
|
@@ -46,12 +50,20 @@ module RSpecDocumentation
|
|
46
50
|
RSpecDocumentation.template('footer').result(binding)
|
47
51
|
end
|
48
52
|
|
53
|
+
def stylesheet_bundle_href
|
54
|
+
Util.assets_root.join('bundle.css')
|
55
|
+
end
|
56
|
+
|
57
|
+
def javascript_bundle_src
|
58
|
+
Util.assets_root.join('bundle.js')
|
59
|
+
end
|
60
|
+
|
49
61
|
private
|
50
62
|
|
51
|
-
attr_reader :document
|
63
|
+
attr_reader :document, :path
|
52
64
|
|
53
65
|
def parsed_document
|
54
|
-
@parsed_document ||= ParsedDocument.new(document)
|
66
|
+
@parsed_document ||= ParsedDocument.new(document, path: path)
|
55
67
|
end
|
56
68
|
|
57
69
|
def gem_spec
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
# Generates documentation from Markdown files, main entry point to documentation generator.
|
5
|
+
class Documentation
|
6
|
+
include Paintbrush
|
7
|
+
|
8
|
+
def generate
|
9
|
+
initialize_if_empty
|
10
|
+
start
|
11
|
+
require_spec_helper
|
12
|
+
ensure_context
|
13
|
+
page_collection.generate
|
14
|
+
flush unless failed?
|
15
|
+
summary.flush
|
16
|
+
rescue RSpecDocumentation::MissingFileError => e
|
17
|
+
warn(paintbrush { red e.message })
|
18
|
+
@failed = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def failed?
|
22
|
+
@failed || !page_collection.failures.empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def require_spec_helper
|
28
|
+
path = pwd.join('rspec-documentation/spec_helper.rb')
|
29
|
+
require path if path.file?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Ensure `__rspec_documentation` shared context is always defined.
|
33
|
+
# See lib/rspec_documenation/spec.rb
|
34
|
+
def ensure_context
|
35
|
+
return if RSpecDocumentation.configuration.context_defined?
|
36
|
+
|
37
|
+
RSpecDocumentation.configuration.context {} # rubocop:disable Lint/EmptyBlock
|
38
|
+
end
|
39
|
+
|
40
|
+
def start
|
41
|
+
warn(paintbrush { white "\nRunning specs..." })
|
42
|
+
@started_at = Time.now.utc
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize_if_empty
|
46
|
+
return if Util.base_dir.exist?
|
47
|
+
|
48
|
+
ProjectInitialization.new.flush
|
49
|
+
end
|
50
|
+
|
51
|
+
def summary
|
52
|
+
@summary ||= RSpecDocumentation::Summary.new(
|
53
|
+
page_collection: page_collection,
|
54
|
+
pwd: pwd,
|
55
|
+
started_at: @started_at
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def flush
|
60
|
+
page_collection.flush
|
61
|
+
stylesheet_bundle.flush
|
62
|
+
javascript_bundle.flush
|
63
|
+
end
|
64
|
+
|
65
|
+
def stylesheet_bundle
|
66
|
+
@stylesheet_bundle ||= RSpecDocumentation::StylesheetBundle.new
|
67
|
+
end
|
68
|
+
|
69
|
+
def javascript_bundle
|
70
|
+
@javascript_bundle ||= RSpecDocumentation::JavascriptBundle.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def page_paths
|
74
|
+
@page_paths ||= pwd.join('rspec-documentation/pages').glob('**/*.md')
|
75
|
+
end
|
76
|
+
|
77
|
+
def page_collection
|
78
|
+
@page_collection ||= RSpecDocumentation::PageCollection.new(page_paths: page_paths)
|
79
|
+
end
|
80
|
+
|
81
|
+
def pwd
|
82
|
+
@pwd ||= Pathname.new(Dir.pwd)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
module Formatters
|
5
|
+
COLOR_CODES = [0, 1, 2, 3, 4, 5, 6, 7, 9].freeze
|
6
|
+
|
7
|
+
# Outputs a string containing ANSI color code escape sequences into HTML with attached
|
8
|
+
# classes for each matched color code. Cleans any remaining escape codes.
|
9
|
+
class Ansi
|
10
|
+
def initialize(subject:)
|
11
|
+
@subject = subject
|
12
|
+
end
|
13
|
+
|
14
|
+
def prettified_output
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def rendered_output
|
19
|
+
"<div class='ansi-html border m-1 p-4'><span>#{subbed_content}</span></div>"
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_raw?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :subject
|
29
|
+
|
30
|
+
def subbed_content
|
31
|
+
COLOR_CODES.reduce(subbed_hex_codes) do |string, color_code|
|
32
|
+
string&.gsub("\e[3#{color_code}m", "</span><span class='ansi-color-#{color_code}'>")
|
33
|
+
&.gsub("\e[9#{color_code}m", "</span><span class='ansi-bright ansi-color-#{color_code}'>")
|
34
|
+
&.gsub(/\e\[38;5;([0-9]{1,3})m/, "</span><span class='ansi-color-\\1'>")
|
35
|
+
&.gsub("\e[0m", "</span><span class='ansi-color-reset'>")
|
36
|
+
end&.gsub(/\e\[[0-9;]+m/, '')
|
37
|
+
end
|
38
|
+
|
39
|
+
def subbed_hex_codes
|
40
|
+
subject&.gsub(/\e\[38;2;([0-9]+);([0-9]+);([0-9]+)m/, '</span><span style="color: rgb(\1,\2,\3)">')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
module Formatters
|
5
|
+
# Beautifies HTML received from a `subject`, renders the raw subject to be inserted directly
|
6
|
+
# into the output document.
|
7
|
+
class Html
|
8
|
+
def initialize(subject:)
|
9
|
+
@subject = subject
|
10
|
+
end
|
11
|
+
|
12
|
+
def prettified_output
|
13
|
+
formatter = Rouge::Formatters::HTML.new
|
14
|
+
lexer = Rouge::Lexers::HTML.new
|
15
|
+
formatter.format(lexer.lex(HtmlBeautifier.beautify(subject)))
|
16
|
+
end
|
17
|
+
|
18
|
+
def rendered_output
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_raw?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :subject
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
module Formatters
|
5
|
+
# Produces prettified JSON to from an RSpec `subject` value.
|
6
|
+
class Json
|
7
|
+
def initialize(subject:)
|
8
|
+
@subject = subject
|
9
|
+
end
|
10
|
+
|
11
|
+
def prettified_output
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def rendered_output
|
16
|
+
formatter = Rouge::Formatters::HTML.new
|
17
|
+
lexer = Rouge::Lexers::JSON.new
|
18
|
+
formatter.format(lexer.lex(JSON.pretty_generate(JSON.parse(subject))))
|
19
|
+
rescue JSON::ParserError => e
|
20
|
+
raise Error, "Expected JSON for:\n#{subject}\n\nParser Error: #{e}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_raw?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :subject
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
module Formatters
|
5
|
+
# Default formatter for all RSpec examples. Used by all examples to generate the "Spec" tab
|
6
|
+
# content, i.e. the original source of the example code.
|
7
|
+
class Ruby
|
8
|
+
def initialize(subject:)
|
9
|
+
@subject = subject
|
10
|
+
end
|
11
|
+
|
12
|
+
def prettified_output
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def rendered_output
|
17
|
+
formatter = Rouge::Formatters::HTML.new
|
18
|
+
lexer = Rouge::Lexers::Ruby.new
|
19
|
+
formatter.format(lexer.lex(subject.inspect))
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_raw?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :subject
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
module Formatters
|
5
|
+
# Produces prettified YAML to from an RSpec `subject` value.
|
6
|
+
class Yaml
|
7
|
+
def initialize(subject:)
|
8
|
+
@subject = subject
|
9
|
+
end
|
10
|
+
|
11
|
+
def prettified_output
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def rendered_output
|
16
|
+
formatter = Rouge::Formatters::HTML.new
|
17
|
+
lexer = Rouge::Lexers::YAML.new
|
18
|
+
formatter.format(lexer.lex(YAML.safe_load(subject, permitted_classes: permitted_classes).to_yaml))
|
19
|
+
rescue Psych::SyntaxError => e
|
20
|
+
raise Error, "Expected YAML for:\n#{subject}\n\nSyntax Error: #{e}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_raw?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :subject
|
30
|
+
|
31
|
+
def permitted_classes
|
32
|
+
[Symbol, Date, Time, DateTime]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'formatters/ruby'
|
4
|
+
require_relative 'formatters/html'
|
5
|
+
require_relative 'formatters/ansi'
|
6
|
+
require_relative 'formatters/json'
|
7
|
+
require_relative 'formatters/yaml'
|
8
|
+
|
9
|
+
module RSpecDocumentation
|
10
|
+
# Provides a set of formatters for rendering the value of a `subject` in an RSpec example into
|
11
|
+
# a useful format according to the language specified in the relevant Markdown code block, e.g.
|
12
|
+
# `rspec:html` will use the `Html` formatter to render beautified HTML source and the rendered
|
13
|
+
# output.
|
14
|
+
module Formatters
|
15
|
+
def self.with_translated_html_entities(content)
|
16
|
+
content&.gsub("\n", '<br/>')
|
17
|
+
&.gsub(' ', ' ')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -14,24 +14,24 @@ module RSpecDocumentation
|
|
14
14
|
Kramdown::Document.new(tabbed_spec, input: 'html').root
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
return nil unless spec.format == :html
|
19
|
-
|
17
|
+
def code_source
|
20
18
|
formatter = Rouge::Formatters::HTML.new
|
21
|
-
lexer = Rouge::Lexers::
|
22
|
-
|
23
|
-
formatter.format(lexer.lex(HtmlBeautifier.beautify(spec.described_object)))
|
19
|
+
lexer = Rouge::Lexers::Ruby.new
|
20
|
+
Formatters.with_translated_html_entities(formatter.format(lexer.lex(spec.source)))
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
27
|
-
|
23
|
+
def prettified_output
|
24
|
+
Formatters.with_translated_html_entities(formatter.prettified_output)
|
28
25
|
end
|
29
26
|
|
30
|
-
def
|
31
|
-
return
|
32
|
-
|
27
|
+
def rendered_output
|
28
|
+
return formatter.rendered_output if render_raw?
|
29
|
+
|
30
|
+
Formatters.with_translated_html_entities(formatter.rendered_output)
|
31
|
+
end
|
33
32
|
|
34
|
-
|
33
|
+
def render_raw?
|
34
|
+
formatter.render_raw?
|
35
35
|
end
|
36
36
|
|
37
37
|
def element_id
|
@@ -42,14 +42,17 @@ module RSpecDocumentation
|
|
42
42
|
|
43
43
|
attr_reader :spec
|
44
44
|
|
45
|
-
def
|
46
|
-
|
45
|
+
def formatter
|
46
|
+
@formatter ||= {
|
47
|
+
html: Formatters::Html,
|
48
|
+
ansi: Formatters::Ansi,
|
49
|
+
json: Formatters::Json,
|
50
|
+
yaml: Formatters::Yaml
|
51
|
+
}.fetch(spec.format, Formatters::Ruby).new(subject: spec.subject)
|
47
52
|
end
|
48
53
|
|
49
|
-
def
|
50
|
-
|
51
|
-
lexer = Rouge::Lexers::Ruby.new
|
52
|
-
formatter.format(lexer.lex(code))
|
54
|
+
def tabbed_spec
|
55
|
+
RSpecDocumentation.template('tabbed_spec').result(binding)
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecDocumentation
|
4
|
+
# Compiles Javascript assets into a single file.
|
5
|
+
class JavascriptBundle
|
6
|
+
def flush
|
7
|
+
Util.bundle_dir.join('assets').mkpath
|
8
|
+
javascript_bundle_path.write(RSpecDocumentation.template(:layout, :js).result(binding))
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def javascript_bundle_path
|
14
|
+
Util.bundle_dir.join('assets/bundle.js')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|