showcase-rails 0.2.3 → 0.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '081d707dee9578e786c17cb621826f685bf2a4f9eab5221037b2394ac3b6805b'
4
- data.tar.gz: 46fad2bf9b84aba2bf22bf0a627eb225ee904cd67da55cda4c0690b34d8d5a07
3
+ metadata.gz: bf778403a9352a0351175e44992b887820d5336c211e2d3dcfa6975b27240bf3
4
+ data.tar.gz: aea48794945648e9681c3fa345d5503b99aebb81f4c49d6e527bbc13f38f7da6
5
5
  SHA512:
6
- metadata.gz: 480d2d5a3c891703603caec5131d3990e19d31c97e815c622d8c6152ec2c1519a430e55416fc63caab1d7f136dd0fe96bf9e45a39bbf854e39134339822f6157
7
- data.tar.gz: d35a92bd276b05225cdb827a9d3ec832665e1b0978b2ec02294ecc3d0810fee926fbb5f58d989612177ebe879d833ea8a476057efa04ca845d5e3e2b1808694a
6
+ metadata.gz: e44e0daed1d4d76efacfd3f261a815ff5a5920335baf2318adea7a72f307c02d45b923905ceca8e6c0d45f179eba3761f7151ed06679a0075cc686fa73f8b6f2
7
+ data.tar.gz: 845ffb9426a6d1de5892cad9cad0a0bffd06d54a238767115d37f7c68d3643aa6e6eaa4c6308106b7cd071014e0be7faeb52e2d89952b66b5dc841a2df0823cf
data/README.md CHANGED
@@ -54,11 +54,34 @@ if defined?(Showcase)
54
54
  end
55
55
  ```
56
56
 
57
- ## Automatic integration testing
57
+ ## Automatic previews testing
58
58
 
59
- Showcase automatically runs integration tests for all your Showcases by rendering them and asserting they respond with `200 OK`. As long as `gem "showcase-rails"` is in the `:test` group you're set.
59
+ Showcase can automatically generate tests for all your Showcases to have it executed in your CI setup, run `bin/rails showcase:install:previews_test` to set this up.
60
60
 
61
- If you want to tweak this, run `bin/rails showcase:install:integration_test` and open `test/integration/showcase_test.rb`. You can then add your own `setup` and `teardown` hooks, as well as override the provided `assert_showcase_preview` to add custom assertions.
61
+ You can then open `test/views/showcase_test.rb` and add your own `setup` and `teardown` hooks, as well as override the provided `assert_showcase_preview` to add custom assertions.
62
+
63
+ If you need custom assertions for specific previews and their samples, you can use the `test` helper:
64
+
65
+ ```ruby
66
+ # test/views/showcase_test.rb
67
+ require "test_helper"
68
+
69
+ class ShowcaseTest < Showcase::PreviewsTest
70
+ test showcase: "combobox" do
71
+ # This test block runs within the #combobox container element.
72
+ assert_text "This is a combobox, for sure."
73
+ end
74
+
75
+ test showcase: "button", id: "basic" do
76
+ # This test block runs within the #button container element's #basic sample.
77
+ assert_button class: ["text-xs"]
78
+ end
79
+
80
+ test "some non-Showcase test" do
81
+ # You can still use the regular Rails `test` method too.
82
+ end
83
+ end
84
+ ```
62
85
 
63
86
  ## View examples
64
87
 
@@ -95,7 +118,7 @@ copy the file from our repo `app/views` directory into your `app/views` director
95
118
 
96
119
  ### Loading your own assets
97
120
 
98
- Showcase bundles its own `showcase.js` and `showcase.css` asset files through
121
+ Showcase bundles its own `showcase.js`, `showcase.css` and `showcase.highlights.css` asset files through
99
122
  Action View's [javascript_include_tag][] and [stylesheet_link_tag][].
100
123
 
101
124
  If your assets require more sophisticated loading techniques, declare your own
@@ -103,12 +126,24 @@ versions of the [showcase/engine/_javascripts.html.erb][] and
103
126
  [showcase/engine/_stylesheets.html.erb][] partials. When customizing those
104
127
  partials, make sure to include `"showcase"` in your list of assets.
105
128
 
106
-
107
129
  [javascript_include_tag]: https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-javascript_include_tag
108
130
  [stylesheet_link_tag]: https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-stylesheet_link_tag
109
131
  [showcase/engine/_javascripts.html.erb]: ./showcase/engine/_javascripts.html.erb
110
132
  [showcase/engine/_stylesheets.html.erb]: ./showcase/engine/_stylesheets.html.erb
111
133
 
134
+ #### Loading your own syntax highlighting theme
135
+
136
+ By default, Showcase's syntax highlighting runs on Rouge's "github" theme.
137
+
138
+ To use a different theme, override [showcase/engine/_stylesheets.html.erb][] with the following, replacing `:magritte` with a [valid theme](rouge-themes):
139
+
140
+ ```erb
141
+ <%= stylesheet_link_tag "application", "showcase" %> # We've removed the default showcase.highlights file here.
142
+ <%= tag.style Rouge::Theme.find(:magritte).render(scope: ".sc-highlight") %>
143
+ ```
144
+
145
+ [rouge-themes]: https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes
146
+
112
147
  ## Installation
113
148
 
114
149
  Add this line to your application's Gemfile. To get the automatic integration testing make sure the `showcase-rails` gem is available to your test environment:
@@ -129,6 +164,12 @@ Or install it yourself as:
129
164
  $ gem install showcase-rails
130
165
  ```
131
166
 
167
+ Then add the following in your `config/routes.rb` within the block passed to `Rails.application.routes.draw`:
168
+
169
+ ```ruby
170
+ mount Showcase::Engine, at: "/docs/showcase" if defined?(Showcase::Engine)
171
+ ```
172
+
132
173
  ## Contributing
133
174
  Contribution directions go here.
134
175
 
@@ -985,6 +985,14 @@ select {
985
985
  background-color: rgb(238 242 255 / var(--tw-bg-opacity));
986
986
  }
987
987
 
988
+ .hover\:sc-text-inherit:hover {
989
+ color: inherit;
990
+ }
991
+
992
+ .hover\:sc-no-underline:hover {
993
+ text-decoration-line: none;
994
+ }
995
+
988
996
  @media (min-width: 768px) {
989
997
  .md\:sc-text-lg {
990
998
  font-size: 1.125rem;
@@ -0,0 +1,112 @@
1
+ .sc-highlight table td { padding: 5px; }
2
+ .sc-highlight table pre { margin: 0; }
3
+ .sc-highlight, .sc-highlight .w {
4
+ color: #24292f;
5
+ background-color: #f6f8fa;
6
+ }
7
+ .sc-highlight .k, .sc-highlight .kd, .sc-highlight .kn, .sc-highlight .kp, .sc-highlight .kr, .sc-highlight .kt, .sc-highlight .kv {
8
+ color: #cf222e;
9
+ }
10
+ .sc-highlight .gr {
11
+ color: #f6f8fa;
12
+ }
13
+ .sc-highlight .gd {
14
+ color: #82071e;
15
+ background-color: #ffebe9;
16
+ }
17
+ .sc-highlight .nb {
18
+ color: #953800;
19
+ }
20
+ .sc-highlight .nc {
21
+ color: #953800;
22
+ }
23
+ .sc-highlight .no {
24
+ color: #953800;
25
+ }
26
+ .sc-highlight .nn {
27
+ color: #953800;
28
+ }
29
+ .sc-highlight .sr {
30
+ color: #116329;
31
+ }
32
+ .sc-highlight .na {
33
+ color: #116329;
34
+ }
35
+ .sc-highlight .nt {
36
+ color: #116329;
37
+ }
38
+ .sc-highlight .gi {
39
+ color: #116329;
40
+ background-color: #dafbe1;
41
+ }
42
+ .sc-highlight .kc {
43
+ color: #0550ae;
44
+ }
45
+ .sc-highlight .l, .sc-highlight .ld, .sc-highlight .m, .sc-highlight .mb, .sc-highlight .mf, .sc-highlight .mh, .sc-highlight .mi, .sc-highlight .il, .sc-highlight .mo, .sc-highlight .mx {
46
+ color: #0550ae;
47
+ }
48
+ .sc-highlight .sb {
49
+ color: #0550ae;
50
+ }
51
+ .sc-highlight .bp {
52
+ color: #0550ae;
53
+ }
54
+ .sc-highlight .ne {
55
+ color: #0550ae;
56
+ }
57
+ .sc-highlight .nl {
58
+ color: #0550ae;
59
+ }
60
+ .sc-highlight .py {
61
+ color: #0550ae;
62
+ }
63
+ .sc-highlight .nv, .sc-highlight .vc, .sc-highlight .vg, .sc-highlight .vi, .sc-highlight .vm {
64
+ color: #0550ae;
65
+ }
66
+ .sc-highlight .o, .sc-highlight .ow {
67
+ color: #0550ae;
68
+ }
69
+ .sc-highlight .gh {
70
+ color: #0550ae;
71
+ font-weight: bold;
72
+ }
73
+ .sc-highlight .gu {
74
+ color: #0550ae;
75
+ font-weight: bold;
76
+ }
77
+ .sc-highlight .s, .sc-highlight .sa, .sc-highlight .sc, .sc-highlight .dl, .sc-highlight .sd, .sc-highlight .s2, .sc-highlight .se, .sc-highlight .sh, .sc-highlight .sx, .sc-highlight .s1, .sc-highlight .ss {
78
+ color: #0a3069;
79
+ }
80
+ .sc-highlight .nd {
81
+ color: #8250df;
82
+ }
83
+ .sc-highlight .nf, .sc-highlight .fm {
84
+ color: #8250df;
85
+ }
86
+ .sc-highlight .err {
87
+ color: #f6f8fa;
88
+ background-color: #82071e;
89
+ }
90
+ .sc-highlight .c, .sc-highlight .ch, .sc-highlight .cd, .sc-highlight .cm, .sc-highlight .cp, .sc-highlight .cpf, .sc-highlight .c1, .sc-highlight .cs {
91
+ color: #6e7781;
92
+ }
93
+ .sc-highlight .gl {
94
+ color: #6e7781;
95
+ }
96
+ .sc-highlight .gt {
97
+ color: #6e7781;
98
+ }
99
+ .sc-highlight .ni {
100
+ color: #24292f;
101
+ }
102
+ .sc-highlight .si {
103
+ color: #24292f;
104
+ }
105
+ .sc-highlight .ge {
106
+ color: #24292f;
107
+ font-style: italic;
108
+ }
109
+ .sc-highlight .gs {
110
+ color: #24292f;
111
+ font-weight: bold;
112
+ }
@@ -2,9 +2,9 @@ class Showcase::Sample
2
2
  attr_reader :name, :id, :events, :details
3
3
  attr_reader :source, :instrumented
4
4
 
5
- def initialize(view_context, name, description: nil, id: name.parameterize, events: nil, **details)
5
+ def initialize(view_context, name, description: nil, id: name.parameterize, syntax: :erb, events: nil, **details)
6
6
  @view_context = view_context
7
- @name, @id, @details = name, id, details
7
+ @name, @id, @syntax, @details = name, id, syntax, details
8
8
  @events = Array(events)
9
9
  description description if description
10
10
  end
@@ -34,13 +34,13 @@ class Showcase::Sample
34
34
  end
35
35
 
36
36
  def extract(&block)
37
- lines = extract_block_lines_via_matched_indentation_from(*block.source_location)
38
- @source = @view_context.instance_exec(lines, &Showcase.sample_renderer)
37
+ source = extract_source_block_via_matched_indentation_from(*block.source_location)
38
+ @source = @view_context.instance_exec(source, @syntax, &Showcase.sample_renderer)
39
39
  end
40
40
 
41
41
  private
42
42
 
43
- def extract_block_lines_via_matched_indentation_from(file, starting_index)
43
+ def extract_source_block_via_matched_indentation_from(file, starting_index)
44
44
  first_line, *lines = File.readlines(file).from(starting_index - 1)
45
45
 
46
46
  indentation = first_line.match(/^\s+(?=\b)/).to_s
@@ -48,6 +48,6 @@ class Showcase::Sample
48
48
 
49
49
  index = lines.index { _1.match?(matcher) }
50
50
  lines.slice!(index..) if index
51
- lines
51
+ lines.join.strip_heredoc
52
52
  end
53
53
  end
@@ -1,4 +1,4 @@
1
- <div class="sc-space-y-8">
1
+ <div class="sc-space-y-8" id="<%= preview.id %>">
2
2
  <section>
3
3
  <% if preview.title %>
4
4
  <div class="sc-flex sc-items-center sc-space-x-2 sc-mb-2">
@@ -27,8 +27,8 @@
27
27
  <details>
28
28
  <summary class="sc-px-4 sc-py-2 hover:sc-bg-indigo-50 sc-cursor-pointer sc-select-none">View Source</summary>
29
29
 
30
- <section class="sc-px-4 sc-py-2 sc-relative sc-overflow-y-auto hover:sc-select-all">
31
- <%= sample.source %>
30
+ <section class="sc-highlight sc-px-4 sc-py-2 sc-relative sc-overflow-y-auto hover:sc-select-all">
31
+ <pre><%= sample.source %></pre>
32
32
  </section>
33
33
  </details>
34
34
  <% end %>
@@ -1 +1 @@
1
- <%= stylesheet_link_tag "application", "showcase" %>
1
+ <%= stylesheet_link_tag "application", "showcase", "showcase.highlights" %>
@@ -1,3 +1,3 @@
1
1
  <article class="hover:sc-bg-indigo-50 <%= "sc-bg-indigo-50" if path.id == params[:id] %>">
2
- <%= link_to path.basename.titleize, preview_path(path.id), class: "sc-inline-block sc-py-2 sc-px-8 sc-w-full" %>
2
+ <%= link_to path.basename.titleize, preview_path(path.id), class: "sc-inline-block sc-py-2 sc-px-8 sc-w-full hover:sc-text-inherit hover:sc-no-underline" %>
3
3
  </article>
@@ -5,9 +5,5 @@ module Showcase
5
5
  initializer "showcase.assets" do
6
6
  config.assets.precompile += %w[showcase_manifest]
7
7
  end
8
-
9
- initializer "showcase.integration_test.autorun" do
10
- Showcase::IntegrationTest.autorun if Rails.env.test?
11
- end
12
8
  end
13
9
  end
@@ -0,0 +1,41 @@
1
+ class Showcase::PreviewsTest < ActionView::TestCase
2
+ def self.inherited(test_class)
3
+ super
4
+ test_class.prepare
5
+ end
6
+
7
+ def self.prepare
8
+ tests Showcase::EngineController._helpers
9
+
10
+ tree = Showcase::Path.tree
11
+ tree.flat_map(&:ordered_paths).each do |path|
12
+ test "Showcase: automatically renders showcase/previews/#{path.id}" do
13
+ render "showcase/engine/preview", preview: path.preview_for(view)
14
+ assert_showcase_preview(path.id)
15
+ end
16
+ end
17
+
18
+ test "Showcase: isn't empty" do
19
+ assert_not_empty tree, "Showcase couldn't find any samples to generate tests for"
20
+ end
21
+ end
22
+
23
+ def self.test(name = nil, showcase: nil, id: nil, &block)
24
+ case
25
+ when name then super(name, &block)
26
+ when id && showcase.nil? then raise ArgumentError, "can't test a sample without a showcase"
27
+ else
28
+ super "Showcase: showcase/previews/#{showcase} #{"sample #{id}" if id}".squish do
29
+ path = Showcase::Path.new(showcase)
30
+ render "showcase/engine/preview", preview: path.preview_for(view)
31
+
32
+ assert_showcase_preview(path.id)
33
+ assert_element(id: id || path.id) { instance_eval(&block) }
34
+ end
35
+ end
36
+ end
37
+
38
+ # Override `assert_showcase_preview` to add custom assertions.
39
+ def assert_showcase_preview(id)
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module Showcase
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.5"
3
3
  end
data/lib/showcase.rb CHANGED
@@ -1,12 +1,28 @@
1
1
  require_relative "showcase/version"
2
2
 
3
+ # Activate the app-bundled Rouge gem to setup default syntax highlighting.
4
+ begin
5
+ gem "rouge"
6
+ require "rouge"
7
+ rescue LoadError
8
+ end
9
+
3
10
  module Showcase
4
- autoload :IntegrationTest, "showcase/integration_test"
5
- autoload :RouteHelper, "showcase/route_helper"
6
- autoload :Options, "showcase/options"
11
+ autoload :PreviewsTest, "showcase/previews_test"
12
+ autoload :RouteHelper, "showcase/route_helper"
13
+ autoload :Options, "showcase/options"
7
14
 
8
15
  singleton_class.attr_accessor :sample_renderer
9
- @sample_renderer = ->(lines) { tag.pre lines.join.strip_heredoc }
16
+ @sample_renderer = proc { _1 }
17
+
18
+ if defined?(Rouge)
19
+ Formatter = Rouge::Formatters::HTML.new
20
+
21
+ @sample_renderer = ->(source, syntax) do
22
+ lexed = Rouge::Lexer.find(syntax).lex(source)
23
+ Showcase::Formatter.format(lexed).html_safe
24
+ end
25
+ end
10
26
 
11
27
  singleton_class.attr_reader :previews_path
12
28
  @previews_path = "showcase/previews"
@@ -1,14 +1,14 @@
1
1
  namespace :showcase do
2
2
  namespace :install do
3
- INTEGRATION_TEST_PATH = "test/integration/showcase_test.rb"
3
+ PREVIEWS_TEST_PATH = "test/views/showcase_test.rb"
4
4
 
5
- desc "Install Showcase integration testing in #{INTEGRATION_TEST_PATH}"
6
- task :integration_test do
7
- mkdir_p File.dirname(INTEGRATION_TEST_PATH)
8
- File.write INTEGRATION_TEST_PATH, <<~RUBY
5
+ desc "Install Showcase previews testing in #{PREVIEWS_TEST_PATH}"
6
+ task :previews_test do
7
+ mkdir_p File.dirname(PREVIEWS_TEST_PATH)
8
+ File.write PREVIEWS_TEST_PATH, <<~RUBY
9
9
  require "test_helper"
10
10
 
11
- class ShowcaseTest < Showcase::IntegrationTest
11
+ class ShowcaseTest < Showcase::PreviewsTest
12
12
  def assert_showcase_preview(id)
13
13
  # Add any custom preview response body assertions here.
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: showcase-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pence
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-02-20 00:00:00.000000000 Z
12
+ date: 2023-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -50,6 +50,7 @@ files:
50
50
  - README.md
51
51
  - Rakefile
52
52
  - app/assets/builds/showcase.css
53
+ - app/assets/builds/showcase.highlights.css
53
54
  - app/assets/config/showcase_manifest.js
54
55
  - app/assets/javascripts/showcase.js
55
56
  - app/controllers/showcase/engine_controller.rb
@@ -73,8 +74,8 @@ files:
73
74
  - lib/showcase-rails.rb
74
75
  - lib/showcase.rb
75
76
  - lib/showcase/engine.rb
76
- - lib/showcase/integration_test.rb
77
77
  - lib/showcase/options.rb
78
+ - lib/showcase/previews_test.rb
78
79
  - lib/showcase/route_helper.rb
79
80
  - lib/showcase/version.rb
80
81
  - lib/tasks/showcase_tasks.rake
@@ -1,30 +0,0 @@
1
- class Showcase::IntegrationTest < ActionDispatch::IntegrationTest
2
- def self.inherited(test_class)
3
- super
4
- test_class.prepare
5
- end
6
-
7
- def self.autorun
8
- at_exit { prepare unless subclasses.any? }
9
- end
10
-
11
- def self.prepare
12
- tree = Showcase::Path.tree
13
- tree.flat_map(&:ordered_paths).each do |path|
14
- test "Showcase: GET showcase/previews/#{path.id} renders successfully" do
15
- get showcase.preview_path(path.id)
16
-
17
- assert_response :ok
18
- assert_showcase_preview(path.id)
19
- end
20
- end
21
-
22
- test "Showcase: isn't empty" do
23
- assert_not_empty tree, "Showcase couldn't find any samples to generate tests for"
24
- end
25
- end
26
-
27
- # Override `assert_showcase_preview` to add custom assertions.
28
- def assert_showcase_preview(id)
29
- end
30
- end