-
Notifications
You must be signed in to change notification settings - Fork 940
Use composition over inheritance for PartsList
#782
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
Conversation
Thanks for your feedback @jeremy ! :-) |
|
||
def ==(other) | ||
super || @parts == other | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means two PartsList objects are equal and a PartsList is equal to an array of the same parts, but a PartsList is not equal to a different PartsList object with the same parts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh I'm not sure to understand but it looks like a PartsList is equal to a different PartsList object with the same parts: http://git.io/rrPtFA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh - not sure how that's working! Should be falling back on Object#==
which is object equality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is the case, normally here super
refers to Object#==
since Mail::PartsList
doesn't inherit from any other object now.
Thanks for your review @jeremy! Regarding YAML seralization, finally, we are serializing the The build is still failing due to a problem with RSpec apparently ; this was already the case on |
Hi, I'm a newbie to github- I'm suffering from the problem this pull-request solves. Is it possible for me to get this change or do I need to wait for someone to merge the pull request? |
@ryan2johnson9 : You'll need to wait until it's merged and it gets included inside a release or reference this branch directly inside your Gemfile: gem 'mail', github: 'robin850/mail', branch: 'composition-parts-list' or apply the patch on a local copy of the gem; There is still some work to do though (especially regarding @bf4's comment) ; I will try to do it as soon as possible so it can be merged. Thanks for the reminder! |
Ahh, thanks so much!! |
It appears the rspec error messages contain invalid utf-8 so rubinius is blowing up monkeypatch I've submitted as a PR to rspec-core rspec/rspec-core#1760 require 'rspec/notifications'
class RSpec::Core::Notifications::FailedExampleNotification
private
def exception_message
@exception_message ||= exception.message.to_s.
# Converting it to a higher higher character set (UTF-16) and then
# back (to UTF-8) ensures that you will strip away invalid or undefined byte sequences.
encode(Encoding::UTF_16LE, :invalid => :replace, :undef => :replace, :replace => '?').
encode(Encoding::UTF_8)
end
def failure_lines
@failure_lines ||=
begin
lines = ["Failure/Error: #{read_failed_line.strip}"]
lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/
exception_message.split("\n").each do |line|
lines << " #{line}" if exception.message
end
lines
end
end
end |
I've confirmed the tests pass on rbx, when I apply commit a1f454d8a26ec822352fcb7eae9db02629f1da4c
Author: Benjamin Fleischer <[email protected]>
Date: Mon Nov 3 16:52:26 2014 -0600
use utf8-friendly rspec-core
diff --git a/Gemfile b/Gemfile
index 8228d32..03df3f1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,12 @@
source "https://rubygems.org"
+%w{rspec-support rspec-expectations rspec-mocks}.each do |gem_name|
+ gem gem_name, github: "rspec/#{gem_name}"
+end
+gem 'rspec-core', github: 'bf4/rspec-core', branch: 'handle_non_utf8_exception_messages'
+gem 'rspec', github: 'rspec/rspec'
gemspec
gem "tlsmail", "~> 0.0.1" if RUBY_VERSION <= "1.8.6"
diff --git a/mail.gemspec b/mail.gemspec
index 7375c30..28f9cc7 100644
--- a/mail.gemspec
+++ b/mail.gemspec
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
s.add_development_dependency('bundler', '>= 1.0.3')
s.add_development_dependency('rake', '> 0.8.7')
- s.add_development_dependency('rspec', '~> 3.0.0')
+ s.add_development_dependency('rspec', '~> 3.0')
s.add_development_dependency('rdoc')
s.files = %w(README.md MIT-LICENSE CONTRIBUTING.md CHANGELOG.rdoc Dependencies.txt Gemfile Rakefile TODO.rdoc) + Dir.glob("lib/**/*") |
|
||
def to_yaml(options = {}) | ||
@parts.to_yaml(options) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests?
Ok, sorry it took so long to get back to you but the feedback seems to be addressed. :-) @bf4 : Thanks a ton for working on making RSpec more compliant with Rubinius ; hoping the pull request will be grabbed soon ! ❤️ Do you want me to put back Rubinius in the list of allowed failures ? At least the JRuby build is broken as well due to travis-ci/travis-ci#3067.
Is it really a problem ? In Ruby 1.9.2 and less, the default YAML engine is Syck so the Let me know if there's anything missing! Happy new year to you guys! 🎉 |
Trying this with RSpec head https://travis-ci.org/mikel/mail/builds/50076945 |
@robin850 This PR built successfully for me locally with rubinius, maybe reopen the PR to trigger a new build? |
Instead of inheriting from `Array`, let's create an attribute that is an array. The current object doesn't fit with the Liskov substitution principle as, for instance, #sort is broken on Rubinius. This makes the `PartsList` class compatible with Rubinius as `undef map` will remove the map method but some other Enumerable methods (e.g. sort) rely on it. Also add fallback for Array's methods for the sake of backward compatibility, we need to provide a fallback for missing method that may be used in the existing libraries. To avoid all the necessary boilerplate to provide such fallback, let's rely on the standard library's delegate gem and its DelegateClass method.
Previously, the object would have been serialized as an Array even though YAML wouldn't be able to round-trip. Let's keep this behavior for now to make upgrade smoother to this new "layer".
Use composition over inheritance for `PartsList`
The edge version ships with a patch that uses composition over inheritance for the Mail::PartsList object (see mikel/mail#782). Let's test Action Mailer against it to prevent eventual regressions and experience it. Moreover, this branch makes the Action Mailer suite green against Rubinius.
Use composition over inheritance for `PartsList`
There's a bug in the mail gem that only affects rubinius. This seems to be causing build failures for mailgun_rails. Here's the details of the bug: mikel/mail#782 This commit temporarily sets travis to ignore failures on rubinius. I think it's better to have a reliable build than have to manually check whether the failure is due to a known bug in another library. Ultimately this should be reverted once the bug is resolved.
Hello,
This pull request makes this gem compatible with Rubinius relying on the composition over inheritance technique. Even Rails no longer uses the inheritance pattern (see this article and rails/rails#16299).
For now, there is a compatibility layer that delegates any missing methods to the parts list's
@parts
so it behaves like an array. This is up to you but you may need to deprecate this path and tell people to access#parts
first, then call the given method or provide your very own API (throughEnumerable
for instance).If you want me to squash some commits together let me know !
Refs rubinius/rubinius#3050.
This has been tested under MRI 2.1.2 and 1.9.3, JRuby 1.7.13 and Rubinius 2.2.10.
Have a nice day.