rspec-documentation 0.0.2 → 0.0.3
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 +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 +13 -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 +18 -4
- 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: a964ddab12c98c8913f741374a4206eaff591787f10e692417d9cf097fd2fe45
|
|
4
|
+
data.tar.gz: 5dd25967d474700f60118b12649906f072bf912a173651bcf5ea1e70889c7ecb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1923b974e68f71be19dfeddc8379d242c54c3ce69770490399237897d46672177c15fa4990260bef4442414746e273e2e1f0764b67ac134a28c4d2c0a2336b09
|
|
7
|
+
data.tar.gz: 5f25067b064fa2acca91e6b82a45d1bf5218005885262b638589b0a94b746daf9c2c7da21b34b64865cec1e3d924c5f960adc30505c5ced25a146059c4a10bd6
|
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.3)
|
|
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
|
@@ -2,4 +2,16 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require_relative '../lib/rspec/documentation'
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
# Try to load Rails and config/environment.rb, but don't panic if not present, we only use Rails
|
|
7
|
+
# to fetch things like application name etc.
|
|
8
|
+
begin
|
|
9
|
+
require 'rails'
|
|
10
|
+
require Pathname.new(Dir.pwd).join('config/environment')
|
|
11
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
documentation = RSpec::Documentation.generate_documentation
|
|
15
|
+
|
|
16
|
+
exit 1 if documentation.failed?
|
|
17
|
+
exit 0
|
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,7 +31,8 @@ module RSpecDocumentation
|
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def title
|
|
33
|
-
|
|
34
|
+
return ::Rails.application.class.module_parent.name.titleize if defined?(::Rails)
|
|
35
|
+
|
|
34
36
|
gem_spec&.name
|
|
35
37
|
end
|
|
36
38
|
|
|
@@ -38,6 +40,10 @@ module RSpecDocumentation
|
|
|
38
40
|
gem_spec&.version
|
|
39
41
|
end
|
|
40
42
|
|
|
43
|
+
def homepage
|
|
44
|
+
gem_spec&.homepage
|
|
45
|
+
end
|
|
46
|
+
|
|
41
47
|
def header
|
|
42
48
|
RSpecDocumentation.template('header').result(binding)
|
|
43
49
|
end
|
|
@@ -46,12 +52,20 @@ module RSpecDocumentation
|
|
|
46
52
|
RSpecDocumentation.template('footer').result(binding)
|
|
47
53
|
end
|
|
48
54
|
|
|
55
|
+
def stylesheet_bundle_href
|
|
56
|
+
Util.assets_root.join('bundle.css')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def javascript_bundle_src
|
|
60
|
+
Util.assets_root.join('bundle.js')
|
|
61
|
+
end
|
|
62
|
+
|
|
49
63
|
private
|
|
50
64
|
|
|
51
|
-
attr_reader :document
|
|
65
|
+
attr_reader :document, :path
|
|
52
66
|
|
|
53
67
|
def parsed_document
|
|
54
|
-
@parsed_document ||= ParsedDocument.new(document)
|
|
68
|
+
@parsed_document ||= ParsedDocument.new(document, path: path)
|
|
55
69
|
end
|
|
56
70
|
|
|
57
71
|
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
|