Commit Graph

101 Commits

Author SHA1 Message Date
Sean Doyle 7badc42723
Introduce `ActionView::TestCase.register_parser`
Register a callable to decode rendered content for a given MIME type

Each registered decoder will also define a `#rendered.$MIME` helper
method, where `$MIME` corresponds to the value of the `mime` argument.

=== Arguments

`mime` - Symbol the MIME Type name for the rendered content
`callable` - Callable to decode the String. Accepts the String
                    value as its only argument
`block` - Block serves as the decoder when the
                 `callable` is omitted

By default, ActionView::TestCase defines a decoder for:

* :html - returns an instance of Nokogiri::XML::Node
* :json - returns an instance of ActiveSupport::HashWithIndifferentAccess

Each pre-registered decoder also defines a corresponding helper:

* :html - defines `rendered.html`
* :json - defines `rendered.json`

=== Examples

To parse the rendered content into RSS, register a call to `RSS::Parser.parse`:

```ruby
register_decoder :rss, -> rendered { RSS::Parser.parse(rendered) }

test "renders RSS" do
  article = Article.create!(title: "Hello, world")

  render formats: :rss, partial: article

  assert_equal "Hello, world", rendered.rss.items.last.title
end
```

To parse the rendered content into a Capybara::Simple::Node,
re-register an `:html` decoder with a call to
`Capybara.string`:

```ruby
register_decoder :html, -> rendered { Capybara.string(rendered) }

test "renders HTML" do
  article = Article.create!(title: "Hello, world")

  render partial: article

  rendered.html.assert_css "h1", text: "Hello, world"
end
```
2023-09-27 02:03:23 +00:00
Sean Doyle a9148b45f3 Add "Testing View Partials" section to the Testing Guides
Motivation / Background
---

While the `ActionView::TestCase` class isn't marked with a `:nodoc:`
comment to indicate that it's internal to Rails, there isn't much
content in the guides that explains how to test view partials.

Libraries like
[view_component](https://github.com/ViewComponent/view_component/) have
[built-in support for
testing](https://viewcomponent.org/guide/testing.html), including
Capybara integration.

While `ActionView::TestCase` already integrates with
`rails-dom-testing`, that integration could be better documented.
Additionally, it wouldn't take much for consuming applications to mimic
the ViewComponent testing experience for their Action View Partials.

Details
---

First, link to the "Testing Rails Applications" page from the
`ActionView::TestCase` class documentation.

Next, add a "Testing View Partials" section to the guides that expands
upon the variety of tooling available to tests that inherit from
`ActionView::TestCase`. In that section, cover topics like:

* the `render` helper method
* the `rendered` helper attribute reader
* calls to `assert_select` with attribute placeholders
* the `document_root_element` helper method
* integration with Ruby's Pattern Matching
* opportunities to integrate with Capybara

Additional Information
---

Additionally, add test coverage that exercise the examples shared in the
new section, including:

* Calls to `assert_select` that utilize attribute placeholders
* Ruby 3.0's Pattern Matching
* Integration with Capybara
2023-09-13 09:44:44 -04:00
Stefanni Brasil 13d8bc10af Add test for nested content_tags with data attributes outside of erb
The existing content_tag tests document how to use content_tag outside
of erb views with data attributes. But for those who need to use
content_tag with nested content_tags and data attributes outside of
erb views, it can be challenging to find out how to do that.

When I had to do this in a project, it took me longer than I wanted.
Hopefully adding this test with an explicit example of how to achieve that
will others some time.
2023-07-14 15:57:23 -06:00
Jean Boussier a2f685c7c0 Cleanly fallback when failing to tokenize ERB templates
Fix: https://github.com/rails/rails/issues/48319
Followup: https://github.com/rails/rails/pull/48184
2023-06-01 11:35:31 +02:00
Jean Boussier 096c785c39 Properly fallback when ERB column can't be computed
Fix: https://github.com/rails/rails/issues/48173

If for some reason the column identification fails, we should
fallback to the old error rendering with only line information.
2023-05-10 10:42:11 +09:00
Rafael Mendonça França 8241178723
Remove deprecated support to instance variables as locals to partials 2023-03-03 00:38:39 +00:00
Aaron Patterson cd48642561
Add tests that column information can be translated 2022-10-09 14:52:17 -07:00
John Bampton 2f699c51ce Fix word case. `html` -> `HTML` 2022-09-18 04:21:22 +10:00
Alex Ghiculescu 3f1f4c7d0c Always preload if using proc with multifetch cache
https://github.com/rails/rails/pull/31250 optimised rendering a collection with `cached: true`, but also with `cached: proc {}`. The problem is the proc may reference associations that should be preloaded to avoid n+1s in generating the cache key.

For example:

```ruby
@posts = Post.preload(:author)

@view.render partial: "test/partial", collection: @post, cached: proc { |post| [post, post.author] }
```

This will n+1 on `post.author`.

To fix this, this PR will always preload the collection if there's a proc given for `cached`. `cached: true` will still not preload unless it renders, as it did in https://github.com/rails/rails/pull/31250.
2022-05-07 22:19:39 +10:00
David Heinemeier Hansson 41478f7074 Make #to_fs the default replacement for #to_s(:format)
#to_formatted_s is too cumbersome.
2022-02-07 12:41:21 +01:00
Rafael Mendonça França 7160f46a9e
Merge pull request #43368 from FestaLab/render-hash-syntax
Replaces the hash rocket operator in favor of the newer Ruby syntax on render
2021-12-08 18:13:44 -05:00
Rafael Mendonça França c2e12e0191
Use `to_formatted_s(:db)` instead of `to_s(:db)` internally
Ruby 3.1 introduced an optimization to string interpolation for some
core classes in b08dacfea3.

But since we override `to_s` in some of those core classes to add behavior
like `to_s(:db)`, all Rails applications will not be able to take advantage
of that improvement.

Since we can use the `to_formatted_s` alias for the Rails specific behavior
it is best for us to deprecate the `to_s` core extension and allow Rails
applications to get the proformace improvement.

This commit starts removing all the `to_s(:db)` calls inside the framework
so we can deprecate the core extension in the next commit.
2021-12-06 19:22:04 +00:00
Liuri Loami d3e5833459 Replaces the "hash rocket" operator in favor of the newer Ruby syntax when rendering on render 2021-10-03 23:33:56 -03:00
John Hawthorn c44d702a08
Merge pull request #42458 from HParker/use-ripper-dependency-tracker
Replace dependency tracker with ripper based tracker
2021-08-04 11:10:13 -07:00
Joel Hawksley fd5792f0fc
Add caching? helper method
Caching something that shouldn't be cached is a potential source of
bugs and security vulnerabilities. For example, one could write a
form helper that outputs a request-specific auth token, only for
the helper to be used inside of a `cache` block.

In the GitHub application, we implemented a caching? method and used
it to raise an error if a specific code path is being cached that
we don't want to be cached.

I've credited its original author, @btoews.

Co-authored-by: Ben Toews <mastahyeti@gmail.com>
Co-authored-by: John Hawthorn <jhawthorn@github.com>
Co-authored-by: Kasper Timm Hansen <kaspth@gmail.com>
2021-08-03 15:49:48 -06:00
HParker 897b9bf6e2 Replace dependency tracker with ripper based tracker
Instead of using the ERBTracker, we can use RipperTracker which is extracted from https://github.com/jhawthorn/actionview_precompiler.

Using a parser finds dependencies that would otherwise be difficult to find with the regular expressions. It should also theoretically work with other template systems since it operates on the compiled template instead of the contents of the file.

Co-authored-by: John Hawthorn <john@hawthorn.email>
2021-07-12 10:33:09 -07:00
John Bampton 54e526e473 chore: fix grammar, spelling and minor whitespace fix 2021-04-13 21:35:50 +10:00
Marek Kasztelnik 9e15560191 Failing test for lazy translation in partial with block 2020-12-30 14:07:09 +01:00
Eugene Kenny 2a8fe4f821 Remove an unused Action View test fixture
The test that used this was deleted in
4642ca9640.
2020-11-01 23:25:29 +00:00
Rafael Mendonça França d52d773946
Remove deprecated support to passing relative paths to `render file:` 2020-10-30 00:25:14 +00:00
Rafael Mendonça França 320e7f7c95
Remove deprecated pattern argument in `ActionView::Template::PathResolver` 2020-10-30 00:25:13 +00:00
Ryuta Kamizono 4194565ddf Remove .DS_Store 2020-10-16 15:23:45 +09:00
Joel Hawksley 136b814144 Include layout when rendering objects from controllers
In https://github.com/rails/rails/pull/37919, support
for rendering objects that respond_to render_in in
controllers was added. However, the implementation
did not support layouts.

This change updates the implementation from #37919
to more closely match the rest of the
ActionView::Template classes, enabling the use of layouts.

Co-authored-by: Felipe Sateler <fsateler@gmail.com>
2020-10-14 11:49:45 -06:00
Joel Hawksley 36b01da797 Do not add newlines when annotating rendered views
When rendering a view with annotate_rendered_view_with_filenames
enabled, we were inserting newlines after the BEGIN and END
comments. These newlines are not ideal in some use cases, such
as rendering templates to strings that are then passed around
our application.

As the newlines were added for aesthetic purposes, we think it
makes sense to remove them so that rendered template strings do
not contain extraneous newlines.

As a result of removing these newlines, the annotations
no longer affect the reporting of template error on the correct
line, as addressed in #38950. As such, we've reverted those
changes as well.

Co-authored-by: Chris Gavin <chrisgavin@github.com>
2020-10-06 11:29:36 -06:00
Sean Doyle 7cf52ae981
Extend `ActionView::Helpers#translate` to yield
This commit extends the `ActionView::Helpers#translate` (and by way of
alias, `#t`) helper methods to accept blocks.

When invoked with a block, the `translate` call will yield the
translated text as its first block argument, along with the resolved
translation key as its second:

```erb
<%= translate(".key") do |translation, resolved_key| %>
  <span data-i18n-key="<%= resolved_key %>"><%= translation %></span>
<% end %>
```

In cases where relative translation keys are foregone in lieu of fully
qualified keys, or if the caller is not interested in the resolved key,
the second block argument can be omitted:

```erb
<%= translate("action.template.key") do |translation| %>
  <p><%= translation %></p>
  <p><%= translation %>, but a second time</p>
<% end %>
```

A benefit of yielding the translation is that it enabled template-local
variable re-use. Alternatively, [`Object#tap`][tap] could be used.

Prior to this commit, however, the resolution of the translation key was
internal to `ActionView`, and unavailable to the caller (unless they
were willing to explicitly determine the resolved key themselves). By
making it available as a block parameter, it could be used to annotate
the translated value in the resulting elements.

[tap]: https://ruby-doc.org/core-2.7.0/Object.html#method-i-tap
2020-08-26 20:46:33 +00:00
Eugene Kenny 5888c359e4 Add test for HTML format fallback from JS template
When rendering a template with an explicit JS format, typically via
`respond_to :js`, we want to be able to render HTML partials without
having to specify their format, in order to make SJR more ergonomic.
2020-05-29 22:07:17 +01:00
Aaron Lipman 4671fe2040
Ensure cache fragment digests include all templates
A Rails view may rely on several templates (e.g. layouts and partials)
in addition to the template for the action being rendered (e.g.
"show.html.erb"). To track which view file is currently being rendered
for the purpose of generating template tree digests used in cache
fragment keys, Action View uses a stack, the top item of which is
accessed via the @current_template variable (introduced in 1581cab).

Consider the following template:

    <!-- home.html.erb -->
    <%= render layout: "wrapper" do %>
      <%= cache "foo" %>
        HOME
      <%= end %>
    <%= end %>

Inside the block passed to the render helper, @current_template
corresponds to the wrapper.html.erb template instead of home.html.erb.
As wrapper.html.erb is then used as the root node for generating the
template tree digest used in the cache fragment key, the cache fragment
fails to expire upon changes to home.html.erb. Additionally, should a
second template use the wrapper.html.erb layout and contain a cache
fragment with the same key, the cache fragment keys for both templates
will be identical - causing cached content to "leak" from one view to
another (as described in #38984).

This commit skips adding templates to the stack when rendered as a
layout with a block via the render helper, ensuring correct and unique
cache fragment digests. Additionally, the virtual_path keyword arguments
found in CacheHelper and all references to the are removed as they no
longer possess any function. (Following the introduction of
@current_template, virtual_path is accessed via
@current_template.virtual_path rather than as a standalone variable.)
2020-05-26 15:52:05 -04:00
Aaron Patterson 5f596e299e
Add a regression test that ActionText caught
ActionText is using ActionView in a way that ActionView doesn't have in
it's test suite.  This is just a regression test to hit that same use
case.
2020-02-27 16:47:22 -08:00
st0012 e8688ddb33 Fix partial caching ignore repeated items issue
This is because we only use hash to maintain the result. So when the key
are the same, the result would be skipped. The solution is to maintain
an array for tracking every item's position to restructure the result.
2019-04-04 09:59:06 +08:00
Rafael França e3f5f1c936
Merge pull request #35308 from erose/better-error-reporting-for-syntax-errors-in-templates
Display a more helpful error message when an ERB template has a Ruby syntax error.
2019-03-28 14:53:22 -04:00
John Hawthorn f35631d466 Prefer render template: in tests
Many tests were using `render file:`, but were only testing the
behaviour of `render template:` (file: just allows more paths/ is less
secure then template:).

The reason for so many `render file:` is probably that they were the old
default.

This commit replaces `render file:` with `render template:` anywhere the
test wasn't specifically interested in using `render file:`.
2019-03-21 13:44:56 -07:00
Eli Rose 07804d4759 Add handling and tests. 2019-02-17 23:07:16 -05:00
Ryuta Kamizono 4c45801ea0 Address to useless assignment `formats = nil` after #35254
https://codeclimate.com/github/rails/rails/pull/35254
2019-02-14 02:17:15 +09:00
Aaron Patterson 9439a18bf7
Adding another failing test case 2019-02-11 17:55:53 -08:00
Aaron Patterson 3b3975b7db
Add a failing test for #35222 2019-02-11 13:15:53 -08:00
yuuji.yaginuma 1b86d90136 Enable `Performance/UnfreezeString` cop
In Ruby 2.3 or later, `String#+@` is available and `+@` is faster than `dup`.

```ruby
# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  gem "benchmark-ips"
end

Benchmark.ips do |x|
  x.report('+@') { +"" }
  x.report('dup') { "".dup }
  x.compare!
end
```

```
$ ruby -v benchmark.rb
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
Warming up --------------------------------------
                  +@   282.289k i/100ms
                 dup   187.638k i/100ms
Calculating -------------------------------------
                  +@      6.775M (± 3.6%) i/s -     33.875M in   5.006253s
                 dup      3.320M (± 2.2%) i/s -     16.700M in   5.032125s

Comparison:
                  +@:  6775299.3 i/s
                 dup:  3320400.7 i/s - 2.04x  slower

```
2018-09-23 08:56:55 +09:00
Javan Makhmali f4eb2e23a8 Fix digesting templates with mixed formats 2018-03-20 06:33:20 -04:00
bogdanvlviv 0f98954a83
Clean up and consolidate .gitignores
* Global ignores at toplevel .gitignore
* Component-specific ignores in each toplevel directory
* Remove `actionview/test/tmp/.keep` for JRuby

```
rm actionview/test/tmp/ -fr
cd actionview/
bundle exec jruby -Itest test/template/digestor_test.rb
```

Related to #11743, #30392.

Closes #29978.
2018-02-17 14:26:19 -08:00
mfo 6d3b57fe42 fix(streaming_template_renderer): I18n.locale broken in layout. I18n gem stores the current locale in Thread.current[:local] (see: https://github.com/svenfuchs/i18n/blob/master/lib/i18n.rb#L23). StreamingTemplateRenderer is implemented with Fiber which have its own stack of locals and can not access Thread.current.locals(keys, see: https://ruby-doc.org/core-2.2.0/Thread.html#class-Thread-label-Fiber-local+vs.+Thread-local). 2017-11-25 21:32:02 +01:00
Kir Shatrov 424117281e Use frozen string literal in actionview/ 2017-07-24 11:53:43 +03:00
Matthew Draper 87b3e226d6 Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"
This reverts commit 3420a14590, reversing
changes made to afb66a5a59.
2017-07-02 02:15:17 +09:30
Matthew Draper 3420a14590 Merge pull request #29540 from kirs/rubocop-frozen-string
Enforce frozen string in Rubocop
2017-07-02 01:11:50 +09:30
Kir Shatrov cfade1ec7e Enforce frozen string in Rubocop 2017-07-01 02:11:03 +03:00
Pat Allan 3d453b409d Make ActionView frozen string literal friendly.
Plus a couple of related ActionPack patches.
2017-06-20 22:20:04 +10:00
Stan Lo 2abf6ca0c8 Use a hash to record every partial's cache hit status instead of sharing a boolean. 2017-06-08 21:42:46 +02:00
Kasper Timm Hansen 61de2e9764 Merge pull request #28753 from st0012/add-render-with-variants-test
Add tests for rendering with variants
2017-05-01 21:44:21 +02:00
Rafael Mendonça França 0871e5e5c1
Fix all style guides violations
Closes #28382
Closes #28651
2017-04-19 20:13:42 -04:00
Stan Lo 8feb7c934f Add tests for render template/partial with variants option. 2017-04-14 17:34:51 +08:00
Matthew Eagar e524327e51 Add partial iteration variable to template keys
When rendering heterogeneous collection using `render @collection` or
`render partial: @collection`, the expected `<partial_name>_iteration`
variable is missing due to `find_template` not having the name of the
iteration variable included in its cache keys.
2017-01-25 09:23:43 -05:00
Andrew White b5edc55d9f Allow render locals to be assigned to instance variables
In #26672 we blocked use of Ruby keywords as identifiers for view
locals but inadvertently broke the use of instance variable names
as identifiers. Whilst not explicitly documented this behavior has
been around for a long time and there's no need to break it now.

Fixes #27480.
2017-01-15 13:41:39 +00:00