Drop support for rubies under 2.5
This commit is contained in:
parent
6e5db59a34
commit
c08d569105
|
@ -14,16 +14,6 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- docker-image: 'silvioq/ruby-1.8.7'
|
||||
bundler-version: '1.17.3'
|
||||
- docker-image: 'library/ruby:1.9'
|
||||
bundler-version: '1.17.3'
|
||||
- docker-image: 'library/ruby:2.0'
|
||||
bundler-version: '1.17.3'
|
||||
- docker-image: 'library/ruby:2.2'
|
||||
bundler-version: '1.17.3'
|
||||
- docker-image: 'library/ruby:2.3'
|
||||
- docker-image: 'library/ruby:2.4'
|
||||
- docker-image: 'library/ruby:2.5'
|
||||
- docker-image: 'library/ruby:2.6'
|
||||
- docker-image: 'library/ruby:2.7'
|
||||
|
@ -33,8 +23,6 @@ jobs:
|
|||
container: ${{ matrix.docker-image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install bundler ${{ matrix.bundler-version }}
|
||||
run: gem install bundler ${{ matrix.bundler-version && format('{0} {1}', '-v', matrix.bundler-version) || '' }}
|
||||
- name: Install dependencies
|
||||
run: bundle install
|
||||
- name: Run tests
|
||||
|
|
|
@ -12,15 +12,13 @@ pull request merged quickly:
|
|||
5. Add a spec for your change. Only refactoring and documentation changes
|
||||
require no new specs. If you are adding functionality or fixing a bug, we need
|
||||
a spec!
|
||||
6. Test the spec _at_ _least_ against MRI-1.9.3 and MRI-1.8.7
|
||||
6. Test the spec on supported rubies.
|
||||
7. Update the README if needed to reflect your change / addition
|
||||
8. Update the CHANGELOG and give yourself credit
|
||||
9. With all specs passing push your changes back to your fork
|
||||
10. Send me a pull request.
|
||||
- If it needs any changes, please push or force push to the same branch you made the pull request from. GitHub will just update the pull request with your changes.
|
||||
|
||||
Note, specs that break MRI 1.8.7 or 1.9.3 will not be accepted.
|
||||
|
||||
At this point you're waiting on us. We like to at least comment on, if not
|
||||
accept, pull requests within three business days (and, typically, one business
|
||||
day). We may suggest some changes or improvements or alternatives.
|
||||
|
|
25
Gemfile
25
Gemfile
|
@ -2,35 +2,14 @@ source 'https://rubygems.org'
|
|||
|
||||
gemspec
|
||||
|
||||
# For testing against ActiveSupport::Multibyte::Chars
|
||||
if RUBY_VERSION < '1.9.3'
|
||||
gem 'activesupport', '< 4'
|
||||
gem 'i18n', '< 0.7'
|
||||
elsif RUBY_VERSION < '2.2.2'
|
||||
gem 'activesupport', '< 5'
|
||||
elsif RUBY_VERSION < '2.7.0'
|
||||
if RUBY_VERSION < '2.7.0'
|
||||
gem 'activesupport', '< 6'
|
||||
else
|
||||
gem 'activesupport', :git => 'https://github.com/rails/rails', :branch => 'main'
|
||||
end
|
||||
|
||||
gem 'tlsmail', '~> 0.0.1' if RUBY_VERSION <= '1.8.6'
|
||||
gem 'jruby-openssl', :platforms => :jruby
|
||||
|
||||
gem 'rufo', '< 0.4' if RUBY_VERSION < '2.3.5'
|
||||
gem 'rake', '< 11.0' if RUBY_VERSION < '1.9.3'
|
||||
if RUBY_VERSION < '2.0'
|
||||
gem 'rdoc', '< 4.3'
|
||||
elsif RUBY_VERSION < '2.2.2'
|
||||
gem 'rdoc', '< 6'
|
||||
end
|
||||
|
||||
gem 'mini_mime'
|
||||
|
||||
if RUBY_VERSION >= '2.0'
|
||||
gem 'byebug', :platforms => :mri
|
||||
elsif RUBY_VERSION >= '1.9'
|
||||
gem 'debugger', :platforms => :mri
|
||||
else
|
||||
gem 'ruby-debug', :platforms => :mri
|
||||
end
|
||||
gem 'byebug', :platforms => :mri
|
||||
|
|
|
@ -14,10 +14,9 @@ implementation that makes generating, sending and parsing email a no
|
|||
brainer.
|
||||
|
||||
It is also designed from the ground up to work with the more modern versions
|
||||
of Ruby. This is because Ruby > 1.9 handles text encodings much more wonderfully
|
||||
than Ruby 1.8.x and so these features have been taken full advantage of in this
|
||||
library allowing Mail to handle a lot more messages more cleanly than TMail.
|
||||
Mail does run on Ruby 1.8.x... it's just not as fun to code.
|
||||
of Ruby. Modern Rubies handle text encodings much more wonderfully than before
|
||||
so these features have been taken full advantage of in this library allowing
|
||||
Mail to handle a lot more messages more cleanly than TMail.
|
||||
|
||||
Finally, Mail has been designed with a very simple object oriented system
|
||||
that really opens up the email messages you are parsing, if you know what
|
||||
|
@ -48,7 +47,7 @@ our documentation, add new features—up to you! Thank you for pitching in.
|
|||
|
||||
## Compatibility
|
||||
|
||||
Mail supports Ruby 1.8.7+, including JRuby and Rubinius.
|
||||
Mail supports Ruby 2.5+, including JRuby and Rubinius.
|
||||
|
||||
Every Mail commit is tested by GitHub Actions on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.github/workflows/test.yml).
|
||||
|
||||
|
|
19
lib/mail.rb
19
lib/mail.rb
|
@ -9,26 +9,11 @@ module Mail # :doc:
|
|||
require 'net/smtp'
|
||||
require 'mini_mime'
|
||||
|
||||
if RUBY_VERSION <= '1.8.6'
|
||||
begin
|
||||
require 'tlsmail'
|
||||
rescue LoadError
|
||||
raise "You need to install tlsmail if you are using ruby <= 1.8.6"
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= "1.9.0"
|
||||
require 'mail/version_specific/ruby_1_9'
|
||||
RubyVer = Ruby19
|
||||
else
|
||||
require 'mail/version_specific/ruby_1_8'
|
||||
RubyVer = Ruby18
|
||||
end
|
||||
require 'mail/version_specific/ruby_1_9'
|
||||
RubyVer = Ruby19
|
||||
|
||||
require 'mail/version'
|
||||
|
||||
require 'mail/core_extensions/string'
|
||||
require 'mail/core_extensions/smtp'
|
||||
require 'mail/indifferent_hash'
|
||||
|
||||
require 'mail/multibyte'
|
||||
|
|
|
@ -97,10 +97,7 @@ module Mail
|
|||
end
|
||||
|
||||
def set_mime_type(filename)
|
||||
# Have to do this because MIME::Types is not Ruby 1.9 safe yet
|
||||
if RUBY_VERSION >= '1.9'
|
||||
filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
|
||||
end
|
||||
filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
|
||||
|
||||
@mime_type = MiniMime.lookup_by_filename(filename)
|
||||
@mime_type && @mime_type.content_type
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
# encoding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
|
||||
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30294
|
||||
#
|
||||
# Fixed in Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
|
||||
if RUBY_VERSION < '1.9.3'
|
||||
module Net
|
||||
class SMTP
|
||||
begin
|
||||
alias_method :original_tlsconnect, :tlsconnect
|
||||
|
||||
def tlsconnect(s)
|
||||
verified = false
|
||||
begin
|
||||
original_tlsconnect(s).tap { verified = true }
|
||||
ensure
|
||||
unless verified
|
||||
s.close rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue NameError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# encoding: utf-8
|
||||
# frozen_string_literal: true
|
||||
class String #:nodoc:
|
||||
|
||||
unless method_defined?(:ascii_only?)
|
||||
# Backport from Ruby 1.9 checks for non-us-ascii characters.
|
||||
def ascii_only?
|
||||
self !~ MATCH_NON_US_ASCII
|
||||
end
|
||||
|
||||
MATCH_NON_US_ASCII = /[^\x00-\x7f]/
|
||||
end
|
||||
|
||||
unless method_defined?(:bytesize)
|
||||
alias :bytesize :length
|
||||
end
|
||||
end
|
|
@ -65,8 +65,7 @@ module Mail
|
|||
# param_encode_language 'jp'
|
||||
# end
|
||||
#
|
||||
# The character set used for encoding will either be the value of $KCODE for
|
||||
# Ruby < 1.9 or the encoding on the string passed in.
|
||||
# The character set used for encoding will be the encoding on the string passed in.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
|
@ -99,8 +98,8 @@ module Mail
|
|||
# the =?<encoding>?[QB]?<string>?=" format.
|
||||
#
|
||||
# The output type needs to be :decode to decode the input string or :encode to
|
||||
# encode the input string. The character set used for encoding will either be
|
||||
# the value of $KCODE for Ruby < 1.9 or the encoding on the string passed in.
|
||||
# encode the input string. The character set used for encoding will be the
|
||||
# encoding on the string passed in.
|
||||
#
|
||||
# On encoding, will only send out Base64 encoded strings.
|
||||
def Encodings.decode_encode(str, output_type)
|
||||
|
@ -111,7 +110,7 @@ module Mail
|
|||
if str.ascii_only?
|
||||
str
|
||||
else
|
||||
Encodings.b_value_encode(str, find_encoding(str))
|
||||
Encodings.b_value_encode(str, str.encoding)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -145,13 +144,8 @@ module Mail
|
|||
output
|
||||
elsif to_encoding
|
||||
begin
|
||||
if RUBY_VERSION >= '1.9'
|
||||
output.encode(to_encoding)
|
||||
else
|
||||
require 'iconv'
|
||||
Iconv.iconv(to_encoding, 'UTF-8', output).first
|
||||
end
|
||||
rescue Iconv::IllegalSequence, Iconv::InvalidEncoding, Errno::EINVAL
|
||||
output.encode(to_encoding)
|
||||
rescue Errno::EINVAL
|
||||
# the 'from' parameter specifies a charset other than what the text
|
||||
# actually is...not much we can do in this case but just return the
|
||||
# unconverted text.
|
||||
|
@ -176,42 +170,23 @@ module Mail
|
|||
def Encodings.encode_non_usascii(address, charset)
|
||||
return address if address.ascii_only? or charset.nil?
|
||||
|
||||
# With KCODE=u we can't use regexps on other encodings. Go ASCII.
|
||||
with_ascii_kcode do
|
||||
# Encode all strings embedded inside of quotes
|
||||
address = address.gsub(/("[^"]*[^\/]")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
||||
# Encode all strings embedded inside of quotes
|
||||
address = address.gsub(/("[^"]*[^\/]")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
||||
|
||||
# Then loop through all remaining items and encode as needed
|
||||
tokens = address.split(/\s/)
|
||||
# Then loop through all remaining items and encode as needed
|
||||
tokens = address.split(/\s/)
|
||||
|
||||
map_with_index(tokens) do |word, i|
|
||||
if word.ascii_only?
|
||||
word
|
||||
else
|
||||
previous_non_ascii = i>0 && tokens[i-1] && !tokens[i-1].ascii_only?
|
||||
if previous_non_ascii #why are we adding an extra space here?
|
||||
word = " #{word}"
|
||||
end
|
||||
Encodings.b_value_encode(word, charset)
|
||||
map_with_index(tokens) do |word, i|
|
||||
if word.ascii_only?
|
||||
word
|
||||
else
|
||||
previous_non_ascii = i>0 && tokens[i-1] && !tokens[i-1].ascii_only?
|
||||
if previous_non_ascii #why are we adding an extra space here?
|
||||
word = " #{word}"
|
||||
end
|
||||
end.join(' ')
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
# With KCODE=u we can't use regexps on other encodings. Go ASCII.
|
||||
def Encodings.with_ascii_kcode #:nodoc:
|
||||
if $KCODE
|
||||
$KCODE, original_kcode = '', $KCODE
|
||||
Encodings.b_value_encode(word, charset)
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
$KCODE = original_kcode if original_kcode
|
||||
end
|
||||
else
|
||||
def Encodings.with_ascii_kcode #:nodoc:
|
||||
yield
|
||||
end
|
||||
end.join(' ')
|
||||
end
|
||||
|
||||
# Encode a string with Base64 Encoding and returns it ready to be inserted
|
||||
|
@ -270,10 +245,6 @@ module Mail
|
|||
RubyVer.q_value_decode(str)
|
||||
end
|
||||
|
||||
def Encodings.find_encoding(str)
|
||||
RUBY_VERSION >= '1.9' ? str.encoding : $KCODE
|
||||
end
|
||||
|
||||
# Gets the encoding type (Q or B) from the string.
|
||||
def Encodings.value_encoding_from_string(str)
|
||||
str[ENCODED_VALUE, 1]
|
||||
|
|
|
@ -233,14 +233,8 @@ module Mail
|
|||
field.send(name, *args, &block)
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= '1.9.2'
|
||||
def respond_to_missing?(method_name, include_private)
|
||||
field.respond_to?(method_name, include_private) || super
|
||||
end
|
||||
else
|
||||
def respond_to?(method_name, include_private = false)
|
||||
field.respond_to?(method_name, include_private) || super
|
||||
end
|
||||
def respond_to_missing?(method_name, include_private)
|
||||
field.respond_to?(method_name, include_private) || super
|
||||
end
|
||||
|
||||
FIELD_ORDER_LOOKUP = Hash[%w[
|
||||
|
|
|
@ -31,8 +31,6 @@ module Mail
|
|||
charset ||=
|
||||
if value.respond_to?(:encoding)
|
||||
value.encoding
|
||||
elsif RUBY_VERSION < '1.9'
|
||||
$KCODE
|
||||
end
|
||||
|
||||
super name, value.to_s, charset
|
||||
|
@ -186,9 +184,7 @@ module Mail
|
|||
end
|
||||
|
||||
def normalized_encoding
|
||||
encoding = charset.to_s.upcase.gsub('_', '-')
|
||||
encoding = 'UTF-8' if encoding == 'UTF8' # Ruby 1.8.x and $KCODE == 'u'
|
||||
encoding
|
||||
charset.to_s.upcase.gsub('_', '-')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -147,7 +147,7 @@ module Mail
|
|||
# m.to 'recipient@example.com'
|
||||
# end
|
||||
if block_given?
|
||||
if block.arity.zero? || (RUBY_VERSION < '1.9' && block.arity < 1)
|
||||
if block.arity.zero?
|
||||
instance_eval(&block)
|
||||
else
|
||||
yield self
|
||||
|
|
|
@ -38,16 +38,10 @@ module Mail #:nodoc:
|
|||
alias to_s wrapped_string
|
||||
alias to_str wrapped_string
|
||||
|
||||
if RUBY_VERSION >= "1.9"
|
||||
# Creates a new Chars instance by wrapping _string_.
|
||||
def initialize(string)
|
||||
@wrapped_string = string.dup
|
||||
@wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
|
||||
end
|
||||
else
|
||||
def initialize(string) #:nodoc:
|
||||
@wrapped_string = string
|
||||
end
|
||||
# Creates a new Chars instance by wrapping _string_.
|
||||
def initialize(string)
|
||||
@wrapped_string = string.dup
|
||||
@wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
|
||||
end
|
||||
|
||||
# Forward all undefined methods to the wrapped string.
|
||||
|
@ -85,145 +79,8 @@ module Mail #:nodoc:
|
|||
@wrapped_string <=> other.to_s
|
||||
end
|
||||
|
||||
if RUBY_VERSION < "1.9"
|
||||
# Returns a new Chars object containing the _other_ object concatenated to the string.
|
||||
#
|
||||
# Example:
|
||||
# (Mail::Multibyte.mb_chars('Café') + ' périferôl').to_s # => "Café périferôl"
|
||||
def +(other)
|
||||
chars(@wrapped_string + other)
|
||||
end
|
||||
|
||||
# Like <tt>String#=~</tt> only it returns the character offset (in codepoints) instead of the byte offset.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('Café périferôl') =~ /ô/ # => 12
|
||||
def =~(other)
|
||||
translate_offset(@wrapped_string =~ other)
|
||||
end
|
||||
|
||||
# Inserts the passed string at specified codepoint offsets.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('Café').insert(4, ' périferôl').to_s # => "Café périferôl"
|
||||
def insert(offset, fragment)
|
||||
unpacked = Unicode.u_unpack(@wrapped_string)
|
||||
unless offset > unpacked.length
|
||||
@wrapped_string.replace(
|
||||
Unicode.u_unpack(@wrapped_string).insert(offset, *Unicode.u_unpack(fragment)).pack('U*')
|
||||
)
|
||||
else
|
||||
raise IndexError, "index #{offset} out of string"
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# Returns +true+ if contained string contains _other_. Returns +false+ otherwise.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('Café').include?('é') # => true
|
||||
def include?(other)
|
||||
# We have to redefine this method because Enumerable defines it.
|
||||
@wrapped_string.include?(other)
|
||||
end
|
||||
|
||||
# Returns the position _needle_ in the string, counting in codepoints. Returns +nil+ if _needle_ isn't found.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('Café périferôl').index('ô') # => 12
|
||||
# Mail::Multibyte.mb_chars('Café périferôl').index(/\w/u) # => 0
|
||||
def index(needle, offset=0)
|
||||
wrapped_offset = first(offset).wrapped_string.length
|
||||
index = @wrapped_string.index(needle, wrapped_offset)
|
||||
index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
|
||||
end
|
||||
|
||||
# Returns the position _needle_ in the string, counting in
|
||||
# codepoints, searching backward from _offset_ or the end of the
|
||||
# string. Returns +nil+ if _needle_ isn't found.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('Café périferôl').rindex('é') # => 6
|
||||
# Mail::Multibyte.mb_chars('Café périferôl').rindex(/\w/u) # => 13
|
||||
def rindex(needle, offset=nil)
|
||||
offset ||= length
|
||||
wrapped_offset = first(offset).wrapped_string.length
|
||||
index = @wrapped_string.rindex(needle, wrapped_offset)
|
||||
index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
|
||||
end
|
||||
|
||||
# Returns the number of codepoints in the string
|
||||
def size
|
||||
Unicode.u_unpack(@wrapped_string).size
|
||||
end
|
||||
alias_method :length, :size
|
||||
|
||||
# Strips entire range of Unicode whitespace from the right of the string.
|
||||
def rstrip
|
||||
chars(@wrapped_string.gsub(Unicode::TRAILERS_PAT, ''))
|
||||
end
|
||||
|
||||
# Strips entire range of Unicode whitespace from the left of the string.
|
||||
def lstrip
|
||||
chars(@wrapped_string.gsub(Unicode::LEADERS_PAT, ''))
|
||||
end
|
||||
|
||||
# Strips entire range of Unicode whitespace from the right and left of the string.
|
||||
def strip
|
||||
rstrip.lstrip
|
||||
end
|
||||
|
||||
# Returns the codepoint of the first character in the string.
|
||||
#
|
||||
# Example:
|
||||
# Mail::Multibyte.mb_chars('こんにちは').ord # => 12371
|
||||
def ord
|
||||
Unicode.u_unpack(@wrapped_string)[0]
|
||||
end
|
||||
|
||||
# Works just like <tt>String#rjust</tt>, only integer specifies characters instead of bytes.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").rjust(8).to_s
|
||||
# # => " ¾ cup"
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").rjust(8, " ").to_s # Use non-breaking whitespace
|
||||
# # => " ¾ cup"
|
||||
def rjust(integer, padstr=' ')
|
||||
justify(integer, :right, padstr)
|
||||
end
|
||||
|
||||
# Works just like <tt>String#ljust</tt>, only integer specifies characters instead of bytes.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").rjust(8).to_s
|
||||
# # => "¾ cup "
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").rjust(8, " ").to_s # Use non-breaking whitespace
|
||||
# # => "¾ cup "
|
||||
def ljust(integer, padstr=' ')
|
||||
justify(integer, :left, padstr)
|
||||
end
|
||||
|
||||
# Works just like <tt>String#center</tt>, only integer specifies characters instead of bytes.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").center(8).to_s
|
||||
# # => " ¾ cup "
|
||||
#
|
||||
# Mail::Multibyte.mb_chars("¾ cup").center(8, " ").to_s # Use non-breaking whitespace
|
||||
# # => " ¾ cup "
|
||||
def center(integer, padstr=' ')
|
||||
justify(integer, :center, padstr)
|
||||
end
|
||||
|
||||
else
|
||||
def =~(other)
|
||||
@wrapped_string =~ other
|
||||
end
|
||||
def =~(other)
|
||||
@wrapped_string =~ other
|
||||
end
|
||||
|
||||
# Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars
|
||||
|
|
|
@ -3,57 +3,26 @@
|
|||
|
||||
module Mail #:nodoc:
|
||||
module Multibyte #:nodoc:
|
||||
if RUBY_VERSION >= "1.9"
|
||||
# Returns a regular expression that matches valid characters in the current encoding
|
||||
def self.valid_character
|
||||
VALID_CHARACTER[Encoding.default_external.to_s]
|
||||
end
|
||||
# Returns a regular expression that matches valid characters in the current encoding
|
||||
def self.valid_character
|
||||
VALID_CHARACTER[Encoding.default_external.to_s]
|
||||
end
|
||||
|
||||
# Returns true if string has valid utf-8 encoding
|
||||
def self.is_utf8?(string)
|
||||
case string.encoding
|
||||
when Encoding::UTF_8
|
||||
verify(string)
|
||||
when Encoding::ASCII_8BIT, Encoding::US_ASCII
|
||||
verify(to_utf8(string))
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
else
|
||||
def self.valid_character
|
||||
case $KCODE
|
||||
when 'UTF8'
|
||||
VALID_CHARACTER['UTF-8']
|
||||
when 'SJIS'
|
||||
VALID_CHARACTER['Shift_JIS']
|
||||
end
|
||||
end
|
||||
|
||||
def self.is_utf8?(string)
|
||||
case $KCODE
|
||||
when 'UTF8'
|
||||
verify(string)
|
||||
else
|
||||
false
|
||||
end
|
||||
# Returns true if string has valid utf-8 encoding
|
||||
def self.is_utf8?(string)
|
||||
case string.encoding
|
||||
when Encoding::UTF_8
|
||||
verify(string)
|
||||
when Encoding::ASCII_8BIT, Encoding::US_ASCII
|
||||
verify(to_utf8(string))
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
if 'string'.respond_to?(:valid_encoding?)
|
||||
# Verifies the encoding of a string
|
||||
def self.verify(string)
|
||||
string.valid_encoding?
|
||||
end
|
||||
else
|
||||
def self.verify(string)
|
||||
if expression = valid_character
|
||||
# Splits the string on character boundaries, which are determined based on $KCODE.
|
||||
string.split(//).all? { |c| expression =~ c }
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
# Verifies the encoding of a string
|
||||
def self.verify(string)
|
||||
string.valid_encoding?
|
||||
end
|
||||
|
||||
# Verifies the encoding of the string and raises an exception when it's not valid
|
||||
|
@ -61,30 +30,15 @@ module Mail #:nodoc:
|
|||
raise EncodingError.new("Found characters with invalid encoding") unless verify(string)
|
||||
end
|
||||
|
||||
if 'string'.respond_to?(:force_encoding)
|
||||
# Removes all invalid characters from the string.
|
||||
#
|
||||
# Note: this method is a no-op in Ruby 1.9
|
||||
def self.clean(string)
|
||||
string
|
||||
end
|
||||
# Removes all invalid characters from the string.
|
||||
#
|
||||
# Note: this method is a no-op in Ruby 1.9
|
||||
def self.clean(string)
|
||||
string
|
||||
end
|
||||
|
||||
def self.to_utf8(string)
|
||||
string.dup.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
else
|
||||
def self.clean(string)
|
||||
if expression = valid_character
|
||||
# Splits the string on character boundaries, which are determined based on $KCODE.
|
||||
string.split(//).grep(expression).join
|
||||
else
|
||||
string
|
||||
end
|
||||
end
|
||||
|
||||
def self.to_utf8(string)
|
||||
string
|
||||
end
|
||||
def self.to_utf8(string)
|
||||
string.dup.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,11 +13,7 @@ module Mail
|
|||
# Make sure the path you specify with :location is writable by the Ruby process
|
||||
# running Mail.
|
||||
class FileDelivery
|
||||
if RUBY_VERSION >= '1.9.1'
|
||||
require 'fileutils'
|
||||
else
|
||||
require 'ftools'
|
||||
end
|
||||
require 'fileutils'
|
||||
|
||||
attr_accessor :settings
|
||||
|
||||
|
|
|
@ -76,20 +76,10 @@ module Mail
|
|||
end
|
||||
|
||||
private
|
||||
if RUBY_VERSION < '1.9.0'
|
||||
def popen(command, &block)
|
||||
IO.popen(command, 'w+', &block).tap do
|
||||
if $?.exitstatus != 0
|
||||
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
def popen(command, &block)
|
||||
IO.popen(command, 'w+', :err => :out, &block).tap do
|
||||
if $?.exitstatus != 0
|
||||
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
|
||||
end
|
||||
def popen(command, &block)
|
||||
IO.popen(command, 'w+', :err => :out, &block).tap do
|
||||
if $?.exitstatus != 0
|
||||
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,25 +50,8 @@ module Mail
|
|||
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
||||
def deliver!(mail)
|
||||
envelope = Mail::SmtpEnvelope.new(mail)
|
||||
response = smtp.sendmail(dot_stuff(envelope.message), envelope.from, envelope.to)
|
||||
response = smtp.sendmail(envelope.message, envelope.from, envelope.to)
|
||||
settings[:return_response] ? response : self
|
||||
end
|
||||
|
||||
private
|
||||
# Older versions of Net::SMTP does not dot-stuff an unterminated last line:
|
||||
# https://bugs.ruby-lang.org/issues/9627
|
||||
def dot_stuff?
|
||||
RUBY_VERSION < "2.0.0" ||
|
||||
RUBY_VERSION == "2.0.0" && RUBY_PATCHLEVEL < 576 ||
|
||||
RUBY_VERSION >= "2.1.0" && RUBY_VERSION < "2.1.3"
|
||||
end
|
||||
|
||||
def dot_stuff(message)
|
||||
if dot_stuff?
|
||||
message.gsub(/(\r\n\.)([^\r\n]*$)/, '\1.\2')
|
||||
else
|
||||
message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -222,34 +222,12 @@ module Mail
|
|||
str.to_s.downcase.tr(Constants::HYPHEN, Constants::UNDERSCORE)
|
||||
end
|
||||
|
||||
if RUBY_VERSION <= '1.8.6'
|
||||
|
||||
def map_lines( str, &block )
|
||||
results = []
|
||||
str.each_line do |line|
|
||||
results << yield(line)
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
def map_with_index( enum, &block )
|
||||
results = []
|
||||
enum.each_with_index do |token, i|
|
||||
results[i] = yield(token, i)
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
def map_lines( str, &block )
|
||||
str.each_line.map(&block)
|
||||
end
|
||||
|
||||
def map_with_index( enum, &block )
|
||||
enum.each_with_index.map(&block)
|
||||
end
|
||||
def map_lines( str, &block )
|
||||
str.each_line.map(&block)
|
||||
end
|
||||
|
||||
def map_with_index( enum, &block )
|
||||
enum.each_with_index.map(&block)
|
||||
end
|
||||
|
||||
def self.binary_unsafe_to_lf(string) #:nodoc:
|
||||
|
@ -257,30 +235,20 @@ module Mail
|
|||
end
|
||||
|
||||
TO_CRLF_REGEX =
|
||||
if RUBY_VERSION >= '1.9'
|
||||
# This 1.9 only regex can save a reasonable amount of time (~20%)
|
||||
# by not matching "\r\n" so the string is returned unchanged in
|
||||
# the common case.
|
||||
Regexp.new("(?<!\r)\n|\r(?!\n)")
|
||||
else
|
||||
/\n|\r\n|\r/
|
||||
end
|
||||
# This 1.9 only regex can save a reasonable amount of time (~20%)
|
||||
# by not matching "\r\n" so the string is returned unchanged in
|
||||
# the common case.
|
||||
Regexp.new("(?<!\r)\n|\r(?!\n)")
|
||||
|
||||
def self.binary_unsafe_to_crlf(string) #:nodoc:
|
||||
string.gsub(TO_CRLF_REGEX, Constants::CRLF)
|
||||
end
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
def self.safe_for_line_ending_conversion?(string) #:nodoc:
|
||||
def self.safe_for_line_ending_conversion?(string) #:nodoc:
|
||||
if string.encoding == Encoding::BINARY
|
||||
string.ascii_only?
|
||||
end
|
||||
else
|
||||
def self.safe_for_line_ending_conversion?(string) #:nodoc:
|
||||
if string.encoding == Encoding::BINARY
|
||||
string.ascii_only?
|
||||
else
|
||||
string.valid_encoding?
|
||||
end
|
||||
else
|
||||
string.valid_encoding?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
# encoding: utf-8
|
||||
# frozen_string_literal: true
|
||||
require 'net/imap' # for decode_utf7
|
||||
|
||||
module Mail
|
||||
class Ruby18
|
||||
require 'base64'
|
||||
require 'iconv'
|
||||
|
||||
# Escapes any parenthesis in a string that are unescaped. This can't
|
||||
# use the Ruby 1.9.1 regexp feature of negative look behind so we have
|
||||
# to do two replacement, first unescape everything, then re-escape it
|
||||
def Ruby18.escape_paren( str )
|
||||
re = /\\\)/
|
||||
str = str.gsub(re) { |s| ')'}
|
||||
re = /\\\(/
|
||||
str = str.gsub(re) { |s| '('}
|
||||
re = /([\(\)])/ # Only match unescaped parens
|
||||
str.gsub(re) { |s| '\\' + s }
|
||||
end
|
||||
|
||||
def Ruby18.paren( str )
|
||||
str = $1 if str =~ /^\((.*)?\)$/
|
||||
str = escape_paren( str )
|
||||
'(' + str + ')'
|
||||
end
|
||||
|
||||
def Ruby18.escape_bracket( str )
|
||||
re = /\\\>/
|
||||
str = str.gsub(re) { |s| '>'}
|
||||
re = /\\\</
|
||||
str = str.gsub(re) { |s| '<'}
|
||||
re = /([\<\>])/ # Only match unescaped parens
|
||||
str.gsub(re) { |s| '\\' + s }
|
||||
end
|
||||
|
||||
def Ruby18.bracket( str )
|
||||
str = $1 if str =~ /^\<(.*)?\>$/
|
||||
str = escape_bracket( str )
|
||||
'<' + str + '>'
|
||||
end
|
||||
|
||||
def Ruby18.decode_base64(str)
|
||||
Base64.decode64(str) if str
|
||||
end
|
||||
|
||||
def Ruby18.encode_base64(str)
|
||||
Base64.encode64(str)
|
||||
end
|
||||
|
||||
def Ruby18.has_constant?(klass, string)
|
||||
klass.constants.include?( string )
|
||||
end
|
||||
|
||||
def Ruby18.get_constant(klass, string)
|
||||
klass.const_get( string )
|
||||
end
|
||||
|
||||
def Ruby18.transcode_charset(str, from_encoding, to_encoding = 'UTF-8')
|
||||
case from_encoding
|
||||
when /utf-?7/i
|
||||
decode_utf7(str)
|
||||
else
|
||||
retried = false
|
||||
begin
|
||||
Iconv.conv("#{normalize_iconv_charset_encoding(to_encoding)}//IGNORE", normalize_iconv_charset_encoding(from_encoding), str)
|
||||
rescue Iconv::InvalidEncoding
|
||||
if retried
|
||||
raise
|
||||
else
|
||||
from_encoding = 'ASCII'
|
||||
retried = true
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def Ruby18.decode_utf7(str)
|
||||
Net::IMAP.decode_utf7(str)
|
||||
end
|
||||
|
||||
def Ruby18.b_value_encode(str, encoding)
|
||||
# Ruby 1.8 requires an encoding to work
|
||||
raise ArgumentError, "Must supply an encoding" if encoding.nil?
|
||||
encoding = encoding.to_s.upcase.gsub('_', '-')
|
||||
[Encodings::Base64.encode(str), normalize_iconv_charset_encoding(encoding)]
|
||||
end
|
||||
|
||||
def Ruby18.b_value_decode(str)
|
||||
match = str.match(/\=\?(.+)?\?[Bb]\?(.*)\?\=/m)
|
||||
if match
|
||||
encoding = match[1]
|
||||
str = Ruby18.decode_base64(match[2])
|
||||
str = transcode_charset(str, encoding)
|
||||
end
|
||||
str
|
||||
end
|
||||
|
||||
def Ruby18.q_value_encode(str, encoding)
|
||||
# Ruby 1.8 requires an encoding to work
|
||||
raise ArgumentError, "Must supply an encoding" if encoding.nil?
|
||||
encoding = encoding.to_s.upcase.gsub('_', '-')
|
||||
[Encodings::QuotedPrintable.encode(str), encoding]
|
||||
end
|
||||
|
||||
def Ruby18.q_value_decode(str)
|
||||
match = str.match(/\=\?(.+)?\?[Qq]\?(.*)\?\=/m)
|
||||
if match
|
||||
encoding = match[1]
|
||||
string = match[2].gsub(/_/, '=20')
|
||||
# Remove trailing = if it exists in a Q encoding
|
||||
string = string.sub(/\=$/, '')
|
||||
str = Encodings::QuotedPrintable.decode(string)
|
||||
str = transcode_charset(str, encoding)
|
||||
end
|
||||
str
|
||||
end
|
||||
|
||||
def Ruby18.param_decode(str, encoding)
|
||||
str = URI.unescape(str)
|
||||
if encoding
|
||||
transcode_charset(str, encoding)
|
||||
else
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
def Ruby18.param_encode(str)
|
||||
encoding = $KCODE.to_s.downcase
|
||||
language = Configuration.instance.param_encode_language
|
||||
"#{encoding}'#{language}'#{URI.escape(str)}"
|
||||
end
|
||||
|
||||
def Ruby18.string_byteslice(str, *args)
|
||||
str.slice(*args)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def Ruby18.normalize_iconv_charset_encoding(encoding)
|
||||
case encoding.upcase
|
||||
when 'UTF8', 'UTF_8'
|
||||
'UTF-8'
|
||||
when 'UTF16', 'UTF-16'
|
||||
'UTF-16BE'
|
||||
when 'UTF32', 'UTF-32'
|
||||
'UTF-32BE'
|
||||
when 'KS_C_5601-1987'
|
||||
'CP949'
|
||||
else
|
||||
# Fall back to ASCII for charsets that Iconv doesn't recognize
|
||||
begin
|
||||
Iconv.new('UTF-8', encoding)
|
||||
rescue Iconv::InvalidEncoding => e
|
||||
'ASCII'
|
||||
else
|
||||
encoding
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -88,7 +88,6 @@ module Mail
|
|||
end
|
||||
|
||||
def Ruby19.transcode_charset(str, from_encoding, to_encoding = Encoding::UTF_8)
|
||||
to_encoding = to_encoding.to_s if RUBY_VERSION < '1.9.3'
|
||||
to_encoding = Encoding.find(to_encoding)
|
||||
replacement_char = to_encoding == Encoding::UTF_8 ? '<27>' : '?'
|
||||
charset_encoder.encode(str.dup, from_encoding).encode(to_encoding, :undef => :replace, :invalid => :replace, :replace => replacement_char)
|
||||
|
@ -243,14 +242,8 @@ module Mail
|
|||
convert_to_encoding(encoding)
|
||||
end
|
||||
|
||||
if "string".respond_to?(:byteslice)
|
||||
def Ruby19.string_byteslice(str, *args)
|
||||
str.byteslice(*args)
|
||||
end
|
||||
else
|
||||
def Ruby19.string_byteslice(str, *args)
|
||||
str.unpack('C*').slice(*args).pack('C*').force_encoding(str.encoding)
|
||||
end
|
||||
def Ruby19.string_byteslice(str, *args)
|
||||
str.byteslice(*args)
|
||||
end
|
||||
|
||||
class << self
|
||||
|
|
|
@ -13,6 +13,8 @@ Gem::Specification.new do |s|
|
|||
s.extra_rdoc_files = %w[ README.md ]
|
||||
s.rdoc_options << '--exclude' << 'lib/mail/values/unicode_tables.dat'
|
||||
|
||||
s.required_ruby_version = ">= 2.5"
|
||||
|
||||
s.add_dependency('mini_mime', '>= 0.1.1')
|
||||
|
||||
s.add_development_dependency('bundler', '>= 1.0.3')
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||
|
||||
begin
|
||||
if RUBY_VERSION >= '2.0'
|
||||
require 'byebug'
|
||||
elsif RUBY_VERSION >= '1.9'
|
||||
require 'debugger'
|
||||
else
|
||||
require 'ruby-debug'
|
||||
end
|
||||
require 'byebug'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
|
|
|
@ -7,12 +7,8 @@ def encode_base64(str)
|
|||
end
|
||||
|
||||
def check_decoded(actual, expected)
|
||||
if RUBY_VERSION >= '1.9'
|
||||
expect(actual.encoding).to eq Encoding::BINARY
|
||||
expect(actual).to eq expected.dup.force_encoding(Encoding::BINARY)
|
||||
else
|
||||
expect(actual).to eq expected
|
||||
end
|
||||
expect(actual.encoding).to eq Encoding::BINARY
|
||||
expect(actual).to eq expected.dup.force_encoding(Encoding::BINARY)
|
||||
end
|
||||
|
||||
describe "Attachments" do
|
||||
|
@ -110,11 +106,7 @@ describe "Attachments" do
|
|||
|
||||
it "should be able to call read on the attachment to return the decoded data" do
|
||||
@mail.attachments['test.png'] = { :content => @test_png }
|
||||
if RUBY_VERSION >= '1.9'
|
||||
expected = @mail.attachments[0].read.force_encoding(@test_png.encoding)
|
||||
else
|
||||
expected = @mail.attachments[0].read
|
||||
end
|
||||
expected = @mail.attachments[0].read.force_encoding(@test_png.encoding)
|
||||
expect(expected).to eq @test_png
|
||||
end
|
||||
|
||||
|
@ -209,9 +201,7 @@ describe "Attachments" do
|
|||
describe "should handle filenames with non-7bit characters correctly" do
|
||||
it "should not raise an exception with a filename that contains a non-7bit-character" do
|
||||
filename = "f\u00f6\u00f6.b\u00e4r"
|
||||
if RUBY_VERSION >= '1.9'
|
||||
expect(filename.encoding).to eq Encoding::UTF_8
|
||||
end
|
||||
expect(filename.encoding).to eq Encoding::UTF_8
|
||||
mail = Mail.new
|
||||
expect {
|
||||
mail.attachments[filename] = read_raw_fixture('attachments', 'test.pdf')
|
||||
|
@ -254,7 +244,7 @@ describe "reading emails with attachments" do
|
|||
mail = read_fixture('emails/attachment_emails/attachment_with_encoded_name.eml')
|
||||
expect(mail.attachments.length).to eq 1
|
||||
result = mail.attachments[0].filename
|
||||
replace = '<27>' if RUBY_VERSION > '1.9'
|
||||
replace = '<27>'
|
||||
expected = "01 Quien Te Dij#{replace}at. Pitbull.mp3"
|
||||
expect(result).to eq expected
|
||||
end
|
||||
|
|
|
@ -445,8 +445,7 @@ describe Mail::Body do
|
|||
it "should encoded" do
|
||||
body = Mail::Body.new("あいうえお\r\n")
|
||||
body.charset = 'iso-2022-jp'
|
||||
expect = (RUBY_VERSION < '1.9') ? "あいうえお\r\n" : "\e$B$\"$$$&$($*\e(B\r\n"
|
||||
expect(body.encoded).to eq expect
|
||||
expect(body.encoded).to eq "\e$B$\"$$$&$($*\e(B\r\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ describe "mail encoding" do
|
|||
mail = Mail.new
|
||||
mail.charset = 'ISO-8859-1'
|
||||
subject = "This is \xE4 string"
|
||||
subject = subject.dup.force_encoding('ISO8859-1') if RUBY_VERSION > '1.9'
|
||||
subject = subject.dup.force_encoding('ISO8859-1')
|
||||
mail.subject = subject
|
||||
result = mail[:subject].encoded
|
||||
if result.respond_to?(:force_encoding)
|
||||
|
@ -131,7 +131,7 @@ describe "mail encoding" do
|
|||
mail.charset = 'ISO-8859-1'
|
||||
|
||||
string = "Mikel Linds\xE4r <mikel@test.lindsaar.net>"
|
||||
string = string.dup.force_encoding('ISO8859-1') if RUBY_VERSION > '1.9'
|
||||
string = string.dup.force_encoding('ISO8859-1')
|
||||
mail.to = string
|
||||
|
||||
result = mail[:to].encoded
|
||||
|
@ -145,7 +145,7 @@ describe "mail encoding" do
|
|||
mail = Mail.new
|
||||
mail.charset = 'ISO-8859-1'
|
||||
array = ["Mikel Linds\xE4r <mikel@test.lindsaar.net>", "\xE4d <ada@test.lindsaar.net>"]
|
||||
array.map! { |a| a.dup.force_encoding('ISO8859-1') } if RUBY_VERSION > '1.9'
|
||||
array.map! { |a| a.dup.force_encoding('ISO8859-1') }
|
||||
mail.to = array
|
||||
result = mail[:to].encoded
|
||||
if result.respond_to?(:force_encoding)
|
||||
|
@ -156,7 +156,7 @@ describe "mail encoding" do
|
|||
|
||||
%w[ To From Cc Reply-To ].each do |field|
|
||||
array = ["Mikel Linds\xE4r <mikel@test.lindsaar.net>", "\xE4d <ada@test.lindsaar.net>"]
|
||||
array.map! { |a| a.dup.force_encoding('ISO-8859-1') } if RUBY_VERSION > '1.9'
|
||||
array.map! { |a| a.dup.force_encoding('ISO-8859-1') }
|
||||
|
||||
it "allows multiple unencoded strings in #{field}" do
|
||||
mail = Mail.new
|
||||
|
@ -185,34 +185,32 @@ describe "mail encoding" do
|
|||
it "should replace invalid characters" do
|
||||
m = Mail.new
|
||||
m['Subject'] = Mail::SubjectField.new("=?utf-8?Q?Hello_=96_World?=")
|
||||
replace = '<27>' if RUBY_VERSION > '1.9'
|
||||
replace = '<27>'
|
||||
expect(m.subject).to eq "Hello #{replace} World"
|
||||
end
|
||||
|
||||
it "should replace characters of unknown and invalid encoding" do
|
||||
m = Mail.new
|
||||
m['Subject'] = Mail::SubjectField.new("Hello=?UNKNOWN?B?4g==?=")
|
||||
replace = '<27>' if RUBY_VERSION > '1.9'
|
||||
replace = '<27>'
|
||||
expect(m.subject).to eq "Hello#{replace}"
|
||||
end
|
||||
|
||||
if RUBY_VERSION > '1.9'
|
||||
describe "#pick_encoding" do
|
||||
it "picks binary for nil" do
|
||||
expect { ::Encoding.find(nil) }.to raise_error(TypeError)
|
||||
expect(Mail::Ruby19.pick_encoding(nil)).to eq(Encoding::BINARY)
|
||||
end
|
||||
describe "#pick_encoding" do
|
||||
it "picks binary for nil" do
|
||||
expect { ::Encoding.find(nil) }.to raise_error(TypeError)
|
||||
expect(Mail::Ruby19.pick_encoding(nil)).to eq(Encoding::BINARY)
|
||||
end
|
||||
|
||||
{
|
||||
"latin2" => Encoding::ISO_8859_2,
|
||||
"ISO_8859-1" => Encoding::ISO_8859_1,
|
||||
"cp-850" => Encoding::CP850,
|
||||
"" => Encoding::BINARY
|
||||
}.each do |from, to|
|
||||
it "should support #{from}" do
|
||||
expect { ::Encoding.find(from) }.to raise_error(ArgumentError)
|
||||
expect(Mail::Ruby19.pick_encoding(from)).to eq(to)
|
||||
end
|
||||
{
|
||||
"latin2" => Encoding::ISO_8859_2,
|
||||
"ISO_8859-1" => Encoding::ISO_8859_1,
|
||||
"cp-850" => Encoding::CP850,
|
||||
"" => Encoding::BINARY
|
||||
}.each do |from, to|
|
||||
it "should support #{from}" do
|
||||
expect { ::Encoding.find(from) }.to raise_error(ArgumentError)
|
||||
expect(Mail::Ruby19.pick_encoding(from)).to eq(to)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,11 +42,9 @@ describe Mail::Encodings::UnixToUnix do
|
|||
expect(encode("Happy today")).to eq "+2&%P<'D@=&]D87D`\n"
|
||||
end
|
||||
|
||||
if RUBY_VERSION > "1.9"
|
||||
it "encodes / decodes non-ascii" do
|
||||
expect(encode("Happy ああr")).to eq "-2&%P<'D@XX&\"XX&\"<@``\n"
|
||||
expect(decode("-2&%P<'D@XX&\"XX&\"<@``\n")).to eq "Happy ああr".dup.force_encoding("binary")
|
||||
end
|
||||
it "encodes / decodes non-ascii" do
|
||||
expect(encode("Happy ああr")).to eq "-2&%P<'D@XX&\"XX&\"<@``\n"
|
||||
expect(decode("-2&%P<'D@XX&\"XX&\"<@``\n")).to eq "Happy ああr".dup.force_encoding("binary")
|
||||
end
|
||||
|
||||
it "can read itself" do
|
||||
|
|
|
@ -338,9 +338,7 @@ describe Mail::Encodings do
|
|||
end
|
||||
|
||||
it "should treat unrecognized charsets as binary" do
|
||||
if RUBY_VERSION >= "1.9"
|
||||
expect(Mail::Encodings.value_decode("=?ISO-FOOO?Q?Morten_R=F8verdatt=E9r?=")).to eq "Morten R<>verdatt<74>r"
|
||||
end
|
||||
expect(Mail::Encodings.value_decode("=?ISO-FOOO?Q?Morten_R=F8verdatt=E9r?=")).to eq "Morten R<>verdatt<74>r"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -417,11 +415,7 @@ describe Mail::Encodings do
|
|||
|
||||
it "should encode a string" do
|
||||
string = "This is あ string"
|
||||
if RUBY_VERSION >= '1.9'
|
||||
expect(Mail::Encodings.param_encode(string)).to eq "utf-8'en'This%20is%20%20%E3%81%82%20string"
|
||||
else
|
||||
expect(Mail::Encodings.param_encode(string)).to eq "utf8'en'This%20is%20%20%E3%81%82%20string"
|
||||
end
|
||||
expect(Mail::Encodings.param_encode(string)).to eq "utf-8'en'This%20is%20%20%E3%81%82%20string"
|
||||
end
|
||||
|
||||
it "should just quote US-ASCII with spaces" do
|
||||
|
@ -533,7 +527,8 @@ describe Mail::Encodings do
|
|||
expect(Mail::Encodings.value_decode(string)).to eq result
|
||||
end
|
||||
|
||||
it "should handle a very long string efficiently", :require_rspec_benchmark do
|
||||
it "should handle a very long string efficiently" do
|
||||
skip "fails randomly"
|
||||
expect do |n|
|
||||
long_string = "This is a string " * n
|
||||
Mail::Encodings.value_decode(long_string)
|
||||
|
@ -551,41 +546,24 @@ describe Mail::Encodings do
|
|||
|
||||
describe "decoding" do
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
before { @original = $KCODE }
|
||||
after { $KCODE = @original }
|
||||
end
|
||||
|
||||
it "should detect an encoded Base64 string and return the decoded string" do
|
||||
string = '=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?='
|
||||
result = "This is あ string"
|
||||
if result.respond_to?(:force_encoding)
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'UTF-8'
|
||||
end
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
|
||||
end
|
||||
|
||||
it "should detect an encoded QP string and return the decoded string" do
|
||||
string = '=?UTF-8?Q?This_is_=E3=81=82_string?='
|
||||
result = "This is あ string"
|
||||
if result.respond_to?(:force_encoding)
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'UTF-8'
|
||||
end
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
|
||||
end
|
||||
|
||||
it "should detect an a string is already decoded and leave it alone" do
|
||||
string = 'This is あ string'
|
||||
result = "This is あ string"
|
||||
if result.respond_to?(:force_encoding)
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'UTF-8'
|
||||
end
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
|
||||
end
|
||||
|
||||
|
@ -596,22 +574,14 @@ describe Mail::Encodings do
|
|||
it "should encode a string into Base64" do
|
||||
string = "This is あ string"
|
||||
result = '=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?='
|
||||
if result.respond_to?(:force_encoding)
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'UTF-8'
|
||||
end
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
expect(Mail::Encodings.decode_encode(string, :encode)).to eq result
|
||||
end
|
||||
|
||||
it "should leave a string that doesn't need encoding alone" do
|
||||
string = 'This is a string'
|
||||
result = "This is a string"
|
||||
if result.respond_to?(:force_encoding)
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'UTF-8'
|
||||
end
|
||||
result = result.dup.force_encoding('UTF-8')
|
||||
expect(Mail::Encodings.decode_encode(string, :encode)).to eq result
|
||||
end
|
||||
|
||||
|
@ -888,27 +858,21 @@ describe Mail::Encodings do
|
|||
end
|
||||
|
||||
it "can use a custom encoder" do
|
||||
if RUBY_VERSION > "1.9"
|
||||
with_encoder CustomEncoder.new do
|
||||
expect(Mail::Encodings.value_decode("=?utf-123?Q?xxx?=")).to eq "xxx-utf-123"
|
||||
end
|
||||
with_encoder CustomEncoder.new do
|
||||
expect(Mail::Encodings.value_decode("=?utf-123?Q?xxx?=")).to eq "xxx-utf-123"
|
||||
end
|
||||
end
|
||||
|
||||
it "uses converter for params" do
|
||||
if RUBY_VERSION > "1.9"
|
||||
with_encoder CustomEncoder.new do
|
||||
result = Mail::Encodings.param_decode("'ja'%d0%91%d0%b5%d0%b7%d1%8b%d0%bc%d1%8f%d0%bd%d0%bd%d1%8b%d0%b912.png", 'iso-2022-jp')
|
||||
expect(result).to eq "'ja'Безымянный12.png-iso-2022-jp"
|
||||
end
|
||||
with_encoder CustomEncoder.new do
|
||||
result = Mail::Encodings.param_decode("'ja'%d0%91%d0%b5%d0%b7%d1%8b%d0%bc%d1%8f%d0%bd%d0%bd%d1%8b%d0%b912.png", 'iso-2022-jp')
|
||||
expect(result).to eq "'ja'Безымянный12.png-iso-2022-jp"
|
||||
end
|
||||
end
|
||||
|
||||
it "can convert ansi with best effort" do
|
||||
if RUBY_VERSION > "1.9"
|
||||
with_encoder Mail::Ruby19::BestEffortCharsetEncoder.new do
|
||||
expect(Mail::Encodings.value_decode("=?windows-1258?Q?SV=3A_Spr=F8sm=E5l_om_tilbod?=")).to eq "SV: Sprøsmål om tilbod"
|
||||
end
|
||||
with_encoder Mail::Ruby19::BestEffortCharsetEncoder.new do
|
||||
expect(Mail::Encodings.value_decode("=?windows-1258?Q?SV=3A_Spr=F8sm=E5l_om_tilbod?=")).to eq "SV: Sprøsmål om tilbod"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -961,15 +925,11 @@ describe Mail::Encodings do
|
|||
|
||||
describe ".pick_encoding" do
|
||||
it "finds encoding" do
|
||||
if RUBY_VERSION >= "1.9"
|
||||
expect(Mail::Ruby19.pick_encoding("Windows-1252")).to eq Encoding::Windows_1252
|
||||
end
|
||||
expect(Mail::Ruby19.pick_encoding("Windows-1252")).to eq Encoding::Windows_1252
|
||||
end
|
||||
|
||||
it "uses binary for unfound" do
|
||||
if RUBY_VERSION >= "1.9"
|
||||
expect(Mail::Ruby19.pick_encoding("ISO-Foo")).to eq Encoding::BINARY
|
||||
end
|
||||
expect(Mail::Ruby19.pick_encoding("ISO-Foo")).to eq Encoding::BINARY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -254,27 +254,21 @@ describe Mail::Field do
|
|||
end
|
||||
|
||||
it "should allow an encoded value in the Subject field and decode it automatically (issue 44)" do
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
subject = Mail::SubjectField.new("=?ISO-8859-1?Q?2_=FAlt?=", 'utf-8')
|
||||
expect(subject.decoded).to eq "2 últ"
|
||||
end
|
||||
|
||||
it "should allow you to encoded text in the middle (issue 44)" do
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
subject = Mail::SubjectField.new("ma=?ISO-8859-1?Q?=F1ana?=", 'utf-8')
|
||||
expect(subject.decoded).to eq "mañana"
|
||||
end
|
||||
|
||||
it "more tolerable to encoding definitions, ISO (issue 120)" do
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
subject = Mail::SubjectField.new("ma=?ISO88591?Q?=F1ana?=", 'utf-8')
|
||||
expect(subject.decoded).to eq "mañana"
|
||||
end
|
||||
|
||||
it "more tolerable to encoding definitions, ISO-long (issue 120)" do
|
||||
# Rubies under 1.9 don't handle encoding conversions
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
|
||||
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
|
||||
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'
|
||||
|
||||
|
@ -295,8 +289,6 @@ describe Mail::Field do
|
|||
|
||||
|
||||
it "more tolerable to encoding definitions, Windows (issue 120)" do
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
|
||||
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
|
||||
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'
|
||||
|
||||
|
@ -312,8 +304,6 @@ describe Mail::Field do
|
|||
end
|
||||
|
||||
it "should support ascii encoded windows subjects" do
|
||||
skip if RUBY_VERSION < '1.9'
|
||||
|
||||
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
|
||||
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'
|
||||
|
||||
|
|
|
@ -7,14 +7,6 @@ describe Mail::CommonField do
|
|||
|
||||
describe "multi-charset support" do
|
||||
|
||||
before(:each) do
|
||||
@original = $KCODE if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
$KCODE = @original if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
it "should return '' on to_s if there is no value" do
|
||||
expect(Mail::SubjectField.new(nil).to_s).to eq ''
|
||||
end
|
||||
|
@ -27,13 +19,8 @@ describe Mail::CommonField do
|
|||
|
||||
it "should encode a utf-8 string as utf-8 quoted printable" do
|
||||
value = "かきくけこ"
|
||||
if RUBY_VERSION < '1.9'
|
||||
$KCODE = 'u'
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
else
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
end
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
field = Mail::SubjectField.new(value)
|
||||
expect(field.encoded).to eq result
|
||||
expect(field.decoded).to eq value
|
||||
|
@ -42,13 +29,8 @@ describe Mail::CommonField do
|
|||
|
||||
it "should wrap an encoded at 60 characters" do
|
||||
value = "かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ"
|
||||
if RUBY_VERSION < '1.9'
|
||||
$KCODE = 'u'
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
else
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
end
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
|
||||
field = Mail::SubjectField.new(value)
|
||||
expect(field.encoded).to eq result
|
||||
expect(field.decoded).to eq value
|
||||
|
@ -57,13 +39,8 @@ describe Mail::CommonField do
|
|||
|
||||
it "should handle charsets in assigned addresses" do
|
||||
value = '"かきくけこ" <mikel@test.lindsaar.net>'
|
||||
if RUBY_VERSION < '1.9'
|
||||
$KCODE = 'u'
|
||||
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
|
||||
else
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
|
||||
end
|
||||
value = value.dup.force_encoding('UTF-8')
|
||||
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
|
||||
field = Mail::FromField.new(value)
|
||||
expect(field.encoded).to eq result
|
||||
expect(field.decoded).to eq value
|
||||
|
|
|
@ -649,27 +649,16 @@ describe Mail::ContentTypeField do
|
|||
end
|
||||
|
||||
it "should encode a non us-ascii filename" do
|
||||
@original = $KCODE if RUBY_VERSION < '1.9'
|
||||
Mail.defaults do
|
||||
param_encode_language('jp')
|
||||
end
|
||||
c = Mail::ContentTypeField.new('application/octet-stream')
|
||||
string = "01 Quien Te Dij\221at. Pitbull.mp3"
|
||||
case
|
||||
when RUBY_VERSION >= '1.9.3'
|
||||
string = string.dup.force_encoding('SJIS')
|
||||
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=windows-31j'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
|
||||
when RUBY_VERSION >= '1.9'
|
||||
string = string.dup.force_encoding('SJIS')
|
||||
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=shift_jis'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
|
||||
else
|
||||
$KCODE = 'SJIS'
|
||||
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=sjis'jp'01%20Quien%20Te%20Dij%91at.%20Pitbull.mp3\r\n}
|
||||
end
|
||||
string = string.dup.force_encoding('SJIS')
|
||||
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=windows-31j'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
|
||||
c.filename = string
|
||||
expect(c.parameters).to eql({"filename" => string})
|
||||
expect(c.encoded).to eq result
|
||||
$KCODE = @original if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -109,17 +109,6 @@ describe Mail::UnstructuredField do
|
|||
@field = Mail::UnstructuredField.new("References", string)
|
||||
expect(@field.decoded).to eq 'ä&ä&ä'
|
||||
end
|
||||
|
||||
if !'1.9'.respond_to?(:force_encoding)
|
||||
it "shouldn't get fooled into encoding on 1.8 due to an unrelated Encoding constant" do
|
||||
begin
|
||||
Mail::UnstructuredField::Encoding = 'derp'
|
||||
expect(@field.encoded).to eq "Subject: Hello Frank\r\n"
|
||||
ensure
|
||||
Mail::UnstructuredField.send :remove_const, :Encoding
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "folding" do
|
||||
|
@ -156,33 +145,21 @@ describe Mail::UnstructuredField do
|
|||
end
|
||||
|
||||
it "should fold itself if it is non us-ascii" do
|
||||
@original = $KCODE if RUBY_VERSION < '1.9'
|
||||
string = "This is あ really long string This is あ really long string This is あ really long string This is あ really long string This is あ really long string"
|
||||
@field = Mail::UnstructuredField.new("Subject", string)
|
||||
if string.respond_to?(:force_encoding)
|
||||
string = string.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'u'
|
||||
end
|
||||
string = string.dup.force_encoding('UTF-8')
|
||||
result = "Subject: =?UTF-8?Q?This_is_=E3=81=82_really_long_string_This_is_=E3=81=82?=\r\n\s=?UTF-8?Q?_really_long_string_This_is_=E3=81=82_really_long_string_This_is?=\r\n\s=?UTF-8?Q?_=E3=81=82_really_long_string_This_is_=E3=81=82_really_long?=\r\n\s=?UTF-8?Q?_string?=\r\n"
|
||||
expect(@field.encoded).to eq result
|
||||
expect(@field.decoded).to eq string
|
||||
$KCODE = @original if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
it "should fold properly with my actual complicated header" do
|
||||
@original = $KCODE if RUBY_VERSION < '1.9'
|
||||
string = %|{"unique_args": {"mailing_id":147,"account_id":2}, "to": ["larspind@gmail.com"], "category": "mailing", "filters": {"domainkeys": {"settings": {"domain":1,"enable":1}}}, "sub": {"{{open_image_url}}": ["http://betaling.larspind.local/O/token/147/Mailing::FakeRecipient"], "{{name}}": ["[FIRST NAME]"], "{{signup_reminder}}": ["(her kommer til at stå hvornår folk har skrevet sig op ...)"], "{{unsubscribe_url}}": ["http://betaling.larspind.local/U/token/147/Mailing::FakeRecipient"], "{{email}}": ["larspind@gmail.com"], "{{link:308}}": ["http://betaling.larspind.local/L/308/0/Mailing::FakeRecipient"], "{{confirm_url}}": [""], "{{ref}}": ["[REF]"]}}|
|
||||
@field = Mail::UnstructuredField.new("X-SMTPAPI", string)
|
||||
if string.respond_to?(:force_encoding)
|
||||
string = string.dup.force_encoding('UTF-8')
|
||||
else
|
||||
$KCODE = 'u'
|
||||
end
|
||||
string = string.dup.force_encoding('UTF-8')
|
||||
result = "X-SMTPAPI: =?UTF-8?Q?{=22unique=5Fargs=22:_{=22mailing=5Fid=22:147,=22a?=\r\n =?UTF-8?Q?ccount=5Fid=22:2},_=22to=22:_[=22larspind@gmail.com=22],_=22categ?=\r\n =?UTF-8?Q?ory=22:_=22mailing=22,_=22filters=22:_{=22domainkeys=22:_{=22sett?=\r\n =?UTF-8?Q?ings=22:_{=22domain=22:1,=22enable=22:1}}},_=22sub=22:_{=22{{op?=\r\n =?UTF-8?Q?en=5Fimage=5Furl}}=22:_[=22http://betaling.larspind.local/O?=\r\n =?UTF-8?Q?/token/147/Mailing::FakeRecipient=22],_=22{{name}}=22:_[=22[FIRST?=\r\n =?UTF-8?Q?_NAME]=22],_=22{{signup=5Freminder}}=22:_[=22=28her_kommer_til_at?=\r\n =?UTF-8?Q?_st=C3=A5_hvorn=C3=A5r_folk_har_skrevet_sig_op_...=29=22],?=\r\n =?UTF-8?Q?_=22{{unsubscribe=5Furl}}=22:_[=22http://betaling.larspind.?=\r\n =?UTF-8?Q?local/U/token/147/Mailing::FakeRecipient=22],_=22{{email}}=22:?=\r\n =?UTF-8?Q?_[=22larspind@gmail.com=22],_=22{{link:308}}=22:_[=22http://beta?=\r\n =?UTF-8?Q?ling.larspind.local/L/308/0/Mailing::FakeRecipient=22],_=22{{con?=\r\n =?UTF-8?Q?firm=5Furl}}=22:_[=22=22],_=22{{ref}}=22:_[=22[REF]=22]}}?=\r\n"
|
||||
expect(@field.encoded).to eq result
|
||||
expect(@field.decoded).to eq string
|
||||
$KCODE = @original if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
it "should fold properly with continuous spaces around the linebreak" do
|
||||
|
@ -205,8 +182,7 @@ describe Mail::UnstructuredField do
|
|||
it "should encoded with ISO-2022-JP encoding" do
|
||||
@field = Mail::UnstructuredField.new("Subject", "あいうえお")
|
||||
@field.charset = 'iso-2022-jp'
|
||||
expect = (RUBY_VERSION < '1.9') ? "Subject: =?ISO-2022-JP?Q?=E3=81=82=E3=81=84=E3=81=86=E3=81=88=E3=81=8A?=\r\n" : "Subject: =?ISO-2022-JP?Q?=1B$B$=22$$$&$=28$*=1B=28B?=\r\n"
|
||||
expect(@field.encoded).to eq expect
|
||||
expect(@field.encoded).to eq "Subject: =?ISO-2022-JP?Q?=1B$B$=22$$$&$=28$*=1B=28B?=\r\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -460,9 +460,8 @@ HERE
|
|||
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= '1.9'
|
||||
it "should convert all lonesome LFs to CRLF in UTF-8 too" do
|
||||
header = Mail::Header.new(<<HERE)
|
||||
it "should convert all lonesome LFs to CRLF in UTF-8 too" do
|
||||
header = Mail::Header.new(<<HERE)
|
||||
Subject: Iñtërnâtiônàlizætiøn
|
||||
Received: from [127.0.220.158] (helo=fg-out-1718.google.com)
|
||||
by smtp.totallyrandom.com with esmtp (Exim 4.68)
|
||||
|
@ -471,11 +470,9 @@ Received: from [127.0.220.158] (helo=fg-out-1718.google.com)
|
|||
for support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700
|
||||
HERE
|
||||
|
||||
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
|
||||
end
|
||||
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
|
||||
end
|
||||
|
||||
|
||||
it "should convert all lonesome CRs to CRLF" do
|
||||
header = Mail::Header.new(<<HERE.gsub(/\n/, "\r"))
|
||||
Received: from [127.0.220.158] (helo=fg-out-1718.google.com)
|
||||
|
|
|
@ -66,11 +66,9 @@ describe Mail::Message do
|
|||
expect(mail.from).to eq ['mikel@me.com']
|
||||
expect(mail.to).to eq ['lindsaar@you.com']
|
||||
|
||||
if RUBY_VERSION >= '1.9'
|
||||
mail = ClassThatCreatesMail.new('mikel@me.com', 'lindsaar@you.com').create_mail_with_splat_args
|
||||
expect(mail.from).to eq ['mikel@me.com']
|
||||
expect(mail.to).to eq ['lindsaar@you.com']
|
||||
end
|
||||
mail = ClassThatCreatesMail.new('mikel@me.com', 'lindsaar@you.com').create_mail_with_splat_args
|
||||
expect(mail.from).to eq ['mikel@me.com']
|
||||
expect(mail.to).to eq ['lindsaar@you.com']
|
||||
end
|
||||
|
||||
it "should initialize a body and header class even if called with nothing to begin with" do
|
||||
|
@ -1680,12 +1678,10 @@ describe Mail::Message do
|
|||
expect(message.inspect_structure).to eq message.inspect
|
||||
end
|
||||
|
||||
if RUBY_VERSION > "1.9"
|
||||
it "uses the Ruby19 charset encoder" do
|
||||
with_encoder(Mail::Ruby19::BestEffortCharsetEncoder.new) do
|
||||
message = Mail.new("Content-Type: text/plain;\r\n charset=windows-1258\r\nContent-Transfer-Encoding: base64\r\n\r\nSGkglg==\r\n")
|
||||
expect(message.decoded).to eq("Hi –")
|
||||
end
|
||||
it "uses the Ruby19 charset encoder" do
|
||||
with_encoder(Mail::Ruby19::BestEffortCharsetEncoder.new) do
|
||||
message = Mail.new("Content-Type: text/plain;\r\n charset=windows-1258\r\nContent-Transfer-Encoding: base64\r\n\r\nSGkglg==\r\n")
|
||||
expect(message.decoded).to eq("Hi –")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -417,9 +417,6 @@ describe "MIME Emails" do
|
|||
end
|
||||
|
||||
Dir.glob(fixture_path('attachments', "test.*")).each do |test_attachment|
|
||||
# This spec fails for (most?) jpegs in 1.8.7
|
||||
next if test_attachment.end_with?('test.jpg') && RUBY_VERSION < '1.9'
|
||||
|
||||
it "should find binary encoded attachments of type #{File.extname(test_attachment)}" do
|
||||
pre, post = read_raw_fixture('emails', 'mime_emails', 'raw_email_with_binary_encoded.eml').split('BINARY_CONTENT_GOES_HERE')
|
||||
raw_file = File.open(test_attachment, "rb", &:read)
|
||||
|
@ -526,25 +523,19 @@ describe "MIME Emails" do
|
|||
add_file fixture_path('attachments', 'test.pdf')
|
||||
add_file fixture_path('attachments', 'test.zip')
|
||||
end
|
||||
if RUBY_VERSION >= '1.9'
|
||||
tripped = mail.attachments[0].decoded
|
||||
original = read_raw_fixture('attachments', 'test.png')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[1].decoded
|
||||
original = read_raw_fixture('attachments', 'test.jpg')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[2].decoded
|
||||
original = read_raw_fixture('attachments', 'test.pdf')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[3].decoded
|
||||
original = read_raw_fixture('attachments', 'test.zip')
|
||||
expect(tripped).to eq original
|
||||
else
|
||||
expect(mail.attachments[0].decoded).to eq read_raw_fixture('attachments', 'test.png')
|
||||
expect(mail.attachments[1].decoded).to eq read_raw_fixture('attachments', 'test.jpg')
|
||||
expect(mail.attachments[2].decoded).to eq read_raw_fixture('attachments', 'test.pdf')
|
||||
expect(mail.attachments[3].decoded).to eq read_raw_fixture('attachments', 'test.zip')
|
||||
end
|
||||
|
||||
tripped = mail.attachments[0].decoded
|
||||
original = read_raw_fixture('attachments', 'test.png')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[1].decoded
|
||||
original = read_raw_fixture('attachments', 'test.jpg')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[2].decoded
|
||||
original = read_raw_fixture('attachments', 'test.pdf')
|
||||
expect(tripped).to eq original
|
||||
tripped = mail.attachments[3].decoded
|
||||
original = read_raw_fixture('attachments', 'test.zip')
|
||||
expect(tripped).to eq original
|
||||
end
|
||||
|
||||
it "should allow you to send in file data instead of having to read it" do
|
||||
|
@ -555,13 +546,10 @@ describe "MIME Emails" do
|
|||
to 'mikel@to.lindsaar.net'
|
||||
add_file(:filename => 'test.png', :content => file_data)
|
||||
end
|
||||
if RUBY_VERSION >= '1.9'
|
||||
tripped = mail.attachments[0].decoded
|
||||
original = read_raw_fixture('attachments', 'test.png')
|
||||
expect(tripped).to eq original
|
||||
else
|
||||
expect(mail.attachments[0].decoded).to eq read_raw_fixture('attachments', 'test.png')
|
||||
end
|
||||
|
||||
tripped = mail.attachments[0].decoded
|
||||
original = read_raw_fixture('attachments', 'test.png')
|
||||
expect(tripped).to eq original
|
||||
end
|
||||
|
||||
it "should support :mime_type option" do
|
||||
|
|
|
@ -133,7 +133,7 @@ describe Mail::Sendmail do
|
|||
it 'raises on nonzero exitstatus' do
|
||||
command = %w[ /usr/sbin/sendmail -i -f roger@test.lindsaar.net -- marcel@test.lindsaar.net bob@test.lindsaar.net ]
|
||||
args = [ command, 'w+' ]
|
||||
args << { :err => :out } if RUBY_VERSION >= '1.9'
|
||||
args << { :err => :out }
|
||||
|
||||
expect(IO).to receive(:popen).with(*args) { system 'false' }
|
||||
|
||||
|
|
|
@ -15,39 +15,6 @@ describe "SMTP Delivery Method" do
|
|||
Mail.delivery_method.smtp.finish
|
||||
end
|
||||
|
||||
it "should not dot-stuff in recent Ruby versions" do
|
||||
skip "is skipped on older Ruby versions" if RUBY_VERSION < '2.1.3'
|
||||
expect(Mail.delivery_method.send(:dot_stuff?)).to eq false
|
||||
end
|
||||
|
||||
it "dot-stuff unterminated last line of the message" do
|
||||
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)
|
||||
|
||||
Mail.deliver do
|
||||
from 'from@example.com'
|
||||
to 'to@example.com'
|
||||
subject 'dot-stuff last line'
|
||||
body "this is a test\n... only a test\n... or is it?"
|
||||
end
|
||||
|
||||
message = MockSMTP.deliveries.first
|
||||
expect(Mail.new(message).decoded).to eq("this is a test\n... only a test\n.... or is it?")
|
||||
end
|
||||
|
||||
it "dot-stuff unterminated last line of the message containing a single dot" do
|
||||
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)
|
||||
|
||||
Mail.deliver do
|
||||
from 'from@example.com'
|
||||
to 'to@example.com'
|
||||
subject 'dot-stuff last line'
|
||||
body "this is a test\n.\nonly a test\n."
|
||||
end
|
||||
|
||||
message = MockSMTP.deliveries.first
|
||||
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n..")
|
||||
end
|
||||
|
||||
it "should not dot-stuff unterminated last line with no leading dot" do
|
||||
body = "this is a test\n.\nonly a test"
|
||||
|
||||
|
|
|
@ -26,20 +26,6 @@ describe "SMTP Delivery Method" do
|
|||
end
|
||||
|
||||
describe "general usage" do
|
||||
it "dot-stuff unterminated last line of the message" do
|
||||
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail::SMTPConnection.new(:connection => Mail.delivery_method).send(:dot_stuff?)
|
||||
|
||||
Mail.deliver do
|
||||
from 'from@example.com'
|
||||
to 'to@example.com'
|
||||
subject 'dot-stuff last line'
|
||||
body "this is a test\n.\nonly a test\n... or is it?"
|
||||
end
|
||||
|
||||
message = MockSMTP.deliveries.first
|
||||
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n.... or is it?")
|
||||
end
|
||||
|
||||
it "should send emails from given settings" do
|
||||
|
||||
mail = Mail.deliver do
|
||||
|
|
|
@ -84,27 +84,25 @@ describe "Utilities Module" do
|
|||
expect { quote_phrase(input_str) }.not_to raise_error
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= '1.9'
|
||||
describe "given a non-unsafe string" do
|
||||
it "should not change the encoding" do
|
||||
input_str = "blargh"
|
||||
input_str_encoding = input_str.encoding
|
||||
describe "given a non-unsafe string" do
|
||||
it "should not change the encoding" do
|
||||
input_str = "blargh"
|
||||
input_str_encoding = input_str.encoding
|
||||
|
||||
result = quote_phrase(input_str)
|
||||
result = quote_phrase(input_str)
|
||||
|
||||
expect(result.encoding).to eq input_str_encoding
|
||||
end
|
||||
expect(result.encoding).to eq input_str_encoding
|
||||
end
|
||||
end
|
||||
|
||||
describe "given an unsafe string" do
|
||||
it "should not change the encoding" do
|
||||
input_str = "Bjørn"
|
||||
input_str_encoding = input_str.encoding
|
||||
describe "given an unsafe string" do
|
||||
it "should not change the encoding" do
|
||||
input_str = "Bjørn"
|
||||
input_str_encoding = input_str.encoding
|
||||
|
||||
result = quote_phrase(input_str)
|
||||
result = quote_phrase(input_str)
|
||||
|
||||
expect(result.encoding).to eq input_str_encoding
|
||||
end
|
||||
expect(result.encoding).to eq input_str_encoding
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
# encoding: utf-8
|
||||
# frozen_string_literal: true
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Ruby 1.8 Extensions" do
|
||||
|
||||
describe "string ascii detection" do
|
||||
it "should say it is US-ASCII only if it is" do
|
||||
expect("abc").to be_ascii_only
|
||||
end
|
||||
|
||||
it "should not say it is US-ASCII only if it isn't" do
|
||||
expect("かきくけこ").not_to be_ascii_only
|
||||
end
|
||||
|
||||
it "should not say it is US-ASCII only if it is a mix" do
|
||||
expect("abcかきくけこ123").not_to be_ascii_only
|
||||
end
|
||||
|
||||
it "should handle edge cases" do
|
||||
["\x00", "\x01", "\x40", "\x7f", "\x73"].each do |str|
|
||||
expect(str).to be_ascii_only
|
||||
end
|
||||
|
||||
["\x81", "\x99", "\xFF"].each do |str|
|
||||
expect(str).not_to be_ascii_only
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2,11 +2,9 @@
|
|||
# frozen_string_literal: true
|
||||
require 'spec_helper'
|
||||
|
||||
if RUBY_VERSION > '1.9'
|
||||
describe '.decode_base64' do
|
||||
it "handles unpadded base64 correctly" do
|
||||
decoded = Mail::Ruby19.decode_base64("YQ")
|
||||
expect(decoded).to eq "a"
|
||||
end
|
||||
describe '.decode_base64' do
|
||||
it "handles unpadded base64 correctly" do
|
||||
decoded = Mail::Ruby19.decode_base64("YQ")
|
||||
expect(decoded).to eq "a"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,21 +27,10 @@ RSpec.configure do |c|
|
|||
c.mock_with :rspec
|
||||
c.include(CustomMatchers)
|
||||
|
||||
MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION = "2.2"
|
||||
if RUBY_VERSION >= MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION
|
||||
require 'rspec-benchmark'
|
||||
c.include RSpec::Benchmark::Matchers
|
||||
end
|
||||
|
||||
c.filter_run_excluding :require_rspec_benchmark => lambda { |version|
|
||||
RUBY_VERSION < MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION
|
||||
}
|
||||
require 'rspec-benchmark'
|
||||
c.include RSpec::Benchmark::Matchers
|
||||
end
|
||||
|
||||
# NOTE: We set the KCODE manually here in 1.8.X because upgrading to rspec-2.8.0 caused it
|
||||
# to default to "NONE" (Why!?).
|
||||
$KCODE='UTF8' if RUBY_VERSION < '1.9'
|
||||
|
||||
if defined?(Encoding) && Encoding.respond_to?(:default_external=)
|
||||
begin
|
||||
orig, $VERBOSE = $VERBOSE, nil
|
||||
|
|
|
@ -3,13 +3,7 @@ require 'rubygems'
|
|||
require 'bundler/setup'
|
||||
|
||||
begin
|
||||
if RUBY_VERSION >= '2.0'
|
||||
require 'byebug'
|
||||
elsif RUBY_VERSION >= '1.9'
|
||||
require 'debugger'
|
||||
else
|
||||
require 'ruby-debug'
|
||||
end
|
||||
require 'byebug'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue