Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: experimental implementation of pattern matching #2523

Merged
merged 1 commit into from
Nov 23, 2022

Conversation

flavorjones
Copy link
Member

@flavorjones flavorjones commented Apr 30, 2022

What problem is this PR intended to solve?

See #2360 for discussion about introducing support for pattern matching.

supporting classes:

  • XML::Attr
  • XML::Document
  • XML::DocumentFragment
  • XML::Namespace
  • XML::Node
  • XML::NodeSet

and their subclasses.

I'd love to hear feedback on this proposed experimental API.

Have you included adequate test coverage?

Unit test coverage introduced in test/test_pattern_matching.rb and actual pattern matching use cases tested in test/_test_pattern_matching.rb

Does this change affect the behavior of either the C or the Java native implementations?

No.

@flavorjones flavorjones force-pushed the flavorjones-pattern-matching branch from bfe1960 to 44ca985 Compare May 8, 2022 01:56
@flavorjones
Copy link
Member Author

OK, I haven't received any comments or feedback, so I'm planning on releasing this as an experimental feature in v1.14.0.

@flavorjones flavorjones added this to the v1.14.0 milestone Jun 5, 2022
@flavorjones flavorjones force-pushed the flavorjones-pattern-matching branch 3 times, most recently from 28e520c to 432f4a4 Compare August 8, 2022 01:45
@flavorjones
Copy link
Member Author

Looks like JRuby is failing a few of the tests, will look into it.

@flavorjones flavorjones force-pushed the flavorjones-pattern-matching branch 2 times, most recently from ad94504 to 123a963 Compare August 27, 2022 18:16
@flavorjones flavorjones force-pushed the flavorjones-pattern-matching branch 4 times, most recently from 47d22db to f110e34 Compare November 22, 2022 06:15
@flavorjones
Copy link
Member Author

I've added documentation to the methods, which should be good enough for folks to pick it up and try it out.

@flavorjones flavorjones force-pushed the flavorjones-pattern-matching branch 2 times, most recently from cf718c0 to 40ad854 Compare November 22, 2022 18:45
supporting classes:

- XML::Attr
- XML::Document
- XML::DocumentFragment
- XML::Namespace
- XML::Node
- XML::NodeSet

and their subclasses.

See #2360 for discussion and to provide feedback.
@flavorjones flavorjones merged commit 3cdb98b into main Nov 23, 2022
@flavorjones flavorjones deleted the flavorjones-pattern-matching branch November 23, 2022 20:23
seanpdoyle added a commit to seanpdoyle/rails that referenced this pull request Jan 28, 2023
…okogiri

Prior to this commit, the only out-of-the-box parsing that
`ActionDispatch::Testing::TestResponse#parsed_body` supported was for
`application/json` requests. This meant that `response.body ==
response.parsed_body` for HTML requests.

```ruby
get "/posts"
response.content_type         # => "text/html; charset=utf-8"
response.parsed_body.class    # => Nokogiri::HTML5::Document
response.parsed_body.to_html  # => "<!DOCTYPE html>\n<html>\n..."
```

Using `parsed_body` for JSON requests supports `Hash#fetch`, `Hash#dig`,
and Ruby 3.2 destructuring assignment and pattern matching.

The introduction of [Nokogiri support for pattern
matching][nokogiri-pattern-matching] poses an opportunity to make assertions
about the structure of the HTML response.

On top of that, there is ongoing work to [introduce pattern matching
support in MiniTest][minitest-pattern-matching].

[nokogiri-pattern-matching]: sparklemotion/nokogiri#2523
[minitest-pattern-matching]: minitest/minitest#936
seanpdoyle added a commit to seanpdoyle/rails that referenced this pull request Aug 23, 2023
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
seanpdoyle added a commit to seanpdoyle/rails that referenced this pull request Aug 23, 2023
Add notes for [rails#47144][] to the 7.1 Release Notes.

Additionally, in the time since that was merged, 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
guidance into the release notes.

[rails#47144]: rails#47144
flavorjones added a commit that referenced this pull request Aug 26, 2023
**What problem is this PR intended to solve?**

Pattern matching was introduced as an experimental feature in v1.14.0
(see #2360 and #2523 for historical context).

Seeing downstream libraries adopt pattern matching for testing, as in
rails/rails#49003, means this is apparently
useful enough to start using.

Let's end experimental support and make it a fully-supported feature in
the next minor release, v1.16.0.
paulreece pushed a commit to paulreece/rails-paulreece that referenced this pull request Aug 26, 2023
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
paulreece pushed a commit to paulreece/rails-paulreece that referenced this pull request Aug 26, 2023
Add notes for [rails#47144][] to the 7.1 Release Notes.

Additionally, in the time since that was merged, 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
guidance into the release notes.

[rails#47144]: rails#47144
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant