forked from rails/rails
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ensure
response.parsed_body
support for pattern matching
Both `Nokogiri` and `Minitest` have merged the PRs mentioned to integrate support for Ruby's Pattern matching (sparklemotion/nokogiri#2523 and minitest/minitest#936, respectively). This commit adds coverage for those new assertions, and incorporates examples into the documentation for the `response.parsed_body` method. In order to incorporate pattern-matching support for JSON responses, this commit changes the response parser to call `JSON.parse` with [object_class: ActiveSupport::HashWithIndifferentAccess][object_class], since String instances for `Hash` keys are incompatible with Ruby's syntactically pattern matching. For example: ```ruby irb(main):001:0> json = {"key" => "value"} => {"key"=>"value"} irb(main):002:0> json in {key: /value/} => false irb(main):001:0> json = {"key" => "value"} => {"key"=>"value"} irb(main):002:0> json in {"key" => /value/} .../3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/lib/irb/workspace.rb:113:in `eval': (irb):2: syntax error, unexpected terminator, expecting literal content or tSTRING_DBEG or tSTRING_DVAR or tLABEL_END (SyntaxError) json in {"key" => /value/} ^ .../ruby/3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/exe/irb:9:in `<top (required)>' .../ruby/3.2.0/bin/irb:25:in `load' .../ruby/3.2.0/bin/irb:25:in `<main>' ``` When the Hash maps String keys to Symbol keys, it's able to be pattern matched: ```ruby irb(main):005:0> json = {"key" => "value"}.with_indifferent_access => {"key"=>"value"} irb(main):006:0> json in {key: /value/} => true ``` [object_class]: https://docs.ruby-lang.org/en/3.2/JSON.html#module-JSON-label-Parsing+Options
- Loading branch information
1 parent
ed5af00
commit 0f4ab82
Showing
6 changed files
with
84 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
actionpack/test/dispatch/test_response_test/pattern_matching_test_cases.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
module TestResponseTest::PatternMatchingTestCases | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
test "JSON response Hash pattern matching" do | ||
response = ActionDispatch::TestResponse.create(200, { "Content-Type" => "application/json" }, '{ "foo": "fighters" }') | ||
|
||
# rubocop:disable Lint/Syntax | ||
assert_pattern { response.parsed_body => { foo: /fighter/ } } | ||
# rubocop:enable Lint/Syntax | ||
end | ||
|
||
test "JSON response Array pattern matching" do | ||
response = ActionDispatch::TestResponse.create(200, { "Content-Type" => "application/json" }, '[{ "foo": "fighters" }, { "nir": "vana" }]') | ||
# rubocop:disable Lint/Syntax | ||
assert_pattern { response.parsed_body => [{ foo: /fighter/ }, { nir: /vana/ }] } | ||
# rubocop:enable Lint/Syntax | ||
end | ||
|
||
test "HTML response pattern matching" do | ||
response = ActionDispatch::TestResponse.create(200, { "Content-Type" => "text/html" }, <<~HTML) | ||
<html> | ||
<head></head> | ||
<body> | ||
<main><h1>Some main content</h1></main> | ||
</body> | ||
</html> | ||
HTML | ||
html = response.parsed_body | ||
|
||
# rubocop:disable Lint/Syntax | ||
html.at("main") => {name:, content:} | ||
# rubocop:enable Lint/Syntax | ||
|
||
assert_equal "main", name | ||
assert_equal "Some main content", content | ||
|
||
# rubocop:disable Lint/Syntax | ||
assert_pattern { html.at("main") => { content: "Some main content" } } | ||
assert_pattern { html.at("main") => { content: /content/ } } | ||
assert_pattern { html.at("main") => { children: [{ name: "h1", content: /content/ }] } } | ||
# rubocop:enable Lint/Syntax | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters