Skip to content

Enumerator inspect tests#7532

Merged
enebo merged 3 commits intojruby:masterfrom
cboos:enumerator_inspect_tests
Dec 19, 2022
Merged

Enumerator inspect tests#7532
enebo merged 3 commits intojruby:masterfrom
cboos:enumerator_inspect_tests

Conversation

@cboos
Copy link

@cboos cboos commented Dec 17, 2022

I wanted to contribute a regression test for issue #7529, as a follow-up to its fix by @enebo in #7531, but I noticed that there was already a corresponding test case in the MRI test suite.

Before the fix, with master 278aaac:

$ jruby test/mri/runner.rb  test/mri/ruby/test_enumerator.rb
...
[48/63] TestEnumerator#test_inspect_encoding = 0.02 s
  7) Failure:
TestEnumerator#test_inspect_encoding [/home/cboos/workspace/jruby/test/mri/ruby/test_enumerator.rb:440]:
<#<Encoding:UTF-8>> expected but was
<#<Encoding:ASCII-8BIT>>.

Finished tests in 2.532488s, 24.8767 tests/s, 171.7678 assertions/s.
63 tests, 435 assertions, 6 failures, 1 errors, 0 skips

However, after the fix, with 1d97237, that test still failed!

With JRuby we got: "#<Enumerator: #<#<Class:0x43312512>:0x1b868ef0>:?>" instead of the expected "#<Enumerator: #<#<Class:0x000002c3ad457ec8>:0x000002c3ad5dacc8>:あ>" as with CRuby 3.0, for example.

Reproducing with irb what the TestEnumerator#test_inspect_encoding test does gives the following:

irb(main):001:0> c = Class.new{define_method("\u{3042}"){}}
=> #<Class:0x79cfc008>
irb(main):002:0> c.new.enum_for("\u{3042}")
=> #<Enumerator: #<#<Class:0x79cfc008>:0x54ebd3b4>:?>
c.new.enum_for("\u{3042}").instance_eval("@__method__")
=> :B

Even worse, trying to use that enumerator leads to:

irb(main):003:0> e.next
uri:classloader:/jruby/kernel/enumerator.rb:72:in `block in initialize': undefined method `B' for #<#<Class:0x4834e816>:0x3389c69d> (NoMethodError)

This pull request adds some follow-up tests and fixes for the above.

"Enumerator#inspect produces an ASCII-8BIT encoded String"

This was fixed by PR jruby#7531

"Enumerator#inspect: Use String concatenation not just bytelist appends"
Without the fix, the following sequence:

    c = Class.new{define_method(:"\u{3042}"){}}
    c.new.enum_for(:"\u{3042}").inspect

would give:

    "#<Enumerator: #<#<Class:0x79cfc008>:0x78077f1c>:\xE3\x81\x82>"

(with ASCII_8BIT encoding)
While working on the inspect behavior, I noticed that there was a much more
serious bug: the enumerator produced by the tested sequence would not work!

    c = Class.new{define_method("\u{3042}"){}}
    e = c.new.enum_for("\u{3042}")
    e.next # => raise StopIteration

Instead, this would produce the following error:

    uri:classloader:/jruby/kernel/enumerator.rb:72:in `block in initialize\': undefined method `B\' for #<#<Class:0x4834e816>:0x3389c69d> (NoMethodError)

Converting the String to a Symbol in RubyKernel#obj_to_enum before calling
asJavaString fixes this problem.
@enebo
Copy link
Member

enebo commented Dec 19, 2022

@cboos we have very slowly been finding places where we are not appropriately encoding m17n symbols into Strings. Mostly in error strings but you found out we also have issues with some inspect()/to_s() (in reflective sorts of things). Most people do not consume these things in a progmatic way so I think that partially explains why they have not been fixed.

This is great though. Thanks for your help!

@enebo enebo added this to the JRuby 9.4.1.0 milestone Dec 19, 2022
@enebo enebo merged commit 6416265 into jruby:master Dec 19, 2022
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.

2 participants