rspec-documentation 0.0.1 → 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/.rspec +1 -0
- data/.rubocop.yml +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +25 -2
- data/Makefile +9 -0
- data/README.md +18 -22
- data/Rakefile +1 -0
- data/exe/rspec-documentation +17 -0
- data/lib/rspec/documentation/version.rb +2 -2
- data/lib/rspec/documentation.rb +15 -2
- data/lib/rspec_documentation/configuration.rb +28 -0
- data/lib/rspec_documentation/document.rb +75 -0
- 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 +58 -0
- data/lib/rspec_documentation/javascript_bundle.rb +17 -0
- data/lib/rspec_documentation/markdown_renderer.rb +7 -0
- data/lib/rspec_documentation/page_collection.rb +64 -0
- data/lib/rspec_documentation/page_tree.rb +81 -0
- data/lib/rspec_documentation/page_tree_element.rb +78 -0
- data/lib/rspec_documentation/parsed_document.rb +72 -0
- data/lib/rspec_documentation/project_initialization.rb +52 -0
- data/lib/rspec_documentation/rspec/failure.rb +52 -0
- data/lib/rspec_documentation/rspec.rb +12 -0
- data/lib/rspec_documentation/spec.rb +108 -0
- data/lib/rspec_documentation/stylesheet_bundle.rb +17 -0
- data/lib/rspec_documentation/summary.rb +87 -0
- data/lib/rspec_documentation/util.rb +58 -0
- data/lib/rspec_documentation.rb +71 -0
- data/lib/tasks/rspec/documentation/generate.rake +10 -0
- 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 +6 -0
- data/lib/templates/header.html.erb +20 -0
- data/lib/templates/layout.css.erb +418 -0
- data/lib/templates/layout.html.erb +31 -0
- 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 +82 -0
- data/lib/templates/themes/bootstrap.min.css +11 -0
- data/lib/templates/themes/cerulean.css +11 -0
- data/lib/templates/themes/cosmo.css +11 -0
- data/lib/templates/themes/cyborg.css +11 -0
- data/lib/templates/themes/darkly.css +11 -0
- data/lib/templates/themes/flatly.css +11 -0
- data/lib/templates/themes/journal.css +11 -0
- data/lib/templates/themes/litera.css +11 -0
- data/lib/templates/themes/lumen.css +11 -0
- data/lib/templates/themes/lux.css +11 -0
- data/lib/templates/themes/materia.css +11 -0
- data/lib/templates/themes/minty.css +11 -0
- data/lib/templates/themes/morph.css +11 -0
- data/lib/templates/themes/pulse.css +11 -0
- data/lib/templates/themes/quartz.css +11 -0
- data/lib/templates/themes/sandstone.css +11 -0
- data/lib/templates/themes/simplex.css +11 -0
- data/lib/templates/themes/sketchy.css +11 -0
- data/lib/templates/themes/slate.css +11 -0
- data/lib/templates/themes/solar.css +11 -0
- data/lib/templates/themes/spacelab.css +11 -0
- data/lib/templates/themes/superhero.css +11 -0
- data/lib/templates/themes/united.css +11 -0
- data/lib/templates/themes/vapor.css +11 -0
- data/lib/templates/themes/yeti.css +11 -0
- data/lib/templates/themes/zephyr.css +11 -0
- data/rspec-documentation/pages/000-Introduction/000-Quickstart.md +17 -0
- data/rspec-documentation/pages/000-Introduction.md +23 -0
- data/rspec-documentation/pages/010-File System/000-Ordering.md +14 -0
- data/rspec-documentation/pages/010-File System/010-Documentation Bundle.md +9 -0
- data/rspec-documentation/pages/010-File System.md +26 -0
- 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 +10 -1
- data/sig/rspec/documentation.rbs +1 -1
- metadata +193 -5
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/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rspec-documentation (0.0.
|
|
4
|
+
rspec-documentation (0.0.3)
|
|
5
|
+
htmlbeautifier (~> 1.4)
|
|
6
|
+
kramdown (~> 2.4)
|
|
7
|
+
kramdown-parser-gfm (~> 1.1)
|
|
8
|
+
paintbrush (~> 0.1.3)
|
|
9
|
+
redcarpet (~> 3.6)
|
|
10
|
+
rouge (~> 4.1)
|
|
11
|
+
rspec (~> 3.12)
|
|
5
12
|
|
|
6
13
|
GEM
|
|
7
14
|
remote: https://rubygems.org/
|
|
8
15
|
specs:
|
|
9
16
|
ast (2.4.2)
|
|
10
17
|
concurrent-ruby (1.2.2)
|
|
18
|
+
devpack (0.4.1)
|
|
11
19
|
diff-lcs (1.5.0)
|
|
20
|
+
htmlbeautifier (1.4.2)
|
|
12
21
|
i18n (1.13.0)
|
|
13
22
|
concurrent-ruby (~> 1.0)
|
|
14
23
|
json (2.6.3)
|
|
24
|
+
kramdown (2.4.0)
|
|
25
|
+
rexml
|
|
26
|
+
kramdown-parser-gfm (1.1.0)
|
|
27
|
+
kramdown (~> 2.0)
|
|
15
28
|
paint (2.3.0)
|
|
29
|
+
paintbrush (0.1.3)
|
|
16
30
|
parallel (1.23.0)
|
|
17
31
|
parser (3.2.2.1)
|
|
18
32
|
ast (~> 2.4.1)
|
|
19
33
|
rainbow (3.1.1)
|
|
20
34
|
rake (13.0.6)
|
|
35
|
+
redcarpet (3.6.0)
|
|
21
36
|
regexp_parser (2.8.0)
|
|
22
37
|
rexml (3.2.5)
|
|
38
|
+
rouge (4.1.1)
|
|
23
39
|
rspec (3.12.0)
|
|
24
40
|
rspec-core (~> 3.12.0)
|
|
25
41
|
rspec-expectations (~> 3.12.0)
|
|
@@ -29,6 +45,11 @@ GEM
|
|
|
29
45
|
rspec-expectations (3.12.3)
|
|
30
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
31
47
|
rspec-support (~> 3.12.0)
|
|
48
|
+
rspec-file_fixtures (0.1.6)
|
|
49
|
+
rspec (~> 3.0)
|
|
50
|
+
rspec-its (1.3.0)
|
|
51
|
+
rspec-core (>= 3.0.0)
|
|
52
|
+
rspec-expectations (>= 3.0.0)
|
|
32
53
|
rspec-mocks (3.12.5)
|
|
33
54
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
34
55
|
rspec-support (~> 3.12.0)
|
|
@@ -62,13 +83,15 @@ GEM
|
|
|
62
83
|
unicode-display_width (2.4.2)
|
|
63
84
|
|
|
64
85
|
PLATFORMS
|
|
65
|
-
ruby
|
|
66
86
|
x86_64-linux
|
|
67
87
|
|
|
68
88
|
DEPENDENCIES
|
|
89
|
+
devpack (~> 0.4.1)
|
|
69
90
|
rake (~> 13.0)
|
|
70
91
|
rspec (~> 3.0)
|
|
71
92
|
rspec-documentation!
|
|
93
|
+
rspec-file_fixtures (~> 0.1.6)
|
|
94
|
+
rspec-its (~> 1.3)
|
|
72
95
|
rubocop (~> 1.51)
|
|
73
96
|
rubocop-rake (~> 0.6.0)
|
|
74
97
|
rubocop-rspec (~> 2.22)
|
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/Rakefile
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/rspec/documentation'
|
|
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
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'documentation/version'
|
|
4
|
+
require_relative '../rspec_documentation'
|
|
5
|
+
load File.expand_path(File.join(__dir__, '../tasks/rspec/documentation/generate.rake'))
|
|
4
6
|
|
|
5
|
-
module
|
|
7
|
+
module RSpec
|
|
8
|
+
# Extension for RSpec, locates RSpec examples found in a Markdown file and executes them,
|
|
9
|
+
# replacing their output into a tree of Markdown files.
|
|
6
10
|
module Documentation
|
|
7
11
|
class Error < StandardError; end
|
|
8
|
-
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def generate_documentation
|
|
15
|
+
RSpecDocumentation::Documentation.new.tap(&:generate)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def configure(&block)
|
|
19
|
+
RSpecDocumentation.configure(&block)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
9
22
|
end
|
|
10
23
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RSpecDocumentation
|
|
4
|
+
# Configures the rspec-documentation gem, allows setting a context that makes values available to each example.
|
|
5
|
+
class Configuration
|
|
6
|
+
def initialize
|
|
7
|
+
@context_defined = false
|
|
8
|
+
end
|
|
9
|
+
|
|
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)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RSpecDocumentation
|
|
4
|
+
# Translates a Markdown document into a structure of parsed Markdown and embedded RSpec examples.
|
|
5
|
+
class Document
|
|
6
|
+
attr_reader :failures, :page_tree
|
|
7
|
+
|
|
8
|
+
def initialize(document:, path:, page_tree:)
|
|
9
|
+
@document = document
|
|
10
|
+
@path = path
|
|
11
|
+
@page_tree = page_tree
|
|
12
|
+
@failures = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def specs
|
|
16
|
+
@specs ||= parsed_document.specs
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def render
|
|
20
|
+
parsed_document.execute_and_substitute_examples!
|
|
21
|
+
if parsed_document.failures.empty?
|
|
22
|
+
RSpecDocumentation.template('layout').result(binding)
|
|
23
|
+
else
|
|
24
|
+
failures.concat(parsed_document.failures)
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def html
|
|
30
|
+
parsed_document.html
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def title
|
|
34
|
+
return ::Rails.application.class.module_parent.name.titleize if defined?(::Rails)
|
|
35
|
+
|
|
36
|
+
gem_spec&.name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def version
|
|
40
|
+
gem_spec&.version
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def homepage
|
|
44
|
+
gem_spec&.homepage
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def header
|
|
48
|
+
RSpecDocumentation.template('header').result(binding)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def footer
|
|
52
|
+
RSpecDocumentation.template('footer').result(binding)
|
|
53
|
+
end
|
|
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
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
attr_reader :document, :path
|
|
66
|
+
|
|
67
|
+
def parsed_document
|
|
68
|
+
@parsed_document ||= ParsedDocument.new(document, path: path)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def gem_spec
|
|
72
|
+
@gem_spec ||= Gem::Specification.load(Pathname.new(Dir.pwd).glob('*.gemspec').first.to_s)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -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
|